From 8aa1b8f449d86618557442a08e0a0c6d7413a37f Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Sun, 15 Mar 2009 16:47:16 -0700 Subject: [PATCH 0001/1109] auto import from //branches/cupcake_rel/...@138607 --- tests/cts/net/Android.mk | 30 + tests/cts/net/AndroidManifest.xml | 30 + .../net/cts/ConnectivityManagerTest.java | 212 +++++ .../src/android/net/cts/CredentialsTest.java | 75 ++ .../net/src/android/net/cts/DhcpInfoTest.java | 80 ++ .../net/cts/LocalServerSocketTest.java | 107 +++ .../net/cts/LocalSocketAddressTest.java | 81 ++ .../cts/LocalSocketAddress_NamespaceTest.java | 59 ++ .../src/android/net/cts/LocalSocketTest.java | 342 ++++++++ .../net/src/android/net/cts/MailToTest.java | 167 ++++ .../src/android/net/cts/NetworkInfoTest.java | 171 ++++ .../cts/NetworkInfo_DetailedStateTest.java | 87 +++ .../net/cts/NetworkInfo_StateTest.java | 72 ++ .../net/src/android/net/cts/ProxyTest.java | 96 +++ .../cts/net/src/android/net/cts/UriTest.java | 727 ++++++++++++++++++ .../src/android/net/cts/Uri_BuilderTest.java | 174 +++++ .../net/http/cts/SslCertificateTest.java | 302 ++++++++ .../http/cts/SslCertificate_DNameTest.java | 83 ++ 18 files changed, 2895 insertions(+) create mode 100644 tests/cts/net/Android.mk create mode 100644 tests/cts/net/AndroidManifest.xml create mode 100644 tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java create mode 100644 tests/cts/net/src/android/net/cts/CredentialsTest.java create mode 100644 tests/cts/net/src/android/net/cts/DhcpInfoTest.java create mode 100644 tests/cts/net/src/android/net/cts/LocalServerSocketTest.java create mode 100644 tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java create mode 100644 tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java create mode 100644 tests/cts/net/src/android/net/cts/LocalSocketTest.java create mode 100644 tests/cts/net/src/android/net/cts/MailToTest.java create mode 100644 tests/cts/net/src/android/net/cts/NetworkInfoTest.java create mode 100644 tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java create mode 100644 tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java create mode 100644 tests/cts/net/src/android/net/cts/ProxyTest.java create mode 100644 tests/cts/net/src/android/net/cts/UriTest.java create mode 100644 tests/cts/net/src/android/net/cts/Uri_BuilderTest.java create mode 100644 tests/cts/net/src/android/net/http/cts/SslCertificateTest.java create mode 100644 tests/cts/net/src/android/net/http/cts/SslCertificate_DNameTest.java diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk new file mode 100644 index 0000000000..d1a459f0d3 --- /dev/null +++ b/tests/cts/net/Android.mk @@ -0,0 +1,30 @@ +# Copyright (C) 2008 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. + +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := ctstests_net + +LOCAL_JAVA_LIBRARIES := android.test.runner + +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_PACKAGE_NAME := CtsNetTestCases + +LOCAL_INSTRUMENTATION_FOR := CtsTestStubs + +include $(BUILD_PACKAGE) + diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml new file mode 100644 index 0000000000..6c2dfbdf65 --- /dev/null +++ b/tests/cts/net/AndroidManifest.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java new file mode 100644 index 0000000000..201105f0a6 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2008 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 com.android.internal.telephony.Phone; + +import dalvik.annotation.TestTargets; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.net.NetworkInfo.DetailedState; +import android.net.NetworkInfo.State; +import android.test.AndroidTestCase; + +@TestTargetClass(ConnectivityManager.class) +public class ConnectivityManagerTest extends AndroidTestCase { + + private static final int HOST_ADDRESS = 0x7f000001;// represent ip 127.0.0.1 + private ConnectivityManager mCm; + @Override + protected void setUp() throws Exception { + super.setUp(); + mCm = (ConnectivityManager) getContext().getSystemService( + Context.CONNECTIVITY_SERVICE); + } + + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test getNetworkInfo(int networkType).", + method = "getNetworkInfo", + args = {int.class} + ) + public void testGetNetworkInfo() { + + // this test assumes that there are at least two network types. + assertTrue(mCm.getAllNetworkInfo().length >= 2); + NetworkInfo ni = mCm.getNetworkInfo(1); + State state = ni.getState(); + assertTrue(State.UNKNOWN.ordinal() >= state.ordinal() + && state.ordinal() >= State.CONNECTING.ordinal()); + DetailedState ds = ni.getDetailedState(); + assertTrue(DetailedState.FAILED.ordinal() >= ds.ordinal() + && ds.ordinal() >= DetailedState.IDLE.ordinal()); + + ni = mCm.getNetworkInfo(0); + state = ni.getState(); + assertTrue(State.UNKNOWN.ordinal() >= state.ordinal() + && state.ordinal() >= State.CONNECTING.ordinal()); + ds = ni.getDetailedState(); + assertTrue(DetailedState.FAILED.ordinal() >= ds.ordinal() + && ds.ordinal() >= DetailedState.IDLE.ordinal()); + + ni = mCm.getNetworkInfo(-1); + assertNull(ni); + + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test isNetworkTypeValid(int networkType).", + method = "isNetworkTypeValid", + args = {int.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test isNetworkTypeValid(int networkType).", + method = "getAllNetworkInfo", + args = {} + ) + }) + public void testIsNetworkTypeValid() { + + NetworkInfo[] ni = mCm.getAllNetworkInfo(); + + for (NetworkInfo n : ni) { + assertTrue(ConnectivityManager.isNetworkTypeValid(n.getType())); + } + assertFalse(ConnectivityManager.isNetworkTypeValid(-1)); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.TODO, + notes = "", + method = "getNetworkPreference", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "", + method = "setNetworkPreference", + args = {int.class} + ) + }) + public void testAccessNetworkPreference() { + + final int EXPECTED = 1; + int per = mCm.getNetworkPreference(); + mCm.setNetworkPreference(EXPECTED); + assertEquals(EXPECTED, mCm.getNetworkPreference()); + + mCm.setNetworkPreference(0); + assertEquals(0, mCm.getNetworkPreference()); + + mCm.setNetworkPreference(-1); + assertEquals(0, mCm.getNetworkPreference()); + + mCm.setNetworkPreference(2); + assertEquals(0, mCm.getNetworkPreference()); + + mCm.setNetworkPreference(1); + + assertEquals(1, mCm.getNetworkPreference()); + + mCm.setNetworkPreference(per); + } + + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test getAllNetworkInfo().", + method = "getAllNetworkInfo", + args = {} + ) + public void testGetAllNetworkInfo() { + + NetworkInfo[] ni = mCm.getAllNetworkInfo(); + assertEquals(2, ni.length); + + assertTrue(ni[0].getType() >=0 && ni[0].getType() <= 1); + assertTrue(ni[1].getType() >=0 && ni[1].getType() <= 1); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test start and stop usingNetworkFeature(int networkType, String feature).", + method = "startUsingNetworkFeature", + args = {int.class, java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test start and stop usingNetworkFeature(int networkType, String feature).", + method = "stopUsingNetworkFeature", + args = {int.class, java.lang.String.class} + ) + }) + public void testStartUsingNetworkFeature() { + + final String invalidateFeature = "invalidateFeature"; + assertEquals(-1, mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, + invalidateFeature)); + + assertEquals(-1, mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, + invalidateFeature)); + + assertEquals(-1, mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_WIFI, + Phone.FEATURE_ENABLE_MMS)); + assertEquals(-1, mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_WIFI, + Phone.FEATURE_ENABLE_MMS)); + } + + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test requestRouteToHost(int networkType, int hostAddress).", + method = "requestRouteToHost", + args = {int.class, int.class} + ) + public void testRequestRouteToHost() { + + NetworkInfo[] ni = mCm.getAllNetworkInfo(); + for (NetworkInfo n : ni) { + assertTrue(mCm.requestRouteToHost(n.getType(), HOST_ADDRESS)); + } + + assertFalse(mCm.requestRouteToHost(-1, HOST_ADDRESS)); + } + + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test getActiveNetworkInfo().", + method = "getActiveNetworkInfo", + args = {} + ) + public void testGetActiveNetworkInfo() { + + NetworkInfo ni = mCm.getActiveNetworkInfo(); + if (ni != null) { + assertTrue(ni.getType() >= 0); + } else { + fail("There is no active network connected, should be at least one kind of network"); + } + } + +} diff --git a/tests/cts/net/src/android/net/cts/CredentialsTest.java b/tests/cts/net/src/android/net/cts/CredentialsTest.java new file mode 100644 index 0000000000..0f6e49e00d --- /dev/null +++ b/tests/cts/net/src/android/net/cts/CredentialsTest.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2008 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.net.Credentials; +import android.test.AndroidTestCase; +import dalvik.annotation.TestTargets; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargetClass; + +@TestTargetClass(android.net.Credentials.class) +public class CredentialsTest extends AndroidTestCase { + + @TestTargets({ + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test constructor of Credentials, and test getGid, getPid, getUid.", + method = "Credentials", + args = {int.class, int.class, int.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test constructor of Credentials, and test getGid, getPid, getUid.", + method = "getGid", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test constructor of Credentials, and test getGid, getPid, getUid.", + method = "getPid", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test constructor of Credentials, and test getGid, getPid, getUid.", + method = "getUid", + args = {} + ) + }) + public void testCredentials() { + // new the Credentials instance + // Test with zero inputs + Credentials cred = new Credentials(0, 0, 0); + assertEquals(0, cred.getGid()); + assertEquals(0, cred.getPid()); + assertEquals(0, cred.getUid()); + + // Test with big integer + cred = new Credentials(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE); + assertEquals(Integer.MAX_VALUE, cred.getGid()); + assertEquals(Integer.MAX_VALUE, cred.getPid()); + assertEquals(Integer.MAX_VALUE, cred.getUid()); + + // Test with big negative integer + cred = new Credentials(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE); + assertEquals(Integer.MIN_VALUE, cred.getGid()); + assertEquals(Integer.MIN_VALUE, cred.getPid()); + assertEquals(Integer.MIN_VALUE, cred.getUid()); + } +} diff --git a/tests/cts/net/src/android/net/cts/DhcpInfoTest.java b/tests/cts/net/src/android/net/cts/DhcpInfoTest.java new file mode 100644 index 0000000000..657d03c368 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/DhcpInfoTest.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2008 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.net.DhcpInfo; +import android.test.AndroidTestCase; +import dalvik.annotation.TestTargets; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargetClass; + +@TestTargetClass(DhcpInfo.class) +public class DhcpInfoTest extends AndroidTestCase { + + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test DhcpInfo's constructor.", + method = "DhcpInfo", + args = {} + ) + public void testConstructor() { + new DhcpInfo(); + } + + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test toString function.", + method = "toString", + args = {} + ) + public void testToString() { + String expectedDefault = "ipaddr 0.0.0.0 gateway 0.0.0.0 netmask 0.0.0.0 dns1 0.0.0.0 " + + "dns2 0.0.0.0 DHCP server 0.0.0.0 lease 0 seconds"; + String STR_ADDR1 = "255.255.255.255"; + String STR_ADDR2 = "127.0.0.1"; + String STR_ADDR3 = "192.168.1.1"; + String STR_ADDR4 = "192.168.1.0"; + int leaseTime = 9999; + String expected = "ipaddr " + STR_ADDR1 + " gateway " + STR_ADDR2 + " netmask " + + STR_ADDR3 + " dns1 " + STR_ADDR4 + " dns2 " + STR_ADDR4 + " DHCP server " + + STR_ADDR2 + " lease " + leaseTime + " seconds"; + + DhcpInfo dhcpInfo = new DhcpInfo(); + + // Test default string. + assertEquals(expectedDefault, dhcpInfo.toString()); + + dhcpInfo.ipAddress = ipToInteger(STR_ADDR1); + dhcpInfo.gateway = ipToInteger(STR_ADDR2); + dhcpInfo.netmask = ipToInteger(STR_ADDR3); + dhcpInfo.dns1 = ipToInteger(STR_ADDR4); + dhcpInfo.dns2 = ipToInteger(STR_ADDR4); + dhcpInfo.serverAddress = ipToInteger(STR_ADDR2); + dhcpInfo.leaseDuration = leaseTime; + + // Test with new values + assertEquals(expected, dhcpInfo.toString()); + } + + private int ipToInteger(String ipString) { + String ipSegs[] = ipString.split("[.]"); + int tmp = Integer.parseInt(ipSegs[3]) << 24 | Integer.parseInt(ipSegs[2]) << 16 | + Integer.parseInt(ipSegs[1]) << 8 | Integer.parseInt(ipSegs[0]); + return tmp; + } +} diff --git a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java new file mode 100644 index 0000000000..4fb8481674 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2008 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 java.io.FileDescriptor; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; +import android.net.LocalServerSocket; +import android.net.LocalSocket; +import android.net.LocalSocketAddress; +import android.os.ParcelFileDescriptor; +import android.test.AndroidTestCase; +import dalvik.annotation.TestInfo; +import dalvik.annotation.TestStatus; +import dalvik.annotation.TestTarget; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.ToBeFixed; + +@TestTargetClass(LocalServerSocket.class) +public class LocalServerSocketTest extends AndroidTestCase { + @TestInfo( + status = TestStatus.TBR, + notes = "test LocalServerSocket", + targets = { + @TestTarget( + methodName = "accept", + methodArgs = {} + ), + @TestTarget( + methodName = "close", + methodArgs = {} + ), + @TestTarget( + methodName = "getFileDescriptor", + methodArgs = {} + ), + @TestTarget( + methodName = "getLocalSocketAddress", + methodArgs = {} + ), + @TestTarget( + methodName = "LocalServerSocket", + methodArgs = {FileDescriptor.class} + ), + @TestTarget( + methodName = "LocalServerSocket", + methodArgs = {String.class} + ) + }) + @ToBeFixed(bug = "1520987", explanation = "Cannot find a proper FileDescriptor for " + + "android.net.LocalServerSocket constructor") + public void testLocalServerSocket() throws IOException { + LocalServerSocket localServerSocket = new LocalServerSocket(LocalSocketTest.mSockAddr); + assertNotNull(localServerSocket.getLocalSocketAddress()); + commonFunctions(localServerSocket); + + Socket socket = new Socket("www.google.com", 80); + ParcelFileDescriptor parcelFD = ParcelFileDescriptor.fromSocket(socket); + FileDescriptor fd = parcelFD.getFileDescriptor(); + + // enable the following after bug 1520987 fixed +// localServerSocket = new LocalServerSocket(fd); +// assertNull(localServerSocket.getLocalSocketAddress()); +// commonFunctions(localServerSocket); + } + + public void commonFunctions(LocalServerSocket localServerSocket) throws IOException { + // create client socket + LocalSocket clientSocket = new LocalSocket(); + + // establish connection between client and server + clientSocket.connect(new LocalSocketAddress(LocalSocketTest.mSockAddr)); + LocalSocket serverSocket = localServerSocket.accept(); + + // send data from client to server + OutputStream clientOutStream = clientSocket.getOutputStream(); + clientOutStream.write(12); + InputStream serverInStream = serverSocket.getInputStream(); + assertEquals(12, serverInStream.read()); + + // send data from server to client + OutputStream serverOutStream = serverSocket.getOutputStream(); + serverOutStream.write(3); + InputStream clientInStream = clientSocket.getInputStream(); + assertEquals(3, clientInStream.read()); + + // close server socket + assertNotNull(localServerSocket.getFileDescriptor()); + localServerSocket.close(); + assertNull(localServerSocket.getFileDescriptor()); + } +} diff --git a/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java b/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java new file mode 100644 index 0000000000..cc3a1d38df --- /dev/null +++ b/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2008 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.net.LocalSocketAddress; +import android.net.LocalSocketAddress.Namespace; +import android.test.AndroidTestCase; +import dalvik.annotation.TestTargets; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargetClass; + +@TestTargetClass(LocalSocketAddress.class) +public class LocalSocketAddressTest extends AndroidTestCase { + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test LocalSocketAddress", + method = "LocalSocketAddress", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test LocalSocketAddress", + method = "LocalSocketAddress", + args = {java.lang.String.class, android.net.LocalSocketAddress.Namespace.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test LocalSocketAddress", + method = "getName", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test LocalSocketAddress", + method = "getNamespace", + args = {} + ) + }) + public void testNewLocalSocketAddressWithDefaultNamespace() { + // default namespace + LocalSocketAddress localSocketAddress = new LocalSocketAddress("name"); + assertEquals("name", localSocketAddress.getName()); + assertEquals(Namespace.ABSTRACT, localSocketAddress.getNamespace()); + + // specify the namespace + LocalSocketAddress localSocketAddress2 = new LocalSocketAddress("name2", Namespace.ABSTRACT); + assertEquals("name2", localSocketAddress2.getName()); + assertEquals(Namespace.ABSTRACT, localSocketAddress2.getNamespace()); + + LocalSocketAddress localSocketAddress3 = new LocalSocketAddress("name3", Namespace.FILESYSTEM); + assertEquals("name3", localSocketAddress3.getName()); + assertEquals(Namespace.FILESYSTEM, localSocketAddress3.getNamespace()); + + LocalSocketAddress localSocketAddress4 = new LocalSocketAddress("name4", Namespace.RESERVED); + assertEquals("name4", localSocketAddress4.getName()); + assertEquals(Namespace.RESERVED, localSocketAddress4.getNamespace()); + } +} + diff --git a/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java b/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java new file mode 100644 index 0000000000..a9acaa357d --- /dev/null +++ b/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2008 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.net.LocalSocketAddress.Namespace; +import android.test.AndroidTestCase; +import dalvik.annotation.TestTargets; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargetClass; + +@TestTargetClass(Namespace.class) +public class LocalSocketAddress_NamespaceTest extends AndroidTestCase { + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test valueOf(String name).", + method = "valueOf", + args = {java.lang.String.class} + ) + public void testValueOf() { + assertEquals(Namespace.ABSTRACT, Namespace.valueOf("ABSTRACT")); + assertEquals(Namespace.RESERVED, Namespace.valueOf("RESERVED")); + assertEquals(Namespace.FILESYSTEM, Namespace.valueOf("FILESYSTEM")); + } + + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test values().", + method = "values", + args = {} + ) + public void testValues() { + Namespace[] expected = Namespace.values(); + assertEquals(Namespace.ABSTRACT, expected[0]); + assertEquals(Namespace.RESERVED, expected[1]); + assertEquals(Namespace.FILESYSTEM, expected[2]); + } +} + diff --git a/tests/cts/net/src/android/net/cts/LocalSocketTest.java b/tests/cts/net/src/android/net/cts/LocalSocketTest.java new file mode 100644 index 0000000000..ae0b51c0ed --- /dev/null +++ b/tests/cts/net/src/android/net/cts/LocalSocketTest.java @@ -0,0 +1,342 @@ +/* + * Copyright (C) 2008 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 java.io.FileDescriptor; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import android.net.Credentials; +import android.net.LocalServerSocket; +import android.net.LocalSocket; +import android.net.LocalSocketAddress; +import android.test.AndroidTestCase; +import dalvik.annotation.TestTargets; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargetClass; + +@TestTargetClass(LocalSocket.class) +public class LocalSocketTest extends AndroidTestCase{ + public final static String mSockAddr = "com.android.net.LocalSocketTest"; + + @TestTargets({ + @TestTargetNew( + level = TestLevel.TODO, + notes = "test core functions of LocalSocket", + method = "LocalSocket", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test core functions of LocalSocket", + method = "close", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test core functions of LocalSocket", + method = "connect", + args = {android.net.LocalSocketAddress.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test core functions of LocalSocket", + method = "getAncillaryFileDescriptors", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test core functions of LocalSocket", + method = "getFileDescriptor", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test core functions of LocalSocket", + method = "getInputStream", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test core functions of LocalSocket", + method = "getOutputStream", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test core functions of LocalSocket", + method = "getPeerCredentials", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test core functions of LocalSocket", + method = "isConnected", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test core functions of LocalSocket", + method = "setFileDescriptorsForSend", + args = {java.io.FileDescriptor[].class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test core functions of LocalSocket", + method = "shutdownInput", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test core functions of LocalSocket", + method = "shutdownOutput", + args = {} + ) + }) + public void testLocalConnections() throws IOException{ + // create client and server socket + LocalServerSocket localServerSocket = new LocalServerSocket(mSockAddr); + LocalSocket clientSocket = new LocalSocket(); + + // establish connection between client and server + LocalSocketAddress locSockAddr = new LocalSocketAddress(mSockAddr); + assertFalse(clientSocket.isConnected()); + clientSocket.connect(locSockAddr); + assertTrue(clientSocket.isConnected()); + LocalSocket serverSocket = localServerSocket.accept(); + + Credentials credent = clientSocket.getPeerCredentials(); + assertTrue(0 != credent.getPid()); + + // send data from client to server + OutputStream clientOutStream = clientSocket.getOutputStream(); + clientOutStream.write(12); + InputStream serverInStream = serverSocket.getInputStream(); + assertEquals(12, serverInStream.read()); + + //send data from server to client + OutputStream serverOutStream = serverSocket.getOutputStream(); + serverOutStream.write(3); + InputStream clientInStream = clientSocket.getInputStream(); + assertEquals(3, clientInStream.read()); + + // Test sending and receiving file descriptors + clientSocket.setFileDescriptorsForSend(new FileDescriptor[]{FileDescriptor.in}); + clientOutStream.write(32); + assertEquals(32, serverInStream.read()); + + FileDescriptor[] out = serverSocket.getAncillaryFileDescriptors(); + assertEquals(1, out.length); + FileDescriptor fd = clientSocket.getFileDescriptor(); + assertTrue(fd.valid()); + + //shutdown input stream of client + clientSocket.shutdownInput(); + assertEquals(-1, clientInStream.read()); + + //shutdown output stream of client + clientSocket.shutdownOutput(); + try { + clientOutStream.write(10); + fail("testLocalSocket shouldn't come to here"); + } catch (IOException e) { + // expected + } + + //shutdown input stream of server + serverSocket.shutdownInput(); + assertEquals(-1, serverInStream.read()); + + //shutdown output stream of server + serverSocket.shutdownOutput(); + try { + serverOutStream.write(10); + fail("testLocalSocket shouldn't come to here"); + } catch (IOException e) { + // expected + } + + //close client socket + clientSocket.close(); + try { + clientInStream.read(); + fail("testLocalSocket shouldn't come to here"); + } catch (IOException e) { + // expected + } + + //close server socket + serverSocket.close(); + try { + serverInStream.read(); + fail("testLocalSocket shouldn't come to here"); + } catch (IOException e) { + // expected + } + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.TODO, + notes = "test secondary functions of LocalSocket", + method = "bind", + args = {android.net.LocalSocketAddress.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test secondary functions of LocalSocket", + method = "connect", + args = {android.net.LocalSocketAddress.class, int.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test secondary functions of LocalSocket", + method = "getLocalSocketAddress", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test secondary functions of LocalSocket", + method = "getReceiveBufferSize", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test secondary functions of LocalSocket", + method = "getRemoteSocketAddress", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test secondary functions of LocalSocket", + method = "getSendBufferSize", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test secondary functions of LocalSocket", + method = "getSoTimeout", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test secondary functions of LocalSocket", + method = "isBound", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test secondary functions of LocalSocket", + method = "isClosed", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test secondary functions of LocalSocket", + method = "isInputShutdown", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test secondary functions of LocalSocket", + method = "isOutputShutdown", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test secondary functions of LocalSocket", + method = "setReceiveBufferSize", + args = {int.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test secondary functions of LocalSocket", + method = "setSendBufferSize", + args = {int.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test secondary functions of LocalSocket", + method = "setSoTimeout", + args = {int.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "test secondary functions of LocalSocket", + method = "toString", + args = {} + ) + }) + public void testAccessors() throws IOException{ + LocalSocket socket = new LocalSocket(); + LocalSocketAddress addr = new LocalSocketAddress("secondary"); + + assertFalse(socket.isBound()); + socket.bind(addr); + assertTrue(socket.isBound()); + assertEquals(addr, socket.getLocalSocketAddress()); + + String str = socket.toString(); + assertTrue(str.contains("impl:android.net.LocalSocketImpl")); + + socket.setReceiveBufferSize(1999); + assertEquals(1999 << 1, socket.getReceiveBufferSize()); + + socket.setSendBufferSize(1998); + assertEquals(1998 << 1, socket.getSendBufferSize()); + + // Timeout is not support at present, so set is ignored + socket.setSoTimeout(1996); + assertEquals(0, socket.getSoTimeout()); + + try { + socket.getRemoteSocketAddress(); + fail("testLocalSocketSecondary shouldn't come to here"); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + socket.isClosed(); + fail("testLocalSocketSecondary shouldn't come to here"); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + socket.isInputShutdown(); + fail("testLocalSocketSecondary shouldn't come to here"); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + socket.isOutputShutdown(); + fail("testLocalSocketSecondary shouldn't come to here"); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + socket.connect(addr, 2005); + fail("testLocalSocketSecondary shouldn't come to here"); + } catch (UnsupportedOperationException e) { + // expected + } + } +} diff --git a/tests/cts/net/src/android/net/cts/MailToTest.java b/tests/cts/net/src/android/net/cts/MailToTest.java new file mode 100644 index 0000000000..e419272517 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/MailToTest.java @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2008 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.net.MailTo; +import android.test.AndroidTestCase; +import android.util.Log; +import dalvik.annotation.TestTargets; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargetClass; + +@TestTargetClass(MailTo.class) +public class MailToTest extends AndroidTestCase { + private static final String MAILTOURI_1 = "mailto:chris@example.com"; + private static final String MAILTOURI_2 = "mailto:infobot@example.com?subject=current-issue"; + private static final String MAILTOURI_3 = "mailto:infobot@example.com?body=send%20current-issue"; + private static final String MAILTOURI_4 = "mailto:infobot@example.com?body=send%20current-" + + "issue%0D%0Asend%20index"; + private static final String MAILTOURI_5 = "mailto:joe@example.com?" + + "cc=bob@example.com&body=hello"; + private static final String MAILTOURI_6 = "mailto:?to=joe@example.com&" + + "cc=bob@example.com&body=hello"; + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test parse mailto URI.", + method = "parse", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test parse mailto URI.", + method = "isMailTo", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test parse mailto URI.", + method = "getTo", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test parse mailto URI.", + method = "getSubject", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test parse mailto URI.", + method = "getBody", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test parse mailto URI.", + method = "getCc", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test parse mailto URI.", + method = "toString", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test parse mailto URI.", + method = "getHeaders", + args = {} + ) + }) + public void testParseMailToURI() { + assertFalse(MailTo.isMailTo(null)); + assertFalse(MailTo.isMailTo("")); + assertFalse(MailTo.isMailTo("http://www.google.com")); + + assertTrue(MailTo.isMailTo(MAILTOURI_1)); + MailTo mailTo_1 = MailTo.parse(MAILTOURI_1); + Log.d("Trace", mailTo_1.toString()); + assertEquals("chris@example.com", mailTo_1.getTo()); + assertEquals(1, mailTo_1.getHeaders().size()); + assertNull(mailTo_1.getBody()); + assertNull(mailTo_1.getCc()); + assertNull(mailTo_1.getSubject()); + assertEquals("mailto:?to=chris%40example.com&", mailTo_1.toString()); + + assertTrue(MailTo.isMailTo(MAILTOURI_2)); + MailTo mailTo_2 = MailTo.parse(MAILTOURI_2); + Log.d("Trace", mailTo_2.toString()); + assertEquals(2, mailTo_2.getHeaders().size()); + assertEquals("infobot@example.com", mailTo_2.getTo()); + assertEquals("current-issue", mailTo_2.getSubject()); + assertNull(mailTo_2.getBody()); + assertNull(mailTo_2.getCc()); + assertEquals("mailto:?to=infobot%40example.com&subject=current-issue&", + mailTo_2.toString()); + + assertTrue(MailTo.isMailTo(MAILTOURI_3)); + MailTo mailTo_3 = MailTo.parse(MAILTOURI_3); + Log.d("Trace", mailTo_3.toString()); + assertEquals(2, mailTo_3.getHeaders().size()); + assertEquals("infobot@example.com", mailTo_3.getTo()); + assertEquals("send current-issue", mailTo_3.getBody()); + assertNull(mailTo_3.getCc()); + assertNull(mailTo_3.getSubject()); + assertEquals("mailto:?body=send%20current-issue&to=infobot%40example.com&", + mailTo_3.toString()); + + assertTrue(MailTo.isMailTo(MAILTOURI_4)); + MailTo mailTo_4 = MailTo.parse(MAILTOURI_4); + Log.d("Trace", mailTo_4.toString() + " " + mailTo_4.getBody()); + assertEquals(2, mailTo_4.getHeaders().size()); + assertEquals("infobot@example.com", mailTo_4.getTo()); + assertEquals("send current-issue\r\nsend index", mailTo_4.getBody()); + assertNull(mailTo_4.getCc()); + assertNull(mailTo_4.getSubject()); + assertEquals("mailto:?body=send%20current-issue%0D%0Asend%20index&to=infobot%40example.com&", + mailTo_4.toString()); + + assertTrue(MailTo.isMailTo(MAILTOURI_5)); + MailTo mailTo_5 = MailTo.parse(MAILTOURI_5); + Log.d("Trace", mailTo_5.toString() + mailTo_5.getHeaders().toString() + + mailTo_5.getHeaders().size()); + assertEquals(3, mailTo_5.getHeaders().size()); + assertEquals("joe@example.com", mailTo_5.getTo()); + assertEquals("bob@example.com", mailTo_5.getCc()); + assertEquals("hello", mailTo_5.getBody()); + assertNull(mailTo_5.getSubject()); + assertEquals("mailto:?cc=bob%40example.com&body=hello&to=joe%40example.com&", + mailTo_5.toString()); + + assertTrue(MailTo.isMailTo(MAILTOURI_6)); + MailTo mailTo_6 = MailTo.parse(MAILTOURI_6); + Log.d("Trace", mailTo_6.toString() + mailTo_6.getHeaders().toString() + + mailTo_6.getHeaders().size()); + assertEquals(3, mailTo_6.getHeaders().size()); + assertEquals(", joe@example.com", mailTo_6.getTo()); + assertEquals("bob@example.com", mailTo_6.getCc()); + assertEquals("hello", mailTo_6.getBody()); + assertNull(mailTo_6.getSubject()); + assertEquals("mailto:?cc=bob%40example.com&body=hello&to=%2C%20joe%40example.com&", + mailTo_6.toString()); + } +} + diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java new file mode 100644 index 0000000000..248ef9a71f --- /dev/null +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2008 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.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.net.NetworkInfo.DetailedState; +import android.net.NetworkInfo.State; +import android.os.Parcel; +import android.test.AndroidTestCase; +import dalvik.annotation.TestInfo; +import dalvik.annotation.TestStatus; +import dalvik.annotation.TestTarget; +import dalvik.annotation.TestTargetClass; + +@TestTargetClass(NetworkInfo.class) +public class NetworkInfoTest extends AndroidTestCase { + ConnectivityManager mConnectivityManager; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mConnectivityManager = (ConnectivityManager) mContext + .getSystemService(Context.CONNECTIVITY_SERVICE); + } + + @TestInfo( + status = TestStatus.TBR, + notes = "Test isConnectedOrConnecting().", + targets = { + @TestTarget( + methodName = "isConnectedOrConnecting", + methodArgs = {} + ), + @TestTarget( + methodName = "setFailover", + methodArgs = {boolean.class} + ), + @TestTarget( + methodName = "isFailover", + methodArgs = {} + ), + @TestTarget( + methodName = "getType", + methodArgs = {} + ), + @TestTarget( + methodName = "getTypeName", + methodArgs = {} + ), + @TestTarget( + methodName = "setIsAvailable", + methodArgs = {boolean.class} + ), + @TestTarget( + methodName = "isAvailable", + methodArgs = {} + ), + @TestTarget( + methodName = "isConnected", + methodArgs = {} + ), + @TestTarget( + methodName = "describeContents", + methodArgs = {} + ), + @TestTarget( + methodName = "getDetailedState", + methodArgs = {} + ), + @TestTarget( + methodName = "getState", + methodArgs = {} + ), + @TestTarget( + methodName = "getReason", + methodArgs = {} + ), + @TestTarget( + methodName = "getExtraInfo", + methodArgs = {} + ), + @TestTarget( + methodName = "toString", + methodArgs = {} + ) + }) + public void testAccessNetworkInfoProperties() { + NetworkInfo[] ni = mConnectivityManager.getAllNetworkInfo(); + assertTrue(ni.length >= 2); + assertFalse(ni[ConnectivityManager.TYPE_MOBILE].isFailover()); + assertFalse(ni[ConnectivityManager.TYPE_WIFI].isFailover()); + + // test environment:connect as TYPE_MOBILE, and connect to internet. + assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getType(), + ConnectivityManager.TYPE_MOBILE); + assertEquals(ni[ConnectivityManager.TYPE_WIFI].getType(), + ConnectivityManager.TYPE_WIFI); + assertEquals("MOBILE",ni[ConnectivityManager.TYPE_MOBILE].getTypeName()); + assertEquals("WIFI",ni[ConnectivityManager.TYPE_WIFI].getTypeName()); + assertTrue(ni[ConnectivityManager.TYPE_MOBILE] + .isConnectedOrConnecting()); + assertFalse(ni[ConnectivityManager.TYPE_WIFI].isConnectedOrConnecting()); + assertTrue(ni[ConnectivityManager.TYPE_MOBILE].isAvailable()); + assertFalse(ni[ConnectivityManager.TYPE_WIFI].isAvailable()); + assertTrue(ni[ConnectivityManager.TYPE_MOBILE].isConnected()); + assertFalse(ni[ConnectivityManager.TYPE_WIFI].isConnected()); + + assertEquals(ni[ConnectivityManager.TYPE_MOBILE].describeContents(), 0); + assertEquals(ni[ConnectivityManager.TYPE_WIFI].describeContents(), 0); + + assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getState(), + State.CONNECTED); + assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getDetailedState(), + DetailedState.CONNECTED); + + assertNull(ni[ConnectivityManager.TYPE_MOBILE].getReason()); + assertNull(ni[ConnectivityManager.TYPE_WIFI].getReason()); + assertEquals("internet",ni[ConnectivityManager.TYPE_MOBILE].getExtraInfo()); + assertNull(ni[ConnectivityManager.TYPE_WIFI].getExtraInfo()); + + assertNotNull(ni[ConnectivityManager.TYPE_MOBILE].toString()); + assertNotNull(ni[ConnectivityManager.TYPE_WIFI].toString()); + } + + @TestInfo( + status = TestStatus.TBR, + notes = "Test writeToParcel(Parcel dest, int flags).", + targets = { + @TestTarget( + methodName = "writeToParcel", + methodArgs = {Parcel.class, Integer.class} + ) + }) + public void testWriteToParcel() { + NetworkInfo[] ni = mConnectivityManager.getAllNetworkInfo(); + Parcel p = Parcel.obtain(); + ni[ConnectivityManager.TYPE_MOBILE].writeToParcel(p, 1); + p.setDataPosition(0); + NetworkInfo mNetworkInfo = NetworkInfo.CREATOR.createFromParcel(p); + assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getExtraInfo(), + mNetworkInfo.getExtraInfo()); + assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getReason(), + mNetworkInfo.getReason()); + assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getType(), + mNetworkInfo.getType()); + assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getState(), + mNetworkInfo.getState()); + assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getDetailedState(), + mNetworkInfo.getDetailedState()); + assertEquals(ni[ConnectivityManager.TYPE_MOBILE].isAvailable(), + mNetworkInfo.isAvailable()); + assertEquals(ni[ConnectivityManager.TYPE_MOBILE].isFailover(), + mNetworkInfo.isFailover()); + } +} diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java new file mode 100644 index 0000000000..64597242a7 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2008 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.net.NetworkInfo.DetailedState; +import android.test.AndroidTestCase; +import dalvik.annotation.TestInfo; +import dalvik.annotation.TestStatus; +import dalvik.annotation.TestTarget; +import dalvik.annotation.TestTargetClass; + +@TestTargetClass(DetailedState.class) +public class NetworkInfo_DetailedStateTest extends AndroidTestCase { + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + @TestInfo( + status = TestStatus.TBR, + notes = "Test valueOf(String name).", + targets = { + @TestTarget( + methodName = "valueOf", + methodArgs = {String.class} + ) + }) + public void testValueOf() { + assertEquals(DetailedState.AUTHENTICATING, DetailedState + .valueOf("AUTHENTICATING")); + assertEquals(DetailedState.CONNECTED, DetailedState + .valueOf("CONNECTED")); + assertEquals(DetailedState.CONNECTING, DetailedState + .valueOf("CONNECTING")); + assertEquals(DetailedState.DISCONNECTED, DetailedState + .valueOf("DISCONNECTED")); + assertEquals(DetailedState.DISCONNECTING, DetailedState + .valueOf("DISCONNECTING")); + assertEquals(DetailedState.FAILED, DetailedState.valueOf("FAILED")); + assertEquals(DetailedState.IDLE, DetailedState.valueOf("IDLE")); + assertEquals(DetailedState.OBTAINING_IPADDR, DetailedState + .valueOf("OBTAINING_IPADDR")); + assertEquals(DetailedState.SCANNING, DetailedState.valueOf("SCANNING")); + assertEquals(DetailedState.SUSPENDED, DetailedState + .valueOf("SUSPENDED")); + } + + @TestInfo( + status = TestStatus.TBR, + notes = "Test values().", + targets = { + @TestTarget( + methodName = "values", + methodArgs = {} + ) + }) + public void testValues() { + DetailedState[] expected = DetailedState.values(); + assertEquals(10, expected.length); + assertEquals(DetailedState.IDLE, expected[0]); + assertEquals(DetailedState.SCANNING, expected[1]); + assertEquals(DetailedState.CONNECTING, expected[2]); + assertEquals(DetailedState.AUTHENTICATING, expected[3]); + assertEquals(DetailedState.OBTAINING_IPADDR, expected[4]); + assertEquals(DetailedState.CONNECTED, expected[5]); + assertEquals(DetailedState.SUSPENDED, expected[6]); + assertEquals(DetailedState.DISCONNECTING, expected[7]); + assertEquals(DetailedState.DISCONNECTED, expected[8]); + assertEquals(DetailedState.FAILED, expected[9]); + } + +} diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java new file mode 100644 index 0000000000..b03c3f0215 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2008 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.test.AndroidTestCase; +import dalvik.annotation.TestInfo; +import dalvik.annotation.TestStatus; +import dalvik.annotation.TestTarget; +import dalvik.annotation.TestTargetClass; +import android.net.NetworkInfo.State; + +@TestTargetClass(State.class) +public class NetworkInfo_StateTest extends AndroidTestCase { + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + @TestInfo( + status = TestStatus.TBR, + notes = "Test valueOf(String name).", + targets = { + @TestTarget( + methodName = "valueOf", + methodArgs = {String.class} + ) + }) + public void testValueOf() { + assertEquals(State.CONNECTED, State.valueOf("CONNECTED")); + assertEquals(State.CONNECTING, State.valueOf("CONNECTING")); + assertEquals(State.DISCONNECTED, State.valueOf("DISCONNECTED")); + assertEquals(State.DISCONNECTING, State.valueOf("DISCONNECTING")); + assertEquals(State.SUSPENDED, State.valueOf("SUSPENDED")); + assertEquals(State.UNKNOWN, State.valueOf("UNKNOWN")); + } + + @TestInfo( + status = TestStatus.TBR, + notes = "Test values().", + targets = { + @TestTarget( + methodName = "values", + methodArgs = {} + ) + }) + public void testValues() { + State[] expected = State.values(); + assertEquals(6, expected.length); + assertEquals(State.CONNECTING, expected[0]); + assertEquals(State.CONNECTED, expected[1]); + assertEquals(State.SUSPENDED, expected[2]); + assertEquals(State.DISCONNECTING, expected[3]); + assertEquals(State.DISCONNECTED, expected[4]); + assertEquals(State.UNKNOWN, expected[5]); + } + +} diff --git a/tests/cts/net/src/android/net/cts/ProxyTest.java b/tests/cts/net/src/android/net/cts/ProxyTest.java new file mode 100644 index 0000000000..d9f7c1a942 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/ProxyTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2008 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.content.Context; +import android.net.Proxy; +import android.provider.Settings; +import android.test.AndroidTestCase; +import dalvik.annotation.TestInfo; +import dalvik.annotation.TestStatus; +import dalvik.annotation.TestTarget; +import dalvik.annotation.TestTargetClass; + +@TestTargetClass(Proxy.class) +public class ProxyTest extends AndroidTestCase { + @Override + protected void setUp() throws Exception { + super.setUp(); + + } + + @TestInfo( + status = TestStatus.TBR, + notes = "Test constructor(s) of Proxy.", + targets = { + @TestTarget( + methodName = "Proxy", + methodArgs = {} + ) + }) + public void testConstructor() { + + try { + Proxy proxy = new Proxy(); + } catch (Exception e) { + fail("shouldn't throw exception"); + } + } + + @TestInfo( + status = TestStatus.TBR, + notes = "Test getDefaultPort().", + targets = { + @TestTarget( + methodName = "getDefaultPort", + methodArgs = {} + ), + @TestTarget( + methodName = "getDefaultHost", + methodArgs = {} + ), + @TestTarget( + methodName = "getHost", + methodArgs = {Context.class} + ), + @TestTarget( + methodName = "getHost", + methodArgs = {Context.class} + ), + @TestTarget( + methodName = "getPort", + methodArgs = {Context.class} + ) + }) + public void testAccessProperties() { + String mHost = "www.google.com"; + int mPort = 8080; + String mHttpProxy = mHost + ":" + mPort; + + Settings.System.putString(mContext.getContentResolver(), + Settings.System.HTTP_PROXY, null); + assertNull(Proxy.getHost(mContext)); + assertEquals(-1,Proxy.getPort(mContext)); + + Settings.System.putString(mContext.getContentResolver(), + Settings.System.HTTP_PROXY, mHttpProxy); + assertEquals(mHost,Proxy.getHost(mContext)); + assertEquals(mPort,Proxy.getPort(mContext)); + } + +} + diff --git a/tests/cts/net/src/android/net/cts/UriTest.java b/tests/cts/net/src/android/net/cts/UriTest.java new file mode 100644 index 0000000000..84b58c081a --- /dev/null +++ b/tests/cts/net/src/android/net/cts/UriTest.java @@ -0,0 +1,727 @@ +/* + * Copyright (C) 2008 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 dalvik.annotation.TestTargets; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import android.content.ContentUris; +import android.net.Uri; +import android.os.Parcel; +import android.test.AndroidTestCase; +import java.io.File; +import java.util.Arrays; + +@TestTargetClass(Uri.class) +public class UriTest extends AndroidTestCase { + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test write to and read frome parcel.", + method = "writeToParcel", + args = {android.os.Parcel.class, android.net.Uri.class} + ) + public void testParcelling() { + parcelAndUnparcel(Uri.parse("foo:bob%20lee")); + parcelAndUnparcel(Uri.fromParts("foo", "bob lee", "fragment")); + parcelAndUnparcel(new Uri.Builder() + .scheme("http") + .authority("crazybob.org") + .path("/rss/") + .encodedQuery("a=b") + .fragment("foo") + .build()); + } + + private void parcelAndUnparcel(Uri u) { + Parcel p = Parcel.obtain(); + Uri.writeToParcel(p, u); + p.setDataPosition(0); + assertEquals(u, Uri.CREATOR.createFromParcel(p)); + + p.setDataPosition(0); + u = u.buildUpon().build(); + Uri.writeToParcel(p, u); + p.setDataPosition(0); + assertEquals(u, Uri.CREATOR.createFromParcel(p)); + } + + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test buildUpon", + method = "buildUpon", + args = {} + ) + public void testBuildUpon() { + Uri u = Uri.parse("bob:lee").buildUpon().scheme("robert").build(); + assertEquals("robert", u.getScheme()); + assertEquals("lee", u.getEncodedSchemeSpecificPart()); + assertEquals("lee", u.getSchemeSpecificPart()); + assertNull(u.getQuery()); + assertNull(u.getPath()); + assertNull(u.getAuthority()); + assertNull(u.getHost()); + + Uri a = Uri.fromParts("foo", "bar", "tee"); + Uri b = a.buildUpon().fragment("new").build(); + assertEquals("new", b.getFragment()); + assertEquals("bar", b.getSchemeSpecificPart()); + assertEquals("foo", b.getScheme()); + a = new Uri.Builder() + .scheme("foo") + .encodedOpaquePart("bar") + .fragment("tee") + .build(); + b = a.buildUpon().fragment("new").build(); + assertEquals("new", b.getFragment()); + assertEquals("bar", b.getSchemeSpecificPart()); + assertEquals("foo", b.getScheme()); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test string uri.", + method = "getSchemeSpecificPart", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test string uri.", + method = "getEncodedSchemeSpecificPart", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test string uri.", + method = "getEncodedPath", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test string uri.", + method = "getPath", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test string uri.", + method = "getEncodedQuery", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test string uri.", + method = "getQuery", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test string uri.", + method = "getEncodedFragment", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test string uri.", + method = "getHost", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test string uri.", + method = "getPort", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test string uri.", + method = "getUserInfo", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test string uri.", + method = "getEncodedUserInfo", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test string uri.", + method = "parse", + args = {java.lang.String.class} + ) + }) + public void testStringUri() { + assertEquals("bob lee", + Uri.parse("foo:bob%20lee").getSchemeSpecificPart()); + assertEquals("bob%20lee", + Uri.parse("foo:bob%20lee").getEncodedSchemeSpecificPart()); + + assertEquals("/bob%20lee", + Uri.parse("foo:/bob%20lee").getEncodedPath()); + assertNull(Uri.parse("foo:bob%20lee").getPath()); + + assertEquals("bob%20lee", + Uri.parse("foo:?bob%20lee").getEncodedQuery()); + assertNull(Uri.parse("foo:bob%20lee").getEncodedQuery()); + assertNull(Uri.parse("foo:bar#?bob%20lee").getQuery()); + + assertEquals("bob%20lee", + Uri.parse("foo:#bob%20lee").getEncodedFragment()); + + Uri uri = Uri.parse("http://localhost:42"); + assertEquals("localhost", uri.getHost()); + assertEquals(42, uri.getPort()); + + uri = Uri.parse("http://bob@localhost:42"); + assertEquals("bob", uri.getUserInfo()); + assertEquals("localhost", uri.getHost()); + assertEquals(42, uri.getPort()); + + uri = Uri.parse("http://bob%20lee@localhost:42"); + assertEquals("bob lee", uri.getUserInfo()); + assertEquals("bob%20lee", uri.getEncodedUserInfo()); + + uri = Uri.parse("http://localhost"); + assertEquals("localhost", uri.getHost()); + assertEquals(-1, uri.getPort()); + } + + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test compareTo", + method = "compareTo", + args = {android.net.Uri.class} + ) + public void testCompareTo() { + Uri a = Uri.parse("foo:a"); + Uri b = Uri.parse("foo:b"); + Uri b2 = Uri.parse("foo:b"); + + assertTrue(a.compareTo(b) < 0); + assertTrue(b.compareTo(a) > 0); + assertEquals(0, b.compareTo(b2)); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test equals and hashCode.", + method = "equals", + args = {java.lang.Object.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test equals and hashCode.", + method = "hashCode", + args = {} + ) + }) + public void testEqualsAndHashCode() { + Uri a = Uri.parse("http://crazybob.org/test/?foo=bar#tee"); + + Uri b = new Uri.Builder() + .scheme("http") + .authority("crazybob.org") + .path("/test/") + .encodedQuery("foo=bar") + .fragment("tee") + .build(); + + // Try alternate builder methods. + Uri c = new Uri.Builder() + .scheme("http") + .encodedAuthority("crazybob.org") + .encodedPath("/test/") + .encodedQuery("foo=bar") + .encodedFragment("tee") + .build(); + + assertFalse(Uri.EMPTY.equals(null)); + assertEquals(a, b); + assertEquals(b, c); + assertEquals(c, a); + assertEquals(a.hashCode(), b.hashCode()); + assertEquals(b.hashCode(), c.hashCode()); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test encode and decode.", + method = "encode", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test encode and decode.", + method = "encode", + args = {java.lang.String.class, java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test encode and decode.", + method = "decode", + args = {java.lang.String.class} + ) + }) + public void testEncodeAndDecode() { + String encoded = Uri.encode("Bob:/", "/"); + assertEquals(-1, encoded.indexOf(':')); + assertTrue(encoded.indexOf('/') > -1); + assertDecode(null); + assertDecode(""); + assertDecode("Bob"); + assertDecode(":Bob"); + assertDecode("::Bob"); + assertDecode("Bob::Lee"); + assertDecode("Bob:Lee"); + assertDecode("Bob::"); + assertDecode("Bob:"); + assertDecode("::Bob::"); + } + + private void assertDecode(String s) { + assertEquals(s, Uri.decode(Uri.encode(s, null))); + } + + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test fromFile.", + method = "fromFile", + args = {java.io.File.class} + ) + public void testFromFile() { + File f = new File("/tmp/bob"); + Uri uri = Uri.fromFile(f); + assertEquals("file:///tmp/bob", uri.toString()); + try { + Uri.fromFile(null); + fail("testFile fail"); + } catch (NullPointerException e) {} + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test get query parameters.", + method = "getQueryParameter", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test get query parameters.", + method = "getQueryParameters", + args = {java.lang.String.class} + ) + }) + public void testQueryParameters() { + Uri uri = Uri.parse("content://user"); + assertEquals(null, uri.getQueryParameter("a")); + + uri = uri.buildUpon().appendQueryParameter("a", "b").build(); + assertEquals("b", uri.getQueryParameter("a")); + + uri = uri.buildUpon().appendQueryParameter("a", "b2").build(); + assertEquals(Arrays.asList("b", "b2"), uri.getQueryParameters("a")); + + uri = uri.buildUpon().appendQueryParameter("c", "d").build(); + assertEquals(Arrays.asList("b", "b2"), uri.getQueryParameters("a")); + assertEquals("d", uri.getQueryParameter("c")); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.TODO, + notes = "", + method = "getPathSegments", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "", + method = "getLastPathSegment", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "", + method = "withAppendedPath", + args = {android.net.Uri.class, java.lang.String.class} + ) + }) + public void testPathOperations() { + Uri uri = Uri.parse("content://user/a/b"); + + assertEquals(2, uri.getPathSegments().size()); + assertEquals("a", uri.getPathSegments().get(0)); + assertEquals("b", uri.getPathSegments().get(1)); + assertEquals("b", uri.getLastPathSegment()); + + Uri first = uri; + uri = uri.buildUpon().appendPath("c").build(); + assertEquals(3, uri.getPathSegments().size()); + assertEquals("c", uri.getPathSegments().get(2)); + assertEquals("c", uri.getLastPathSegment()); + assertEquals("content://user/a/b/c", uri.toString()); + + uri = ContentUris.withAppendedId(uri, 100); + assertEquals(4, uri.getPathSegments().size()); + assertEquals("100", uri.getPathSegments().get(3)); + assertEquals("100", uri.getLastPathSegment()); + assertEquals(100, ContentUris.parseId(uri)); + assertEquals("content://user/a/b/c/100", uri.toString()); + + // Make sure the original URI is still intact. + assertEquals(2, first.getPathSegments().size()); + assertEquals("b", first.getLastPathSegment()); + + try { + first.getPathSegments().get(2); + fail("test path operations"); + } catch (IndexOutOfBoundsException e) {} + + assertEquals(null, Uri.EMPTY.getLastPathSegment()); + + Uri withC = Uri.parse("foo:/a/b/").buildUpon().appendPath("c").build(); + assertEquals("/a/b/c", withC.getPath()); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test opaque uri.", + method = "isAbsolute", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test opaque uri.", + method = "isOpaque", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test opaque uri.", + method = "isRelative", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test opaque uri.", + method = "getHost", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test opaque uri.", + method = "getPort", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test opaque uri.", + method = "getScheme", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test opaque uri.", + method = "getSchemeSpecificPart", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test opaque uri.", + method = "fromParts", + args = {java.lang.String.class, java.lang.String.class, java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test opaque uri.", + method = "toString", + args = {} + ) + }) + public void testOpaqueUri() { + Uri uri = Uri.parse("mailto:nobody"); + testOpaqueUri(uri); + + uri = uri.buildUpon().build(); + testOpaqueUri(uri); + + uri = Uri.fromParts("mailto", "nobody", null); + testOpaqueUri(uri); + + uri = uri.buildUpon().build(); + testOpaqueUri(uri); + + uri = new Uri.Builder() + .scheme("mailto") + .opaquePart("nobody") + .build(); + testOpaqueUri(uri); + + uri = uri.buildUpon().build(); + testOpaqueUri(uri); + } + + private void testOpaqueUri(Uri uri) { + assertEquals("mailto", uri.getScheme()); + assertEquals("nobody", uri.getSchemeSpecificPart()); + assertEquals("nobody", uri.getEncodedSchemeSpecificPart()); + + assertNull(uri.getFragment()); + assertTrue(uri.isAbsolute()); + assertTrue(uri.isOpaque()); + assertFalse(uri.isRelative()); + assertFalse(uri.isHierarchical()); + + assertNull(uri.getAuthority()); + assertNull(uri.getEncodedAuthority()); + assertNull(uri.getPath()); + assertNull(uri.getEncodedPath()); + assertNull(uri.getUserInfo()); + assertNull(uri.getEncodedUserInfo()); + assertNull(uri.getQuery()); + assertNull(uri.getEncodedQuery()); + assertNull(uri.getHost()); + assertEquals(-1, uri.getPort()); + + assertTrue(uri.getPathSegments().isEmpty()); + assertNull(uri.getLastPathSegment()); + + assertEquals("mailto:nobody", uri.toString()); + + Uri withFragment = uri.buildUpon().fragment("top").build(); + assertEquals("mailto:nobody#top", withFragment.toString()); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test hierarchical uris.", + method = "getAuthority", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test hierarchical uris.", + method = "getScheme", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test hierarchical uris.", + method = "getEncodedAuthority", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test hierarchical uris.", + method = "getPath", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test hierarchical uris.", + method = "getEncodedPath", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test hierarchical uris.", + method = "getQuery", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test hierarchical uris.", + method = "getEncodedQuery", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test hierarchical uris.", + method = "getFragment", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test hierarchical uris.", + method = "getEncodedFragment", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test hierarchical uris.", + method = "getSchemeSpecificPart", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test hierarchical uris.", + method = "isAbsolute", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test hierarchical uris.", + method = "isHierarchical", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test hierarchical uris.", + method = "isOpaque", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test hierarchical uris.", + method = "isRelative", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test hierarchical uris.", + method = "toString", + args = {} + ) + }) + public void testHierarchicalUris() { + testHierarchical("http", "google.com", "/p1/p2", "query", "fragment"); + testHierarchical("file", null, "/p1/p2", null, null); + testHierarchical("content", "contact", "/p1/p2", null, null); + testHierarchical("http", "google.com", "/p1/p2", null, "fragment"); + testHierarchical("http", "google.com", "", null, "fragment"); + testHierarchical("http", "google.com", "", "query", "fragment"); + testHierarchical("http", "google.com", "", "query", null); + testHierarchical("http", null, "/", "query", null); + } + + private static void testHierarchical(String scheme, String authority, + String path, String query, String fragment) { + StringBuilder sb = new StringBuilder(); + + if (authority != null) { + sb.append("//").append(authority); + } + if (path != null) { + sb.append(path); + } + if (query != null) { + sb.append('?').append(query); + } + + String ssp = sb.toString(); + + if (scheme != null) { + sb.insert(0, scheme + ":"); + } + if (fragment != null) { + sb.append('#').append(fragment); + } + + String uriString = sb.toString(); + + Uri uri = Uri.parse(uriString); + + // Run these twice to test caching. + compareHierarchical( + uriString, ssp, uri, scheme, authority, path, query, fragment); + compareHierarchical( + uriString, ssp, uri, scheme, authority, path, query, fragment); + + // Test rebuilt version. + uri = uri.buildUpon().build(); + + // Run these twice to test caching. + compareHierarchical( + uriString, ssp, uri, scheme, authority, path, query, fragment); + compareHierarchical( + uriString, ssp, uri, scheme, authority, path, query, fragment); + + // The decoded and encoded versions of the inputs are all the same. + // We'll test the actual encoding decoding separately. + + // Test building with encoded versions. + Uri built = new Uri.Builder() + .scheme(scheme) + .encodedAuthority(authority) + .encodedPath(path) + .encodedQuery(query) + .encodedFragment(fragment) + .build(); + + compareHierarchical( + uriString, ssp, built, scheme, authority, path, query, fragment); + compareHierarchical( + uriString, ssp, built, scheme, authority, path, query, fragment); + + // Test building with decoded versions. + built = new Uri.Builder() + .scheme(scheme) + .authority(authority) + .path(path) + .query(query) + .fragment(fragment) + .build(); + + compareHierarchical( + uriString, ssp, built, scheme, authority, path, query, fragment); + compareHierarchical( + uriString, ssp, built, scheme, authority, path, query, fragment); + + // Rebuild. + built = built.buildUpon().build(); + + compareHierarchical( + uriString, ssp, built, scheme, authority, path, query, fragment); + compareHierarchical( + uriString, ssp, built, scheme, authority, path, query, fragment); + } + + private static void compareHierarchical(String uriString, String ssp, + Uri uri, + String scheme, String authority, String path, String query, + String fragment) { + assertEquals(scheme, uri.getScheme()); + assertEquals(authority, uri.getAuthority()); + assertEquals(authority, uri.getEncodedAuthority()); + assertEquals(path, uri.getPath()); + assertEquals(path, uri.getEncodedPath()); + assertEquals(query, uri.getQuery()); + assertEquals(query, uri.getEncodedQuery()); + assertEquals(fragment, uri.getFragment()); + assertEquals(fragment, uri.getEncodedFragment()); + assertEquals(ssp, uri.getSchemeSpecificPart()); + + if (scheme != null) { + assertTrue(uri.isAbsolute()); + assertFalse(uri.isRelative()); + } else { + assertFalse(uri.isAbsolute()); + assertTrue(uri.isRelative()); + } + + assertFalse(uri.isOpaque()); + assertTrue(uri.isHierarchical()); + assertEquals(uriString, uri.toString()); + } +} diff --git a/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java b/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java new file mode 100644 index 0000000000..8a1b42341b --- /dev/null +++ b/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2008 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 junit.framework.TestCase; +import dalvik.annotation.TestTargets; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargetClass; +import android.net.Uri.Builder; +import android.net.Uri; + +@TestTargetClass(Uri.Builder.class) +public class Uri_BuilderTest extends TestCase { + @TestTargets({ + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test Builder operations.", + method = "Uri.Builder", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test Builder operations.", + method = "build", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test Builder operations.", + method = "scheme", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test Builder operations.", + method = "authority", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test Builder operations.", + method = "path", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test Builder operations.", + method = "query", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test Builder operations.", + method = "opaquePart", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test Builder operations.", + method = "fragment", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test Builder operations.", + method = "appendEncodedPath", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test Builder operations.", + method = "appendPath", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test Builder operations.", + method = "appendQueryParameter", + args = {java.lang.String.class, java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test Builder operations.", + method = "encodedAuthority", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test Builder operations.", + method = "encodedFragment", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test Builder operations.", + method = "encodedPath", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test Builder operations.", + method = "encodedQuery", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test Builder operations.", + method = "encodedOpaquePart", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test Builder operations.", + method = "toString", + args = {} + ) + }) + public void testBuilderOperations() { + Uri uri = Uri.parse("http://google.com/p1?query#fragment"); + Builder builder = uri.buildUpon(); + uri = builder.appendPath("p2").build(); + assertEquals("http", uri.getScheme()); + assertEquals("google.com", uri.getAuthority()); + assertEquals("/p1/p2", uri.getPath()); + assertEquals("query", uri.getQuery()); + assertEquals("fragment", uri.getFragment()); + assertEquals(uri.toString(), builder.toString()); + + uri = Uri.parse("mailto:nobody"); + builder = uri.buildUpon(); + uri = builder.build(); + assertEquals("mailto", uri.getScheme()); + assertEquals("nobody", uri.getSchemeSpecificPart()); + assertEquals(uri.toString(), builder.toString()); + + uri = new Uri.Builder() + .scheme("http") + .encodedAuthority("google.com") + .encodedPath("/p1") + .appendEncodedPath("p2") + .encodedQuery("query") + .appendQueryParameter("query2", null) + .encodedFragment("fragment") + .build(); + assertEquals("http", uri.getScheme()); + assertEquals("google.com", uri.getEncodedAuthority()); + assertEquals("/p1/p2", uri.getEncodedPath()); + assertEquals("query&query2=null", uri.getEncodedQuery()); + assertEquals("fragment", uri.getEncodedFragment()); + + uri = new Uri.Builder() + .scheme("mailto") + .encodedOpaquePart("nobody") + .build(); + assertEquals("mailto", uri.getScheme()); + assertEquals("nobody", uri.getEncodedSchemeSpecificPart()); + } +} + diff --git a/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java b/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java new file mode 100644 index 0000000000..6e23419de9 --- /dev/null +++ b/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java @@ -0,0 +1,302 @@ +/* + * Copyright (C) 2008 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.http.cts; + +import java.math.BigInteger; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Principal; +import java.security.PublicKey; +import java.security.SignatureException; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateExpiredException; +import java.security.cert.CertificateNotYetValidException; +import java.security.cert.X509Certificate; +import java.text.DateFormat; +import java.util.Date; +import java.util.Set; + +import junit.framework.TestCase; +import dalvik.annotation.TestTargets; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargetClass; +import android.net.http.SslCertificate; +import android.net.http.SslCertificate.DName; +import android.os.Bundle; + +@TestTargetClass(SslCertificate.class) +public class SslCertificateTest extends TestCase { + + @TestTargets({ + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test constructor(s) of SslCertificate.", + method = "SslCertificate", + args = {java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test constructor(s) of SslCertificate.", + method = "SslCertificate", + args = {java.security.cert.X509Certificate.class} + ) + }) + public void testConstructor() { + // new the SslCertificate instance + String date = DateFormat.getInstance().format(new Date()); + new SslCertificate("c=129", "e=weji", date, date); + + // new the SslCertificate instance + new SslCertificate(new MockX509Certificate()); + + } + + class MockX509Certificate extends X509Certificate { + + @Override + public void checkValidity() throws CertificateExpiredException, + CertificateNotYetValidException { + } + + @Override + public void checkValidity(Date date) throws CertificateExpiredException, + CertificateNotYetValidException { + } + + @Override + public int getBasicConstraints() { + return 0; + } + + @Override + public Principal getIssuerDN() { + return new MockPrincipal(); + } + + @Override + public boolean[] getIssuerUniqueID() { + return null; + } + + @Override + public boolean[] getKeyUsage() { + return null; + } + + @Override + public Date getNotAfter() { + return new Date(System.currentTimeMillis()); + } + + @Override + public Date getNotBefore() { + return new Date(System.currentTimeMillis() - 1000); + } + + @Override + public BigInteger getSerialNumber() { + return null; + } + + @Override + public String getSigAlgName() { + return null; + } + + @Override + public String getSigAlgOID() { + return null; + } + + @Override + public byte[] getSigAlgParams() { + return null; + } + + @Override + public byte[] getSignature() { + return null; + } + + @Override + public Principal getSubjectDN() { + return new MockPrincipal(); + } + + class MockPrincipal implements Principal { + public String getName() { + return null; + } + } + @Override + public boolean[] getSubjectUniqueID() { + return null; + } + + @Override + public byte[] getTBSCertificate() throws CertificateEncodingException { + return null; + } + + @Override + public int getVersion() { + return 0; + } + + @Override + public byte[] getEncoded() throws CertificateEncodingException { + return null; + } + + @Override + public PublicKey getPublicKey() { + return null; + } + + @Override + public String toString() { + return null; + } + + @Override + public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException, + InvalidKeyException, NoSuchProviderException, SignatureException { + } + + @Override + public void verify(PublicKey key, String sigProvider) throws CertificateException, + NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, + SignatureException { + } + + public Set getCriticalExtensionOIDs() { + return null; + } + + public byte[] getExtensionValue(String oid) { + return null; + } + + public Set getNonCriticalExtensionOIDs() { + return null; + } + + public boolean hasUnsupportedCriticalExtension() { + return false; + } + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test saveState and restoreState(SslCertificate certificate).", + method = "saveState", + args = {android.net.http.SslCertificate.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test saveState and restoreState(SslCertificate certificate).", + method = "restoreState", + args = {android.os.Bundle.class} + ) + }) + public void testState() { + // set the expected value + + Date date1 = new Date(System.currentTimeMillis() - 1000); + Date date2 = new Date(System.currentTimeMillis()); + SslCertificate ssl = new SslCertificate("c=129", "e=weji", DateFormat.getInstance().format( + date1), DateFormat.getInstance().format(date2)); + Bundle saved = SslCertificate.saveState(ssl); + assertTrue(saved.size() == 4); + + assertNotNull(saved.getString("issued-to")); + assertNotNull(saved.getString("issued-by")); + assertNotNull(saved.getString("valid-not-before")); + assertNotNull(saved.getString("valid-not-after")); + assertNull(SslCertificate.saveState(null)); + + SslCertificate restored = SslCertificate.restoreState(saved); + assertEquals(ssl.getValidNotAfter(), restored.getValidNotAfter()); + assertEquals(ssl.getValidNotBefore(), restored.getValidNotBefore()); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test getIssuedTo().", + method = "getIssuedTo", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test getIssuedTo().", + method = "getIssuedBy", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test getIssuedTo().", + method = "getValidNotAfter", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test getIssuedTo().", + method = "getValidNotBefore", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test getIssuedTo().", + method = "toString", + args = {} + ) + }) + public void testSslCertificate() { + + final String TO = "c=ccc,o=testOName,ou=testUName,cn=testCName"; + final String BY = "e=aeei,c=adb,o=testOName,ou=testUName,cn=testCName"; + // new the SslCertificate instance + Date date1 = new Date(System.currentTimeMillis() - 1000); + Date date2 = new Date(System.currentTimeMillis()); + SslCertificate ssl = new SslCertificate(TO, BY, DateFormat.getInstance().format( + date1), DateFormat.getInstance().format(date2)); + DName issuedTo = ssl.getIssuedTo(); + DName issuedBy = ssl.getIssuedBy(); + + assertEquals("testCName", issuedTo.getCName()); + assertEquals(TO, issuedTo.getDName()); + assertEquals("testOName", issuedTo.getOName()); + assertEquals("testUName", issuedTo.getUName()); + + assertEquals("testCName", issuedBy.getCName()); + assertEquals(BY, issuedBy.getDName()); + assertEquals("testOName", issuedBy.getOName()); + assertEquals("testUName", issuedBy.getUName()); + + assertEquals(DateFormat.getInstance().format(date1), ssl.getValidNotBefore()); + assertEquals(DateFormat.getInstance().format(date2), ssl.getValidNotAfter()); + final String EXPECTED = "Issued to: c=ccc,o=testOName,ou=testUName,cn=testCName;\n" + + "Issued by: e=aeei,c=adb,o=testOName,ou=testUName,cn=testCName;\n"; + assertEquals(EXPECTED, ssl.toString()); + } + +} diff --git a/tests/cts/net/src/android/net/http/cts/SslCertificate_DNameTest.java b/tests/cts/net/src/android/net/http/cts/SslCertificate_DNameTest.java new file mode 100644 index 0000000000..7562e3a847 --- /dev/null +++ b/tests/cts/net/src/android/net/http/cts/SslCertificate_DNameTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2008 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.http.cts; + +import java.text.DateFormat; +import java.util.Date; + +import junit.framework.TestCase; +import dalvik.annotation.TestTargets; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargetClass; +import android.net.http.SslCertificate; +import android.net.http.SslCertificate.DName; + +@TestTargetClass(DName.class) +public class SslCertificate_DNameTest extends TestCase { + + @TestTargets({ + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test DName.", + method = "SslCertificate.DName", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test DName.", + method = "getCName", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test DName.", + method = "getDName", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test DName.", + method = "getOName", + args = {} + ), + @TestTargetNew( + level = TestLevel.TODO, + notes = "Test DName.", + method = "getUName", + args = {} + ) + }) + public void testDName() { + final String TO = "c=ccc,o=testOName,ou=testUName,cn=testCName"; + final String BY = "e=aeei,c=adb,o=testOName,ou=testUName,cn=testCName"; + // new the SslCertificate instance + Date date1 = new Date(System.currentTimeMillis() - 1000); + Date date2 = new Date(System.currentTimeMillis()); + SslCertificate ssl = new SslCertificate(TO, BY, DateFormat.getInstance().format( + date1), DateFormat.getInstance().format(date2)); + DName issuedTo = ssl.getIssuedTo(); + + assertNotNull(issuedTo); + + assertEquals("testCName", issuedTo.getCName()); + assertEquals(TO, issuedTo.getDName()); + assertEquals("testOName", issuedTo.getOName()); + assertEquals("testUName", issuedTo.getUName()); + } + +} From 3cae4df32ad7dc766946b271fea7528d98a580a2 Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Wed, 18 Mar 2009 17:39:42 -0700 Subject: [PATCH 0002/1109] auto import from //branches/cupcake_rel/...@140373 --- tests/cts/net/Android.mk | 2 + .../net/cts/ConnectivityManagerTest.java | 41 +++++++++------- .../src/android/net/cts/NetworkInfoTest.java | 49 +++++++------------ 3 files changed, 42 insertions(+), 50 deletions(-) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index d1a459f0d3..0a2a6f382b 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -26,5 +26,7 @@ LOCAL_PACKAGE_NAME := CtsNetTestCases LOCAL_INSTRUMENTATION_FOR := CtsTestStubs +LOCAL_SDK_VERSION := current + include $(BUILD_PACKAGE) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 201105f0a6..f2ddd2143f 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -16,12 +16,11 @@ package android.net.cts; -import com.android.internal.telephony.Phone; - -import dalvik.annotation.TestTargets; -import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; + import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; @@ -112,10 +111,10 @@ public class ConnectivityManagerTest extends AndroidTestCase { }) public void testAccessNetworkPreference() { - final int EXPECTED = 1; + final int expected = 1; int per = mCm.getNetworkPreference(); - mCm.setNetworkPreference(EXPECTED); - assertEquals(EXPECTED, mCm.getNetworkPreference()); + mCm.setNetworkPreference(expected); + assertEquals(expected, mCm.getNetworkPreference()); mCm.setNetworkPreference(0); assertEquals(0, mCm.getNetworkPreference()); @@ -144,20 +143,22 @@ public class ConnectivityManagerTest extends AndroidTestCase { NetworkInfo[] ni = mCm.getAllNetworkInfo(); assertEquals(2, ni.length); - assertTrue(ni[0].getType() >=0 && ni[0].getType() <= 1); - assertTrue(ni[1].getType() >=0 && ni[1].getType() <= 1); + assertTrue(ni[0].getType() >= 0 && ni[0].getType() <= 1); + assertTrue(ni[1].getType() >= 0 && ni[1].getType() <= 1); } @TestTargets({ @TestTargetNew( level = TestLevel.TODO, - notes = "Test start and stop usingNetworkFeature(int networkType, String feature).", + notes = "Test startUsingNetworkFeature(int networkType, String feature)." + + "Only test failure case.", method = "startUsingNetworkFeature", args = {int.class, java.lang.String.class} ), @TestTargetNew( level = TestLevel.TODO, - notes = "Test start and stop usingNetworkFeature(int networkType, String feature).", + notes = "Test stopUsingNetworkFeature(int networkType, String feature)." + + "Only test failure case.", method = "stopUsingNetworkFeature", args = {int.class, java.lang.String.class} ) @@ -165,16 +166,18 @@ public class ConnectivityManagerTest extends AndroidTestCase { public void testStartUsingNetworkFeature() { final String invalidateFeature = "invalidateFeature"; - assertEquals(-1, mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, + // TODO: MMS feature string is not public + final String mmsFeature = "enableMMS"; + final int failureCode = -1; + + assertEquals(failureCode, mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, + invalidateFeature)); + assertEquals(failureCode, mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, invalidateFeature)); - assertEquals(-1, mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, - invalidateFeature)); - - assertEquals(-1, mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_WIFI, - Phone.FEATURE_ENABLE_MMS)); - assertEquals(-1, mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_WIFI, - Phone.FEATURE_ENABLE_MMS)); + // Should return failure(-1) because MMS is not supported on WIFI. + assertEquals(failureCode, mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_WIFI, mmsFeature)); + assertEquals(failureCode, mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_WIFI, mmsFeature)); } @TestTargetNew( diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java index 248ef9a71f..5036c4af60 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java @@ -16,6 +16,12 @@ package android.net.cts; +import dalvik.annotation.TestInfo; +import dalvik.annotation.TestStatus; +import dalvik.annotation.TestTarget; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.ToBeFixed; + import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; @@ -23,10 +29,6 @@ import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; import android.os.Parcel; import android.test.AndroidTestCase; -import dalvik.annotation.TestInfo; -import dalvik.annotation.TestStatus; -import dalvik.annotation.TestTarget; -import dalvik.annotation.TestTargetClass; @TestTargetClass(NetworkInfo.class) public class NetworkInfoTest extends AndroidTestCase { @@ -109,12 +111,10 @@ public class NetworkInfoTest extends AndroidTestCase { // test environment:connect as TYPE_MOBILE, and connect to internet. assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getType(), ConnectivityManager.TYPE_MOBILE); - assertEquals(ni[ConnectivityManager.TYPE_WIFI].getType(), - ConnectivityManager.TYPE_WIFI); - assertEquals("MOBILE",ni[ConnectivityManager.TYPE_MOBILE].getTypeName()); - assertEquals("WIFI",ni[ConnectivityManager.TYPE_WIFI].getTypeName()); - assertTrue(ni[ConnectivityManager.TYPE_MOBILE] - .isConnectedOrConnecting()); + assertEquals(ni[ConnectivityManager.TYPE_WIFI].getType(), ConnectivityManager.TYPE_WIFI); + assertEquals("MOBILE", ni[ConnectivityManager.TYPE_MOBILE].getTypeName()); + assertEquals("WIFI", ni[ConnectivityManager.TYPE_WIFI].getTypeName()); + assertTrue(ni[ConnectivityManager.TYPE_MOBILE].isConnectedOrConnecting()); assertFalse(ni[ConnectivityManager.TYPE_WIFI].isConnectedOrConnecting()); assertTrue(ni[ConnectivityManager.TYPE_MOBILE].isAvailable()); assertFalse(ni[ConnectivityManager.TYPE_WIFI].isAvailable()); @@ -124,14 +124,13 @@ public class NetworkInfoTest extends AndroidTestCase { assertEquals(ni[ConnectivityManager.TYPE_MOBILE].describeContents(), 0); assertEquals(ni[ConnectivityManager.TYPE_WIFI].describeContents(), 0); - assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getState(), - State.CONNECTED); + assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getState(), State.CONNECTED); assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getDetailedState(), DetailedState.CONNECTED); assertNull(ni[ConnectivityManager.TYPE_MOBILE].getReason()); assertNull(ni[ConnectivityManager.TYPE_WIFI].getReason()); - assertEquals("internet",ni[ConnectivityManager.TYPE_MOBILE].getExtraInfo()); + assertEquals("internet", ni[ConnectivityManager.TYPE_MOBILE].getExtraInfo()); assertNull(ni[ConnectivityManager.TYPE_WIFI].getExtraInfo()); assertNotNull(ni[ConnectivityManager.TYPE_MOBILE].toString()); @@ -147,25 +146,13 @@ public class NetworkInfoTest extends AndroidTestCase { methodArgs = {Parcel.class, Integer.class} ) }) + @ToBeFixed(bug = "1703933", explanation = "Cannot test if the data was written correctly," + + " if build CTS against SDK.") public void testWriteToParcel() { - NetworkInfo[] ni = mConnectivityManager.getAllNetworkInfo(); + NetworkInfo[] networkInfos = mConnectivityManager.getAllNetworkInfo(); + NetworkInfo mobileInfo = networkInfos[ConnectivityManager.TYPE_MOBILE]; Parcel p = Parcel.obtain(); - ni[ConnectivityManager.TYPE_MOBILE].writeToParcel(p, 1); - p.setDataPosition(0); - NetworkInfo mNetworkInfo = NetworkInfo.CREATOR.createFromParcel(p); - assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getExtraInfo(), - mNetworkInfo.getExtraInfo()); - assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getReason(), - mNetworkInfo.getReason()); - assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getType(), - mNetworkInfo.getType()); - assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getState(), - mNetworkInfo.getState()); - assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getDetailedState(), - mNetworkInfo.getDetailedState()); - assertEquals(ni[ConnectivityManager.TYPE_MOBILE].isAvailable(), - mNetworkInfo.isAvailable()); - assertEquals(ni[ConnectivityManager.TYPE_MOBILE].isFailover(), - mNetworkInfo.isFailover()); + + mobileInfo.writeToParcel(p, 1); } } From c2af01c91d3d9faa1923db4936083e8a0e217670 Mon Sep 17 00:00:00 2001 From: Scott Su <> Date: Thu, 26 Mar 2009 01:42:37 -0700 Subject: [PATCH 0003/1109] Automated import from //branches/cupcake/...@142888,142888 --- .../net/cts/ConnectivityManagerTest.java | 26 ++-- .../src/android/net/cts/CredentialsTest.java | 8 +- .../net/src/android/net/cts/DhcpInfoTest.java | 4 +- .../net/cts/LocalServerSocketTest.java | 58 ++++--- .../net/cts/LocalSocketAddressTest.java | 18 ++- .../cts/LocalSocketAddress_NamespaceTest.java | 5 +- .../src/android/net/cts/LocalSocketTest.java | 56 +++---- .../net/src/android/net/cts/MailToTest.java | 23 +-- .../src/android/net/cts/NetworkInfoTest.java | 144 ++++++++++-------- .../cts/NetworkInfo_DetailedStateTest.java | 35 ++--- .../net/cts/NetworkInfo_StateTest.java | 35 ++--- .../cts/net/src/android/net/cts/UriTest.java | 100 ++++++------ .../src/android/net/cts/Uri_BuilderTest.java | 35 +++-- .../net/http/cts/SslCertificateTest.java | 21 +-- .../http/cts/SslCertificate_DNameTest.java | 10 +- 15 files changed, 302 insertions(+), 276 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index f2ddd2143f..e8697bebab 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -41,7 +41,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getNetworkInfo(int networkType).", method = "getNetworkInfo", args = {int.class} @@ -73,13 +73,13 @@ public class ConnectivityManagerTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test isNetworkTypeValid(int networkType).", method = "isNetworkTypeValid", args = {int.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test isNetworkTypeValid(int networkType).", method = "getAllNetworkInfo", args = {} @@ -97,13 +97,13 @@ public class ConnectivityManagerTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "", method = "getNetworkPreference", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "", method = "setNetworkPreference", args = {int.class} @@ -133,7 +133,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getAllNetworkInfo().", method = "getAllNetworkInfo", args = {} @@ -149,14 +149,14 @@ public class ConnectivityManagerTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test startUsingNetworkFeature(int networkType, String feature)." + "Only test failure case.", method = "startUsingNetworkFeature", args = {int.class, java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test stopUsingNetworkFeature(int networkType, String feature)." + "Only test failure case.", method = "stopUsingNetworkFeature", @@ -176,12 +176,14 @@ public class ConnectivityManagerTest extends AndroidTestCase { invalidateFeature)); // Should return failure(-1) because MMS is not supported on WIFI. - assertEquals(failureCode, mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_WIFI, mmsFeature)); - assertEquals(failureCode, mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_WIFI, mmsFeature)); + assertEquals(failureCode, + mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_WIFI, mmsFeature)); + assertEquals(failureCode, + mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_WIFI, mmsFeature)); } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test requestRouteToHost(int networkType, int hostAddress).", method = "requestRouteToHost", args = {int.class, int.class} @@ -197,7 +199,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getActiveNetworkInfo().", method = "getActiveNetworkInfo", args = {} diff --git a/tests/cts/net/src/android/net/cts/CredentialsTest.java b/tests/cts/net/src/android/net/cts/CredentialsTest.java index 0f6e49e00d..fe65805294 100644 --- a/tests/cts/net/src/android/net/cts/CredentialsTest.java +++ b/tests/cts/net/src/android/net/cts/CredentialsTest.java @@ -28,25 +28,25 @@ public class CredentialsTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test constructor of Credentials, and test getGid, getPid, getUid.", method = "Credentials", args = {int.class, int.class, int.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test constructor of Credentials, and test getGid, getPid, getUid.", method = "getGid", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test constructor of Credentials, and test getGid, getPid, getUid.", method = "getPid", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test constructor of Credentials, and test getGid, getPid, getUid.", method = "getUid", args = {} diff --git a/tests/cts/net/src/android/net/cts/DhcpInfoTest.java b/tests/cts/net/src/android/net/cts/DhcpInfoTest.java index 657d03c368..1a1ad477fd 100644 --- a/tests/cts/net/src/android/net/cts/DhcpInfoTest.java +++ b/tests/cts/net/src/android/net/cts/DhcpInfoTest.java @@ -27,7 +27,7 @@ import dalvik.annotation.TestTargetClass; public class DhcpInfoTest extends AndroidTestCase { @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test DhcpInfo's constructor.", method = "DhcpInfo", args = {} @@ -37,7 +37,7 @@ public class DhcpInfoTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test toString function.", method = "toString", args = {} diff --git a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java index 4fb8481674..a6511e8521 100644 --- a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java @@ -25,41 +25,51 @@ import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.os.ParcelFileDescriptor; import android.test.AndroidTestCase; -import dalvik.annotation.TestInfo; +import dalvik.annotation.TestTargets; import dalvik.annotation.TestStatus; -import dalvik.annotation.TestTarget; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; import dalvik.annotation.ToBeFixed; @TestTargetClass(LocalServerSocket.class) public class LocalServerSocketTest extends AndroidTestCase { - @TestInfo( - status = TestStatus.TBR, - notes = "test LocalServerSocket", - targets = { - @TestTarget( - methodName = "accept", - methodArgs = {} + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test LocalServerSocket", + method = "accept", + args = {} ), - @TestTarget( - methodName = "close", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test LocalServerSocket", + method = "close", + args = {} ), - @TestTarget( - methodName = "getFileDescriptor", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test LocalServerSocket", + method = "getFileDescriptor", + args = {} ), - @TestTarget( - methodName = "getLocalSocketAddress", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test LocalServerSocket", + method = "getLocalSocketAddress", + args = {} ), - @TestTarget( - methodName = "LocalServerSocket", - methodArgs = {FileDescriptor.class} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test LocalServerSocket", + method = "LocalServerSocket", + args = {java.io.FileDescriptor.class} ), - @TestTarget( - methodName = "LocalServerSocket", - methodArgs = {String.class} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test LocalServerSocket", + method = "LocalServerSocket", + args = {java.lang.String.class} ) }) @ToBeFixed(bug = "1520987", explanation = "Cannot find a proper FileDescriptor for " + diff --git a/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java b/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java index cc3a1d38df..75232c4fff 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java @@ -34,25 +34,25 @@ public class LocalSocketAddressTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test LocalSocketAddress", method = "LocalSocketAddress", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test LocalSocketAddress", method = "LocalSocketAddress", args = {java.lang.String.class, android.net.LocalSocketAddress.Namespace.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test LocalSocketAddress", method = "getName", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test LocalSocketAddress", method = "getNamespace", args = {} @@ -65,17 +65,19 @@ public class LocalSocketAddressTest extends AndroidTestCase { assertEquals(Namespace.ABSTRACT, localSocketAddress.getNamespace()); // specify the namespace - LocalSocketAddress localSocketAddress2 = new LocalSocketAddress("name2", Namespace.ABSTRACT); + LocalSocketAddress localSocketAddress2 = + new LocalSocketAddress("name2", Namespace.ABSTRACT); assertEquals("name2", localSocketAddress2.getName()); assertEquals(Namespace.ABSTRACT, localSocketAddress2.getNamespace()); - LocalSocketAddress localSocketAddress3 = new LocalSocketAddress("name3", Namespace.FILESYSTEM); + LocalSocketAddress localSocketAddress3 = + new LocalSocketAddress("name3", Namespace.FILESYSTEM); assertEquals("name3", localSocketAddress3.getName()); assertEquals(Namespace.FILESYSTEM, localSocketAddress3.getNamespace()); - LocalSocketAddress localSocketAddress4 = new LocalSocketAddress("name4", Namespace.RESERVED); + LocalSocketAddress localSocketAddress4 = + new LocalSocketAddress("name4", Namespace.RESERVED); assertEquals("name4", localSocketAddress4.getName()); assertEquals(Namespace.RESERVED, localSocketAddress4.getNamespace()); } } - diff --git a/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java b/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java index a9acaa357d..5d29c81895 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java @@ -32,7 +32,7 @@ public class LocalSocketAddress_NamespaceTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test valueOf(String name).", method = "valueOf", args = {java.lang.String.class} @@ -44,7 +44,7 @@ public class LocalSocketAddress_NamespaceTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test values().", method = "values", args = {} @@ -56,4 +56,3 @@ public class LocalSocketAddress_NamespaceTest extends AndroidTestCase { assertEquals(Namespace.FILESYSTEM, expected[2]); } } - diff --git a/tests/cts/net/src/android/net/cts/LocalSocketTest.java b/tests/cts/net/src/android/net/cts/LocalSocketTest.java index ae0b51c0ed..8e3cd6714b 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketTest.java @@ -36,73 +36,73 @@ public class LocalSocketTest extends AndroidTestCase{ @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "LocalSocket", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "close", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "connect", args = {android.net.LocalSocketAddress.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "getAncillaryFileDescriptors", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "getFileDescriptor", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "getInputStream", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "getOutputStream", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "getPeerCredentials", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "isConnected", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "setFileDescriptorsForSend", args = {java.io.FileDescriptor[].class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "shutdownInput", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "shutdownOutput", args = {} @@ -192,91 +192,91 @@ public class LocalSocketTest extends AndroidTestCase{ @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "bind", args = {android.net.LocalSocketAddress.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "connect", args = {android.net.LocalSocketAddress.class, int.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "getLocalSocketAddress", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "getReceiveBufferSize", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "getRemoteSocketAddress", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "getSendBufferSize", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "getSoTimeout", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "isBound", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "isClosed", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "isInputShutdown", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "isOutputShutdown", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "setReceiveBufferSize", args = {int.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "setSendBufferSize", args = {int.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "setSoTimeout", args = {int.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "toString", args = {} @@ -285,7 +285,7 @@ public class LocalSocketTest extends AndroidTestCase{ public void testAccessors() throws IOException{ LocalSocket socket = new LocalSocket(); LocalSocketAddress addr = new LocalSocketAddress("secondary"); - + assertFalse(socket.isBound()); socket.bind(addr); assertTrue(socket.isBound()); diff --git a/tests/cts/net/src/android/net/cts/MailToTest.java b/tests/cts/net/src/android/net/cts/MailToTest.java index e419272517..e64aaf46e0 100644 --- a/tests/cts/net/src/android/net/cts/MailToTest.java +++ b/tests/cts/net/src/android/net/cts/MailToTest.java @@ -28,7 +28,8 @@ import dalvik.annotation.TestTargetClass; public class MailToTest extends AndroidTestCase { private static final String MAILTOURI_1 = "mailto:chris@example.com"; private static final String MAILTOURI_2 = "mailto:infobot@example.com?subject=current-issue"; - private static final String MAILTOURI_3 = "mailto:infobot@example.com?body=send%20current-issue"; + private static final String MAILTOURI_3 = + "mailto:infobot@example.com?body=send%20current-issue"; private static final String MAILTOURI_4 = "mailto:infobot@example.com?body=send%20current-" + "issue%0D%0Asend%20index"; private static final String MAILTOURI_5 = "mailto:joe@example.com?" + @@ -43,49 +44,49 @@ public class MailToTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "parse", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "isMailTo", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "getTo", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "getSubject", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "getBody", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "getCc", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "toString", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "getHeaders", args = {} @@ -136,7 +137,8 @@ public class MailToTest extends AndroidTestCase { assertEquals("send current-issue\r\nsend index", mailTo_4.getBody()); assertNull(mailTo_4.getCc()); assertNull(mailTo_4.getSubject()); - assertEquals("mailto:?body=send%20current-issue%0D%0Asend%20index&to=infobot%40example.com&", + assertEquals( + "mailto:?body=send%20current-issue%0D%0Asend%20index&to=infobot%40example.com&", mailTo_4.toString()); assertTrue(MailTo.isMailTo(MAILTOURI_5)); @@ -164,4 +166,3 @@ public class MailToTest extends AndroidTestCase { mailTo_6.toString()); } } - diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java index 5036c4af60..46da3ca74f 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java @@ -16,10 +16,6 @@ package android.net.cts; -import dalvik.annotation.TestInfo; -import dalvik.annotation.TestStatus; -import dalvik.annotation.TestTarget; -import dalvik.annotation.TestTargetClass; import dalvik.annotation.ToBeFixed; import android.content.Context; @@ -29,6 +25,11 @@ import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; import android.os.Parcel; import android.test.AndroidTestCase; +import dalvik.annotation.TestTargets; +import dalvik.annotation.TestStatus; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; @TestTargetClass(NetworkInfo.class) public class NetworkInfoTest extends AndroidTestCase { @@ -41,65 +42,90 @@ public class NetworkInfoTest extends AndroidTestCase { .getSystemService(Context.CONNECTIVITY_SERVICE); } - @TestInfo( - status = TestStatus.TBR, - notes = "Test isConnectedOrConnecting().", - targets = { - @TestTarget( - methodName = "isConnectedOrConnecting", - methodArgs = {} + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "isConnectedOrConnecting", + args = {} ), - @TestTarget( - methodName = "setFailover", - methodArgs = {boolean.class} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "setFailover", + args = {boolean.class} ), - @TestTarget( - methodName = "isFailover", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "isFailover", + args = {} ), - @TestTarget( - methodName = "getType", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "getType", + args = {} ), - @TestTarget( - methodName = "getTypeName", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "getTypeName", + args = {} ), - @TestTarget( - methodName = "setIsAvailable", - methodArgs = {boolean.class} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "setIsAvailable", + args = {boolean.class} ), - @TestTarget( - methodName = "isAvailable", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "isAvailable", + args = {} ), - @TestTarget( - methodName = "isConnected", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "isConnected", + args = {} ), - @TestTarget( - methodName = "describeContents", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "describeContents", + args = {} ), - @TestTarget( - methodName = "getDetailedState", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "getDetailedState", + args = {} ), - @TestTarget( - methodName = "getState", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "getState", + args = {} ), - @TestTarget( - methodName = "getReason", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "getReason", + args = {} ), - @TestTarget( - methodName = "getExtraInfo", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "getExtraInfo", + args = {} ), - @TestTarget( - methodName = "toString", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "toString", + args = {} ) }) public void testAccessNetworkInfoProperties() { @@ -137,17 +163,13 @@ public class NetworkInfoTest extends AndroidTestCase { assertNotNull(ni[ConnectivityManager.TYPE_WIFI].toString()); } - @TestInfo( - status = TestStatus.TBR, - notes = "Test writeToParcel(Parcel dest, int flags).", - targets = { - @TestTarget( - methodName = "writeToParcel", - methodArgs = {Parcel.class, Integer.class} - ) - }) - @ToBeFixed(bug = "1703933", explanation = "Cannot test if the data was written correctly," - + " if build CTS against SDK.") + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test writeToParcel(Parcel dest, int flags).", + method = "writeToParcel", + args = {android.os.Parcel.class, java.lang.Integer.class} + ) + //@ToBeFixed(bug = "1703933", explanation = "Cannot test if the data was written correctly," public void testWriteToParcel() { NetworkInfo[] networkInfos = mConnectivityManager.getAllNetworkInfo(); NetworkInfo mobileInfo = networkInfos[ConnectivityManager.TYPE_MOBILE]; diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java index 64597242a7..002adfecaf 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java @@ -18,9 +18,10 @@ package android.net.cts; import android.net.NetworkInfo.DetailedState; import android.test.AndroidTestCase; -import dalvik.annotation.TestInfo; +import dalvik.annotation.TestTargets; import dalvik.annotation.TestStatus; -import dalvik.annotation.TestTarget; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; @TestTargetClass(DetailedState.class) @@ -31,15 +32,12 @@ public class NetworkInfo_DetailedStateTest extends AndroidTestCase { super.setUp(); } - @TestInfo( - status = TestStatus.TBR, - notes = "Test valueOf(String name).", - targets = { - @TestTarget( - methodName = "valueOf", - methodArgs = {String.class} - ) - }) + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test valueOf(String name).", + method = "valueOf", + args = {java.lang.String.class} + ) public void testValueOf() { assertEquals(DetailedState.AUTHENTICATING, DetailedState .valueOf("AUTHENTICATING")); @@ -60,15 +58,12 @@ public class NetworkInfo_DetailedStateTest extends AndroidTestCase { .valueOf("SUSPENDED")); } - @TestInfo( - status = TestStatus.TBR, - notes = "Test values().", - targets = { - @TestTarget( - methodName = "values", - methodArgs = {} - ) - }) + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test values().", + method = "values", + args = {} + ) public void testValues() { DetailedState[] expected = DetailedState.values(); assertEquals(10, expected.length); diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java index b03c3f0215..2f58784708 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java @@ -17,9 +17,10 @@ package android.net.cts; import android.test.AndroidTestCase; -import dalvik.annotation.TestInfo; +import dalvik.annotation.TestTargets; import dalvik.annotation.TestStatus; -import dalvik.annotation.TestTarget; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; import android.net.NetworkInfo.State; @@ -31,15 +32,12 @@ public class NetworkInfo_StateTest extends AndroidTestCase { super.setUp(); } - @TestInfo( - status = TestStatus.TBR, - notes = "Test valueOf(String name).", - targets = { - @TestTarget( - methodName = "valueOf", - methodArgs = {String.class} - ) - }) + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test valueOf(String name).", + method = "valueOf", + args = {java.lang.String.class} + ) public void testValueOf() { assertEquals(State.CONNECTED, State.valueOf("CONNECTED")); assertEquals(State.CONNECTING, State.valueOf("CONNECTING")); @@ -49,15 +47,12 @@ public class NetworkInfo_StateTest extends AndroidTestCase { assertEquals(State.UNKNOWN, State.valueOf("UNKNOWN")); } - @TestInfo( - status = TestStatus.TBR, - notes = "Test values().", - targets = { - @TestTarget( - methodName = "values", - methodArgs = {} - ) - }) + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test values().", + method = "values", + args = {} + ) public void testValues() { State[] expected = State.values(); assertEquals(6, expected.length); diff --git a/tests/cts/net/src/android/net/cts/UriTest.java b/tests/cts/net/src/android/net/cts/UriTest.java index 84b58c081a..067ce52372 100644 --- a/tests/cts/net/src/android/net/cts/UriTest.java +++ b/tests/cts/net/src/android/net/cts/UriTest.java @@ -30,7 +30,7 @@ import java.util.Arrays; @TestTargetClass(Uri.class) public class UriTest extends AndroidTestCase { @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test write to and read frome parcel.", method = "writeToParcel", args = {android.os.Parcel.class, android.net.Uri.class} @@ -61,7 +61,7 @@ public class UriTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test buildUpon", method = "buildUpon", args = {} @@ -94,73 +94,73 @@ public class UriTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getSchemeSpecificPart", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getEncodedSchemeSpecificPart", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getEncodedPath", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getPath", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getEncodedQuery", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getQuery", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getEncodedFragment", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getHost", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getPort", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getUserInfo", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getEncodedUserInfo", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "parse", args = {java.lang.String.class} @@ -203,7 +203,7 @@ public class UriTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test compareTo", method = "compareTo", args = {android.net.Uri.class} @@ -220,13 +220,13 @@ public class UriTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test equals and hashCode.", method = "equals", args = {java.lang.Object.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test equals and hashCode.", method = "hashCode", args = {} @@ -262,19 +262,19 @@ public class UriTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test encode and decode.", method = "encode", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test encode and decode.", method = "encode", args = {java.lang.String.class, java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test encode and decode.", method = "decode", args = {java.lang.String.class} @@ -301,7 +301,7 @@ public class UriTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test fromFile.", method = "fromFile", args = {java.io.File.class} @@ -318,13 +318,13 @@ public class UriTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test get query parameters.", method = "getQueryParameter", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test get query parameters.", method = "getQueryParameters", args = {java.lang.String.class} @@ -347,19 +347,19 @@ public class UriTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "", method = "getPathSegments", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "", method = "getLastPathSegment", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "", method = "withAppendedPath", args = {android.net.Uri.class, java.lang.String.class} @@ -404,55 +404,55 @@ public class UriTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "isAbsolute", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "isOpaque", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "isRelative", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "getHost", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "getPort", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "getScheme", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "getSchemeSpecificPart", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "fromParts", args = {java.lang.String.class, java.lang.String.class, java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "toString", args = {} @@ -514,91 +514,91 @@ public class UriTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getAuthority", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getScheme", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getEncodedAuthority", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getPath", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getEncodedPath", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getQuery", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getEncodedQuery", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getFragment", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getEncodedFragment", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getSchemeSpecificPart", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "isAbsolute", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "isHierarchical", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "isOpaque", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "isRelative", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "toString", args = {} diff --git a/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java b/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java index 8a1b42341b..66bdb074b0 100644 --- a/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java +++ b/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java @@ -28,103 +28,103 @@ import android.net.Uri; public class Uri_BuilderTest extends TestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "Uri.Builder", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "build", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "scheme", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "authority", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "path", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "query", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "opaquePart", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "fragment", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "appendEncodedPath", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "appendPath", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "appendQueryParameter", args = {java.lang.String.class, java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "encodedAuthority", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "encodedFragment", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "encodedPath", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "encodedQuery", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "encodedOpaquePart", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "toString", args = {} @@ -171,4 +171,3 @@ public class Uri_BuilderTest extends TestCase { assertEquals("nobody", uri.getEncodedSchemeSpecificPart()); } } - diff --git a/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java b/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java index 6e23419de9..91ca876fda 100644 --- a/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java +++ b/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java @@ -46,13 +46,14 @@ public class SslCertificateTest extends TestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test constructor(s) of SslCertificate.", method = "SslCertificate", - args = {java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class} + args = {java.lang.String.class, java.lang.String.class, java.lang.String.class, + java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test constructor(s) of SslCertificate.", method = "SslCertificate", args = {java.security.cert.X509Certificate.class} @@ -205,13 +206,13 @@ public class SslCertificateTest extends TestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test saveState and restoreState(SslCertificate certificate).", method = "saveState", args = {android.net.http.SslCertificate.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test saveState and restoreState(SslCertificate certificate).", method = "restoreState", args = {android.os.Bundle.class} @@ -240,31 +241,31 @@ public class SslCertificateTest extends TestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getIssuedTo().", method = "getIssuedTo", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getIssuedTo().", method = "getIssuedBy", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getIssuedTo().", method = "getValidNotAfter", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getIssuedTo().", method = "getValidNotBefore", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getIssuedTo().", method = "toString", args = {} diff --git a/tests/cts/net/src/android/net/http/cts/SslCertificate_DNameTest.java b/tests/cts/net/src/android/net/http/cts/SslCertificate_DNameTest.java index 7562e3a847..848bf7b95a 100644 --- a/tests/cts/net/src/android/net/http/cts/SslCertificate_DNameTest.java +++ b/tests/cts/net/src/android/net/http/cts/SslCertificate_DNameTest.java @@ -32,31 +32,31 @@ public class SslCertificate_DNameTest extends TestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test DName.", method = "SslCertificate.DName", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test DName.", method = "getCName", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test DName.", method = "getDName", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test DName.", method = "getOName", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test DName.", method = "getUName", args = {} From 02051d27459011773f90e8796009fde63b9be863 Mon Sep 17 00:00:00 2001 From: Scott Su <> Date: Fri, 27 Mar 2009 16:24:28 -0700 Subject: [PATCH 0004/1109] AI 143176: am: CL 142888 CTS annotation update update wrong TestLevel values update tests that were still using the old annotations minor fixes to eliminate eclipse warnings style fixes Original author: sus Merged from: //branches/cupcake/... Automated import of CL 143176 --- .../net/cts/ConnectivityManagerTest.java | 26 ++-- .../src/android/net/cts/CredentialsTest.java | 8 +- .../net/src/android/net/cts/DhcpInfoTest.java | 4 +- .../net/cts/LocalServerSocketTest.java | 58 ++++--- .../net/cts/LocalSocketAddressTest.java | 18 ++- .../cts/LocalSocketAddress_NamespaceTest.java | 5 +- .../src/android/net/cts/LocalSocketTest.java | 56 +++---- .../net/src/android/net/cts/MailToTest.java | 23 +-- .../src/android/net/cts/NetworkInfoTest.java | 144 ++++++++++-------- .../cts/NetworkInfo_DetailedStateTest.java | 35 ++--- .../net/cts/NetworkInfo_StateTest.java | 35 ++--- .../cts/net/src/android/net/cts/UriTest.java | 100 ++++++------ .../src/android/net/cts/Uri_BuilderTest.java | 35 +++-- .../net/http/cts/SslCertificateTest.java | 21 +-- .../http/cts/SslCertificate_DNameTest.java | 10 +- 15 files changed, 302 insertions(+), 276 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index f2ddd2143f..e8697bebab 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -41,7 +41,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getNetworkInfo(int networkType).", method = "getNetworkInfo", args = {int.class} @@ -73,13 +73,13 @@ public class ConnectivityManagerTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test isNetworkTypeValid(int networkType).", method = "isNetworkTypeValid", args = {int.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test isNetworkTypeValid(int networkType).", method = "getAllNetworkInfo", args = {} @@ -97,13 +97,13 @@ public class ConnectivityManagerTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "", method = "getNetworkPreference", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "", method = "setNetworkPreference", args = {int.class} @@ -133,7 +133,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getAllNetworkInfo().", method = "getAllNetworkInfo", args = {} @@ -149,14 +149,14 @@ public class ConnectivityManagerTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test startUsingNetworkFeature(int networkType, String feature)." + "Only test failure case.", method = "startUsingNetworkFeature", args = {int.class, java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test stopUsingNetworkFeature(int networkType, String feature)." + "Only test failure case.", method = "stopUsingNetworkFeature", @@ -176,12 +176,14 @@ public class ConnectivityManagerTest extends AndroidTestCase { invalidateFeature)); // Should return failure(-1) because MMS is not supported on WIFI. - assertEquals(failureCode, mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_WIFI, mmsFeature)); - assertEquals(failureCode, mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_WIFI, mmsFeature)); + assertEquals(failureCode, + mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_WIFI, mmsFeature)); + assertEquals(failureCode, + mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_WIFI, mmsFeature)); } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test requestRouteToHost(int networkType, int hostAddress).", method = "requestRouteToHost", args = {int.class, int.class} @@ -197,7 +199,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getActiveNetworkInfo().", method = "getActiveNetworkInfo", args = {} diff --git a/tests/cts/net/src/android/net/cts/CredentialsTest.java b/tests/cts/net/src/android/net/cts/CredentialsTest.java index 0f6e49e00d..fe65805294 100644 --- a/tests/cts/net/src/android/net/cts/CredentialsTest.java +++ b/tests/cts/net/src/android/net/cts/CredentialsTest.java @@ -28,25 +28,25 @@ public class CredentialsTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test constructor of Credentials, and test getGid, getPid, getUid.", method = "Credentials", args = {int.class, int.class, int.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test constructor of Credentials, and test getGid, getPid, getUid.", method = "getGid", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test constructor of Credentials, and test getGid, getPid, getUid.", method = "getPid", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test constructor of Credentials, and test getGid, getPid, getUid.", method = "getUid", args = {} diff --git a/tests/cts/net/src/android/net/cts/DhcpInfoTest.java b/tests/cts/net/src/android/net/cts/DhcpInfoTest.java index 657d03c368..1a1ad477fd 100644 --- a/tests/cts/net/src/android/net/cts/DhcpInfoTest.java +++ b/tests/cts/net/src/android/net/cts/DhcpInfoTest.java @@ -27,7 +27,7 @@ import dalvik.annotation.TestTargetClass; public class DhcpInfoTest extends AndroidTestCase { @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test DhcpInfo's constructor.", method = "DhcpInfo", args = {} @@ -37,7 +37,7 @@ public class DhcpInfoTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test toString function.", method = "toString", args = {} diff --git a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java index 4fb8481674..a6511e8521 100644 --- a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java @@ -25,41 +25,51 @@ import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.os.ParcelFileDescriptor; import android.test.AndroidTestCase; -import dalvik.annotation.TestInfo; +import dalvik.annotation.TestTargets; import dalvik.annotation.TestStatus; -import dalvik.annotation.TestTarget; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; import dalvik.annotation.ToBeFixed; @TestTargetClass(LocalServerSocket.class) public class LocalServerSocketTest extends AndroidTestCase { - @TestInfo( - status = TestStatus.TBR, - notes = "test LocalServerSocket", - targets = { - @TestTarget( - methodName = "accept", - methodArgs = {} + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test LocalServerSocket", + method = "accept", + args = {} ), - @TestTarget( - methodName = "close", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test LocalServerSocket", + method = "close", + args = {} ), - @TestTarget( - methodName = "getFileDescriptor", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test LocalServerSocket", + method = "getFileDescriptor", + args = {} ), - @TestTarget( - methodName = "getLocalSocketAddress", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test LocalServerSocket", + method = "getLocalSocketAddress", + args = {} ), - @TestTarget( - methodName = "LocalServerSocket", - methodArgs = {FileDescriptor.class} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test LocalServerSocket", + method = "LocalServerSocket", + args = {java.io.FileDescriptor.class} ), - @TestTarget( - methodName = "LocalServerSocket", - methodArgs = {String.class} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test LocalServerSocket", + method = "LocalServerSocket", + args = {java.lang.String.class} ) }) @ToBeFixed(bug = "1520987", explanation = "Cannot find a proper FileDescriptor for " + diff --git a/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java b/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java index cc3a1d38df..75232c4fff 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java @@ -34,25 +34,25 @@ public class LocalSocketAddressTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test LocalSocketAddress", method = "LocalSocketAddress", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test LocalSocketAddress", method = "LocalSocketAddress", args = {java.lang.String.class, android.net.LocalSocketAddress.Namespace.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test LocalSocketAddress", method = "getName", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test LocalSocketAddress", method = "getNamespace", args = {} @@ -65,17 +65,19 @@ public class LocalSocketAddressTest extends AndroidTestCase { assertEquals(Namespace.ABSTRACT, localSocketAddress.getNamespace()); // specify the namespace - LocalSocketAddress localSocketAddress2 = new LocalSocketAddress("name2", Namespace.ABSTRACT); + LocalSocketAddress localSocketAddress2 = + new LocalSocketAddress("name2", Namespace.ABSTRACT); assertEquals("name2", localSocketAddress2.getName()); assertEquals(Namespace.ABSTRACT, localSocketAddress2.getNamespace()); - LocalSocketAddress localSocketAddress3 = new LocalSocketAddress("name3", Namespace.FILESYSTEM); + LocalSocketAddress localSocketAddress3 = + new LocalSocketAddress("name3", Namespace.FILESYSTEM); assertEquals("name3", localSocketAddress3.getName()); assertEquals(Namespace.FILESYSTEM, localSocketAddress3.getNamespace()); - LocalSocketAddress localSocketAddress4 = new LocalSocketAddress("name4", Namespace.RESERVED); + LocalSocketAddress localSocketAddress4 = + new LocalSocketAddress("name4", Namespace.RESERVED); assertEquals("name4", localSocketAddress4.getName()); assertEquals(Namespace.RESERVED, localSocketAddress4.getNamespace()); } } - diff --git a/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java b/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java index a9acaa357d..5d29c81895 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java @@ -32,7 +32,7 @@ public class LocalSocketAddress_NamespaceTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test valueOf(String name).", method = "valueOf", args = {java.lang.String.class} @@ -44,7 +44,7 @@ public class LocalSocketAddress_NamespaceTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test values().", method = "values", args = {} @@ -56,4 +56,3 @@ public class LocalSocketAddress_NamespaceTest extends AndroidTestCase { assertEquals(Namespace.FILESYSTEM, expected[2]); } } - diff --git a/tests/cts/net/src/android/net/cts/LocalSocketTest.java b/tests/cts/net/src/android/net/cts/LocalSocketTest.java index ae0b51c0ed..8e3cd6714b 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketTest.java @@ -36,73 +36,73 @@ public class LocalSocketTest extends AndroidTestCase{ @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "LocalSocket", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "close", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "connect", args = {android.net.LocalSocketAddress.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "getAncillaryFileDescriptors", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "getFileDescriptor", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "getInputStream", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "getOutputStream", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "getPeerCredentials", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "isConnected", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "setFileDescriptorsForSend", args = {java.io.FileDescriptor[].class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "shutdownInput", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "shutdownOutput", args = {} @@ -192,91 +192,91 @@ public class LocalSocketTest extends AndroidTestCase{ @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "bind", args = {android.net.LocalSocketAddress.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "connect", args = {android.net.LocalSocketAddress.class, int.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "getLocalSocketAddress", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "getReceiveBufferSize", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "getRemoteSocketAddress", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "getSendBufferSize", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "getSoTimeout", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "isBound", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "isClosed", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "isInputShutdown", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "isOutputShutdown", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "setReceiveBufferSize", args = {int.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "setSendBufferSize", args = {int.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "setSoTimeout", args = {int.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "toString", args = {} @@ -285,7 +285,7 @@ public class LocalSocketTest extends AndroidTestCase{ public void testAccessors() throws IOException{ LocalSocket socket = new LocalSocket(); LocalSocketAddress addr = new LocalSocketAddress("secondary"); - + assertFalse(socket.isBound()); socket.bind(addr); assertTrue(socket.isBound()); diff --git a/tests/cts/net/src/android/net/cts/MailToTest.java b/tests/cts/net/src/android/net/cts/MailToTest.java index e419272517..e64aaf46e0 100644 --- a/tests/cts/net/src/android/net/cts/MailToTest.java +++ b/tests/cts/net/src/android/net/cts/MailToTest.java @@ -28,7 +28,8 @@ import dalvik.annotation.TestTargetClass; public class MailToTest extends AndroidTestCase { private static final String MAILTOURI_1 = "mailto:chris@example.com"; private static final String MAILTOURI_2 = "mailto:infobot@example.com?subject=current-issue"; - private static final String MAILTOURI_3 = "mailto:infobot@example.com?body=send%20current-issue"; + private static final String MAILTOURI_3 = + "mailto:infobot@example.com?body=send%20current-issue"; private static final String MAILTOURI_4 = "mailto:infobot@example.com?body=send%20current-" + "issue%0D%0Asend%20index"; private static final String MAILTOURI_5 = "mailto:joe@example.com?" + @@ -43,49 +44,49 @@ public class MailToTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "parse", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "isMailTo", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "getTo", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "getSubject", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "getBody", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "getCc", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "toString", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "getHeaders", args = {} @@ -136,7 +137,8 @@ public class MailToTest extends AndroidTestCase { assertEquals("send current-issue\r\nsend index", mailTo_4.getBody()); assertNull(mailTo_4.getCc()); assertNull(mailTo_4.getSubject()); - assertEquals("mailto:?body=send%20current-issue%0D%0Asend%20index&to=infobot%40example.com&", + assertEquals( + "mailto:?body=send%20current-issue%0D%0Asend%20index&to=infobot%40example.com&", mailTo_4.toString()); assertTrue(MailTo.isMailTo(MAILTOURI_5)); @@ -164,4 +166,3 @@ public class MailToTest extends AndroidTestCase { mailTo_6.toString()); } } - diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java index 5036c4af60..46da3ca74f 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java @@ -16,10 +16,6 @@ package android.net.cts; -import dalvik.annotation.TestInfo; -import dalvik.annotation.TestStatus; -import dalvik.annotation.TestTarget; -import dalvik.annotation.TestTargetClass; import dalvik.annotation.ToBeFixed; import android.content.Context; @@ -29,6 +25,11 @@ import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; import android.os.Parcel; import android.test.AndroidTestCase; +import dalvik.annotation.TestTargets; +import dalvik.annotation.TestStatus; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; @TestTargetClass(NetworkInfo.class) public class NetworkInfoTest extends AndroidTestCase { @@ -41,65 +42,90 @@ public class NetworkInfoTest extends AndroidTestCase { .getSystemService(Context.CONNECTIVITY_SERVICE); } - @TestInfo( - status = TestStatus.TBR, - notes = "Test isConnectedOrConnecting().", - targets = { - @TestTarget( - methodName = "isConnectedOrConnecting", - methodArgs = {} + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "isConnectedOrConnecting", + args = {} ), - @TestTarget( - methodName = "setFailover", - methodArgs = {boolean.class} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "setFailover", + args = {boolean.class} ), - @TestTarget( - methodName = "isFailover", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "isFailover", + args = {} ), - @TestTarget( - methodName = "getType", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "getType", + args = {} ), - @TestTarget( - methodName = "getTypeName", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "getTypeName", + args = {} ), - @TestTarget( - methodName = "setIsAvailable", - methodArgs = {boolean.class} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "setIsAvailable", + args = {boolean.class} ), - @TestTarget( - methodName = "isAvailable", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "isAvailable", + args = {} ), - @TestTarget( - methodName = "isConnected", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "isConnected", + args = {} ), - @TestTarget( - methodName = "describeContents", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "describeContents", + args = {} ), - @TestTarget( - methodName = "getDetailedState", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "getDetailedState", + args = {} ), - @TestTarget( - methodName = "getState", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "getState", + args = {} ), - @TestTarget( - methodName = "getReason", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "getReason", + args = {} ), - @TestTarget( - methodName = "getExtraInfo", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "getExtraInfo", + args = {} ), - @TestTarget( - methodName = "toString", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "toString", + args = {} ) }) public void testAccessNetworkInfoProperties() { @@ -137,17 +163,13 @@ public class NetworkInfoTest extends AndroidTestCase { assertNotNull(ni[ConnectivityManager.TYPE_WIFI].toString()); } - @TestInfo( - status = TestStatus.TBR, - notes = "Test writeToParcel(Parcel dest, int flags).", - targets = { - @TestTarget( - methodName = "writeToParcel", - methodArgs = {Parcel.class, Integer.class} - ) - }) - @ToBeFixed(bug = "1703933", explanation = "Cannot test if the data was written correctly," - + " if build CTS against SDK.") + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test writeToParcel(Parcel dest, int flags).", + method = "writeToParcel", + args = {android.os.Parcel.class, java.lang.Integer.class} + ) + //@ToBeFixed(bug = "1703933", explanation = "Cannot test if the data was written correctly," public void testWriteToParcel() { NetworkInfo[] networkInfos = mConnectivityManager.getAllNetworkInfo(); NetworkInfo mobileInfo = networkInfos[ConnectivityManager.TYPE_MOBILE]; diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java index 64597242a7..002adfecaf 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java @@ -18,9 +18,10 @@ package android.net.cts; import android.net.NetworkInfo.DetailedState; import android.test.AndroidTestCase; -import dalvik.annotation.TestInfo; +import dalvik.annotation.TestTargets; import dalvik.annotation.TestStatus; -import dalvik.annotation.TestTarget; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; @TestTargetClass(DetailedState.class) @@ -31,15 +32,12 @@ public class NetworkInfo_DetailedStateTest extends AndroidTestCase { super.setUp(); } - @TestInfo( - status = TestStatus.TBR, - notes = "Test valueOf(String name).", - targets = { - @TestTarget( - methodName = "valueOf", - methodArgs = {String.class} - ) - }) + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test valueOf(String name).", + method = "valueOf", + args = {java.lang.String.class} + ) public void testValueOf() { assertEquals(DetailedState.AUTHENTICATING, DetailedState .valueOf("AUTHENTICATING")); @@ -60,15 +58,12 @@ public class NetworkInfo_DetailedStateTest extends AndroidTestCase { .valueOf("SUSPENDED")); } - @TestInfo( - status = TestStatus.TBR, - notes = "Test values().", - targets = { - @TestTarget( - methodName = "values", - methodArgs = {} - ) - }) + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test values().", + method = "values", + args = {} + ) public void testValues() { DetailedState[] expected = DetailedState.values(); assertEquals(10, expected.length); diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java index b03c3f0215..2f58784708 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java @@ -17,9 +17,10 @@ package android.net.cts; import android.test.AndroidTestCase; -import dalvik.annotation.TestInfo; +import dalvik.annotation.TestTargets; import dalvik.annotation.TestStatus; -import dalvik.annotation.TestTarget; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; import android.net.NetworkInfo.State; @@ -31,15 +32,12 @@ public class NetworkInfo_StateTest extends AndroidTestCase { super.setUp(); } - @TestInfo( - status = TestStatus.TBR, - notes = "Test valueOf(String name).", - targets = { - @TestTarget( - methodName = "valueOf", - methodArgs = {String.class} - ) - }) + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test valueOf(String name).", + method = "valueOf", + args = {java.lang.String.class} + ) public void testValueOf() { assertEquals(State.CONNECTED, State.valueOf("CONNECTED")); assertEquals(State.CONNECTING, State.valueOf("CONNECTING")); @@ -49,15 +47,12 @@ public class NetworkInfo_StateTest extends AndroidTestCase { assertEquals(State.UNKNOWN, State.valueOf("UNKNOWN")); } - @TestInfo( - status = TestStatus.TBR, - notes = "Test values().", - targets = { - @TestTarget( - methodName = "values", - methodArgs = {} - ) - }) + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test values().", + method = "values", + args = {} + ) public void testValues() { State[] expected = State.values(); assertEquals(6, expected.length); diff --git a/tests/cts/net/src/android/net/cts/UriTest.java b/tests/cts/net/src/android/net/cts/UriTest.java index 84b58c081a..067ce52372 100644 --- a/tests/cts/net/src/android/net/cts/UriTest.java +++ b/tests/cts/net/src/android/net/cts/UriTest.java @@ -30,7 +30,7 @@ import java.util.Arrays; @TestTargetClass(Uri.class) public class UriTest extends AndroidTestCase { @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test write to and read frome parcel.", method = "writeToParcel", args = {android.os.Parcel.class, android.net.Uri.class} @@ -61,7 +61,7 @@ public class UriTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test buildUpon", method = "buildUpon", args = {} @@ -94,73 +94,73 @@ public class UriTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getSchemeSpecificPart", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getEncodedSchemeSpecificPart", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getEncodedPath", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getPath", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getEncodedQuery", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getQuery", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getEncodedFragment", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getHost", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getPort", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getUserInfo", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getEncodedUserInfo", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "parse", args = {java.lang.String.class} @@ -203,7 +203,7 @@ public class UriTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test compareTo", method = "compareTo", args = {android.net.Uri.class} @@ -220,13 +220,13 @@ public class UriTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test equals and hashCode.", method = "equals", args = {java.lang.Object.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test equals and hashCode.", method = "hashCode", args = {} @@ -262,19 +262,19 @@ public class UriTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test encode and decode.", method = "encode", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test encode and decode.", method = "encode", args = {java.lang.String.class, java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test encode and decode.", method = "decode", args = {java.lang.String.class} @@ -301,7 +301,7 @@ public class UriTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test fromFile.", method = "fromFile", args = {java.io.File.class} @@ -318,13 +318,13 @@ public class UriTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test get query parameters.", method = "getQueryParameter", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test get query parameters.", method = "getQueryParameters", args = {java.lang.String.class} @@ -347,19 +347,19 @@ public class UriTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "", method = "getPathSegments", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "", method = "getLastPathSegment", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "", method = "withAppendedPath", args = {android.net.Uri.class, java.lang.String.class} @@ -404,55 +404,55 @@ public class UriTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "isAbsolute", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "isOpaque", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "isRelative", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "getHost", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "getPort", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "getScheme", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "getSchemeSpecificPart", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "fromParts", args = {java.lang.String.class, java.lang.String.class, java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "toString", args = {} @@ -514,91 +514,91 @@ public class UriTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getAuthority", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getScheme", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getEncodedAuthority", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getPath", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getEncodedPath", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getQuery", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getEncodedQuery", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getFragment", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getEncodedFragment", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getSchemeSpecificPart", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "isAbsolute", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "isHierarchical", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "isOpaque", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "isRelative", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "toString", args = {} diff --git a/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java b/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java index 8a1b42341b..66bdb074b0 100644 --- a/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java +++ b/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java @@ -28,103 +28,103 @@ import android.net.Uri; public class Uri_BuilderTest extends TestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "Uri.Builder", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "build", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "scheme", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "authority", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "path", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "query", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "opaquePart", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "fragment", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "appendEncodedPath", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "appendPath", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "appendQueryParameter", args = {java.lang.String.class, java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "encodedAuthority", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "encodedFragment", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "encodedPath", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "encodedQuery", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "encodedOpaquePart", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "toString", args = {} @@ -171,4 +171,3 @@ public class Uri_BuilderTest extends TestCase { assertEquals("nobody", uri.getEncodedSchemeSpecificPart()); } } - diff --git a/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java b/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java index 6e23419de9..91ca876fda 100644 --- a/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java +++ b/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java @@ -46,13 +46,14 @@ public class SslCertificateTest extends TestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test constructor(s) of SslCertificate.", method = "SslCertificate", - args = {java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class} + args = {java.lang.String.class, java.lang.String.class, java.lang.String.class, + java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test constructor(s) of SslCertificate.", method = "SslCertificate", args = {java.security.cert.X509Certificate.class} @@ -205,13 +206,13 @@ public class SslCertificateTest extends TestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test saveState and restoreState(SslCertificate certificate).", method = "saveState", args = {android.net.http.SslCertificate.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test saveState and restoreState(SslCertificate certificate).", method = "restoreState", args = {android.os.Bundle.class} @@ -240,31 +241,31 @@ public class SslCertificateTest extends TestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getIssuedTo().", method = "getIssuedTo", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getIssuedTo().", method = "getIssuedBy", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getIssuedTo().", method = "getValidNotAfter", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getIssuedTo().", method = "getValidNotBefore", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getIssuedTo().", method = "toString", args = {} diff --git a/tests/cts/net/src/android/net/http/cts/SslCertificate_DNameTest.java b/tests/cts/net/src/android/net/http/cts/SslCertificate_DNameTest.java index 7562e3a847..848bf7b95a 100644 --- a/tests/cts/net/src/android/net/http/cts/SslCertificate_DNameTest.java +++ b/tests/cts/net/src/android/net/http/cts/SslCertificate_DNameTest.java @@ -32,31 +32,31 @@ public class SslCertificate_DNameTest extends TestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test DName.", method = "SslCertificate.DName", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test DName.", method = "getCName", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test DName.", method = "getDName", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test DName.", method = "getOName", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test DName.", method = "getUName", args = {} From ab7e18c924ed6b8e752ac9f8d53cc99eae178631 Mon Sep 17 00:00:00 2001 From: Scott Su <> Date: Fri, 27 Mar 2009 18:17:33 -0700 Subject: [PATCH 0005/1109] AI 143326: am: CL 143176 am: CL 142888 CTS annotation update update wrong TestLevel values update tests that were still using the old annotations minor fixes to eliminate eclipse warnings style fixes Original author: sus Merged from: //branches/cupcake/... Original author: android-build Merged from: //branches/donutburger/... Automated import of CL 143326 --- .../net/cts/ConnectivityManagerTest.java | 26 ++-- .../src/android/net/cts/CredentialsTest.java | 8 +- .../net/src/android/net/cts/DhcpInfoTest.java | 4 +- .../net/cts/LocalServerSocketTest.java | 58 ++++--- .../net/cts/LocalSocketAddressTest.java | 18 ++- .../cts/LocalSocketAddress_NamespaceTest.java | 5 +- .../src/android/net/cts/LocalSocketTest.java | 56 +++---- .../net/src/android/net/cts/MailToTest.java | 23 +-- .../src/android/net/cts/NetworkInfoTest.java | 144 ++++++++++-------- .../cts/NetworkInfo_DetailedStateTest.java | 35 ++--- .../net/cts/NetworkInfo_StateTest.java | 35 ++--- .../cts/net/src/android/net/cts/UriTest.java | 100 ++++++------ .../src/android/net/cts/Uri_BuilderTest.java | 35 +++-- .../net/http/cts/SslCertificateTest.java | 21 +-- .../http/cts/SslCertificate_DNameTest.java | 10 +- 15 files changed, 302 insertions(+), 276 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index f2ddd2143f..e8697bebab 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -41,7 +41,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getNetworkInfo(int networkType).", method = "getNetworkInfo", args = {int.class} @@ -73,13 +73,13 @@ public class ConnectivityManagerTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test isNetworkTypeValid(int networkType).", method = "isNetworkTypeValid", args = {int.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test isNetworkTypeValid(int networkType).", method = "getAllNetworkInfo", args = {} @@ -97,13 +97,13 @@ public class ConnectivityManagerTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "", method = "getNetworkPreference", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "", method = "setNetworkPreference", args = {int.class} @@ -133,7 +133,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getAllNetworkInfo().", method = "getAllNetworkInfo", args = {} @@ -149,14 +149,14 @@ public class ConnectivityManagerTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test startUsingNetworkFeature(int networkType, String feature)." + "Only test failure case.", method = "startUsingNetworkFeature", args = {int.class, java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test stopUsingNetworkFeature(int networkType, String feature)." + "Only test failure case.", method = "stopUsingNetworkFeature", @@ -176,12 +176,14 @@ public class ConnectivityManagerTest extends AndroidTestCase { invalidateFeature)); // Should return failure(-1) because MMS is not supported on WIFI. - assertEquals(failureCode, mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_WIFI, mmsFeature)); - assertEquals(failureCode, mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_WIFI, mmsFeature)); + assertEquals(failureCode, + mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_WIFI, mmsFeature)); + assertEquals(failureCode, + mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_WIFI, mmsFeature)); } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test requestRouteToHost(int networkType, int hostAddress).", method = "requestRouteToHost", args = {int.class, int.class} @@ -197,7 +199,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getActiveNetworkInfo().", method = "getActiveNetworkInfo", args = {} diff --git a/tests/cts/net/src/android/net/cts/CredentialsTest.java b/tests/cts/net/src/android/net/cts/CredentialsTest.java index 0f6e49e00d..fe65805294 100644 --- a/tests/cts/net/src/android/net/cts/CredentialsTest.java +++ b/tests/cts/net/src/android/net/cts/CredentialsTest.java @@ -28,25 +28,25 @@ public class CredentialsTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test constructor of Credentials, and test getGid, getPid, getUid.", method = "Credentials", args = {int.class, int.class, int.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test constructor of Credentials, and test getGid, getPid, getUid.", method = "getGid", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test constructor of Credentials, and test getGid, getPid, getUid.", method = "getPid", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test constructor of Credentials, and test getGid, getPid, getUid.", method = "getUid", args = {} diff --git a/tests/cts/net/src/android/net/cts/DhcpInfoTest.java b/tests/cts/net/src/android/net/cts/DhcpInfoTest.java index 657d03c368..1a1ad477fd 100644 --- a/tests/cts/net/src/android/net/cts/DhcpInfoTest.java +++ b/tests/cts/net/src/android/net/cts/DhcpInfoTest.java @@ -27,7 +27,7 @@ import dalvik.annotation.TestTargetClass; public class DhcpInfoTest extends AndroidTestCase { @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test DhcpInfo's constructor.", method = "DhcpInfo", args = {} @@ -37,7 +37,7 @@ public class DhcpInfoTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test toString function.", method = "toString", args = {} diff --git a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java index 4fb8481674..a6511e8521 100644 --- a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java @@ -25,41 +25,51 @@ import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.os.ParcelFileDescriptor; import android.test.AndroidTestCase; -import dalvik.annotation.TestInfo; +import dalvik.annotation.TestTargets; import dalvik.annotation.TestStatus; -import dalvik.annotation.TestTarget; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; import dalvik.annotation.ToBeFixed; @TestTargetClass(LocalServerSocket.class) public class LocalServerSocketTest extends AndroidTestCase { - @TestInfo( - status = TestStatus.TBR, - notes = "test LocalServerSocket", - targets = { - @TestTarget( - methodName = "accept", - methodArgs = {} + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test LocalServerSocket", + method = "accept", + args = {} ), - @TestTarget( - methodName = "close", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test LocalServerSocket", + method = "close", + args = {} ), - @TestTarget( - methodName = "getFileDescriptor", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test LocalServerSocket", + method = "getFileDescriptor", + args = {} ), - @TestTarget( - methodName = "getLocalSocketAddress", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test LocalServerSocket", + method = "getLocalSocketAddress", + args = {} ), - @TestTarget( - methodName = "LocalServerSocket", - methodArgs = {FileDescriptor.class} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test LocalServerSocket", + method = "LocalServerSocket", + args = {java.io.FileDescriptor.class} ), - @TestTarget( - methodName = "LocalServerSocket", - methodArgs = {String.class} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test LocalServerSocket", + method = "LocalServerSocket", + args = {java.lang.String.class} ) }) @ToBeFixed(bug = "1520987", explanation = "Cannot find a proper FileDescriptor for " + diff --git a/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java b/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java index cc3a1d38df..75232c4fff 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java @@ -34,25 +34,25 @@ public class LocalSocketAddressTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test LocalSocketAddress", method = "LocalSocketAddress", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test LocalSocketAddress", method = "LocalSocketAddress", args = {java.lang.String.class, android.net.LocalSocketAddress.Namespace.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test LocalSocketAddress", method = "getName", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test LocalSocketAddress", method = "getNamespace", args = {} @@ -65,17 +65,19 @@ public class LocalSocketAddressTest extends AndroidTestCase { assertEquals(Namespace.ABSTRACT, localSocketAddress.getNamespace()); // specify the namespace - LocalSocketAddress localSocketAddress2 = new LocalSocketAddress("name2", Namespace.ABSTRACT); + LocalSocketAddress localSocketAddress2 = + new LocalSocketAddress("name2", Namespace.ABSTRACT); assertEquals("name2", localSocketAddress2.getName()); assertEquals(Namespace.ABSTRACT, localSocketAddress2.getNamespace()); - LocalSocketAddress localSocketAddress3 = new LocalSocketAddress("name3", Namespace.FILESYSTEM); + LocalSocketAddress localSocketAddress3 = + new LocalSocketAddress("name3", Namespace.FILESYSTEM); assertEquals("name3", localSocketAddress3.getName()); assertEquals(Namespace.FILESYSTEM, localSocketAddress3.getNamespace()); - LocalSocketAddress localSocketAddress4 = new LocalSocketAddress("name4", Namespace.RESERVED); + LocalSocketAddress localSocketAddress4 = + new LocalSocketAddress("name4", Namespace.RESERVED); assertEquals("name4", localSocketAddress4.getName()); assertEquals(Namespace.RESERVED, localSocketAddress4.getNamespace()); } } - diff --git a/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java b/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java index a9acaa357d..5d29c81895 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java @@ -32,7 +32,7 @@ public class LocalSocketAddress_NamespaceTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test valueOf(String name).", method = "valueOf", args = {java.lang.String.class} @@ -44,7 +44,7 @@ public class LocalSocketAddress_NamespaceTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test values().", method = "values", args = {} @@ -56,4 +56,3 @@ public class LocalSocketAddress_NamespaceTest extends AndroidTestCase { assertEquals(Namespace.FILESYSTEM, expected[2]); } } - diff --git a/tests/cts/net/src/android/net/cts/LocalSocketTest.java b/tests/cts/net/src/android/net/cts/LocalSocketTest.java index ae0b51c0ed..8e3cd6714b 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketTest.java @@ -36,73 +36,73 @@ public class LocalSocketTest extends AndroidTestCase{ @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "LocalSocket", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "close", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "connect", args = {android.net.LocalSocketAddress.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "getAncillaryFileDescriptors", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "getFileDescriptor", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "getInputStream", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "getOutputStream", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "getPeerCredentials", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "isConnected", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "setFileDescriptorsForSend", args = {java.io.FileDescriptor[].class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "shutdownInput", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test core functions of LocalSocket", method = "shutdownOutput", args = {} @@ -192,91 +192,91 @@ public class LocalSocketTest extends AndroidTestCase{ @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "bind", args = {android.net.LocalSocketAddress.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "connect", args = {android.net.LocalSocketAddress.class, int.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "getLocalSocketAddress", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "getReceiveBufferSize", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "getRemoteSocketAddress", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "getSendBufferSize", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "getSoTimeout", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "isBound", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "isClosed", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "isInputShutdown", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "isOutputShutdown", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "setReceiveBufferSize", args = {int.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "setSendBufferSize", args = {int.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "setSoTimeout", args = {int.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "test secondary functions of LocalSocket", method = "toString", args = {} @@ -285,7 +285,7 @@ public class LocalSocketTest extends AndroidTestCase{ public void testAccessors() throws IOException{ LocalSocket socket = new LocalSocket(); LocalSocketAddress addr = new LocalSocketAddress("secondary"); - + assertFalse(socket.isBound()); socket.bind(addr); assertTrue(socket.isBound()); diff --git a/tests/cts/net/src/android/net/cts/MailToTest.java b/tests/cts/net/src/android/net/cts/MailToTest.java index e419272517..e64aaf46e0 100644 --- a/tests/cts/net/src/android/net/cts/MailToTest.java +++ b/tests/cts/net/src/android/net/cts/MailToTest.java @@ -28,7 +28,8 @@ import dalvik.annotation.TestTargetClass; public class MailToTest extends AndroidTestCase { private static final String MAILTOURI_1 = "mailto:chris@example.com"; private static final String MAILTOURI_2 = "mailto:infobot@example.com?subject=current-issue"; - private static final String MAILTOURI_3 = "mailto:infobot@example.com?body=send%20current-issue"; + private static final String MAILTOURI_3 = + "mailto:infobot@example.com?body=send%20current-issue"; private static final String MAILTOURI_4 = "mailto:infobot@example.com?body=send%20current-" + "issue%0D%0Asend%20index"; private static final String MAILTOURI_5 = "mailto:joe@example.com?" + @@ -43,49 +44,49 @@ public class MailToTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "parse", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "isMailTo", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "getTo", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "getSubject", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "getBody", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "getCc", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "toString", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test parse mailto URI.", method = "getHeaders", args = {} @@ -136,7 +137,8 @@ public class MailToTest extends AndroidTestCase { assertEquals("send current-issue\r\nsend index", mailTo_4.getBody()); assertNull(mailTo_4.getCc()); assertNull(mailTo_4.getSubject()); - assertEquals("mailto:?body=send%20current-issue%0D%0Asend%20index&to=infobot%40example.com&", + assertEquals( + "mailto:?body=send%20current-issue%0D%0Asend%20index&to=infobot%40example.com&", mailTo_4.toString()); assertTrue(MailTo.isMailTo(MAILTOURI_5)); @@ -164,4 +166,3 @@ public class MailToTest extends AndroidTestCase { mailTo_6.toString()); } } - diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java index 5036c4af60..46da3ca74f 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java @@ -16,10 +16,6 @@ package android.net.cts; -import dalvik.annotation.TestInfo; -import dalvik.annotation.TestStatus; -import dalvik.annotation.TestTarget; -import dalvik.annotation.TestTargetClass; import dalvik.annotation.ToBeFixed; import android.content.Context; @@ -29,6 +25,11 @@ import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; import android.os.Parcel; import android.test.AndroidTestCase; +import dalvik.annotation.TestTargets; +import dalvik.annotation.TestStatus; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; @TestTargetClass(NetworkInfo.class) public class NetworkInfoTest extends AndroidTestCase { @@ -41,65 +42,90 @@ public class NetworkInfoTest extends AndroidTestCase { .getSystemService(Context.CONNECTIVITY_SERVICE); } - @TestInfo( - status = TestStatus.TBR, - notes = "Test isConnectedOrConnecting().", - targets = { - @TestTarget( - methodName = "isConnectedOrConnecting", - methodArgs = {} + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "isConnectedOrConnecting", + args = {} ), - @TestTarget( - methodName = "setFailover", - methodArgs = {boolean.class} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "setFailover", + args = {boolean.class} ), - @TestTarget( - methodName = "isFailover", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "isFailover", + args = {} ), - @TestTarget( - methodName = "getType", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "getType", + args = {} ), - @TestTarget( - methodName = "getTypeName", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "getTypeName", + args = {} ), - @TestTarget( - methodName = "setIsAvailable", - methodArgs = {boolean.class} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "setIsAvailable", + args = {boolean.class} ), - @TestTarget( - methodName = "isAvailable", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "isAvailable", + args = {} ), - @TestTarget( - methodName = "isConnected", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "isConnected", + args = {} ), - @TestTarget( - methodName = "describeContents", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "describeContents", + args = {} ), - @TestTarget( - methodName = "getDetailedState", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "getDetailedState", + args = {} ), - @TestTarget( - methodName = "getState", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "getState", + args = {} ), - @TestTarget( - methodName = "getReason", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "getReason", + args = {} ), - @TestTarget( - methodName = "getExtraInfo", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "getExtraInfo", + args = {} ), - @TestTarget( - methodName = "toString", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test isConnectedOrConnecting().", + method = "toString", + args = {} ) }) public void testAccessNetworkInfoProperties() { @@ -137,17 +163,13 @@ public class NetworkInfoTest extends AndroidTestCase { assertNotNull(ni[ConnectivityManager.TYPE_WIFI].toString()); } - @TestInfo( - status = TestStatus.TBR, - notes = "Test writeToParcel(Parcel dest, int flags).", - targets = { - @TestTarget( - methodName = "writeToParcel", - methodArgs = {Parcel.class, Integer.class} - ) - }) - @ToBeFixed(bug = "1703933", explanation = "Cannot test if the data was written correctly," - + " if build CTS against SDK.") + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test writeToParcel(Parcel dest, int flags).", + method = "writeToParcel", + args = {android.os.Parcel.class, java.lang.Integer.class} + ) + //@ToBeFixed(bug = "1703933", explanation = "Cannot test if the data was written correctly," public void testWriteToParcel() { NetworkInfo[] networkInfos = mConnectivityManager.getAllNetworkInfo(); NetworkInfo mobileInfo = networkInfos[ConnectivityManager.TYPE_MOBILE]; diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java index 64597242a7..002adfecaf 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java @@ -18,9 +18,10 @@ package android.net.cts; import android.net.NetworkInfo.DetailedState; import android.test.AndroidTestCase; -import dalvik.annotation.TestInfo; +import dalvik.annotation.TestTargets; import dalvik.annotation.TestStatus; -import dalvik.annotation.TestTarget; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; @TestTargetClass(DetailedState.class) @@ -31,15 +32,12 @@ public class NetworkInfo_DetailedStateTest extends AndroidTestCase { super.setUp(); } - @TestInfo( - status = TestStatus.TBR, - notes = "Test valueOf(String name).", - targets = { - @TestTarget( - methodName = "valueOf", - methodArgs = {String.class} - ) - }) + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test valueOf(String name).", + method = "valueOf", + args = {java.lang.String.class} + ) public void testValueOf() { assertEquals(DetailedState.AUTHENTICATING, DetailedState .valueOf("AUTHENTICATING")); @@ -60,15 +58,12 @@ public class NetworkInfo_DetailedStateTest extends AndroidTestCase { .valueOf("SUSPENDED")); } - @TestInfo( - status = TestStatus.TBR, - notes = "Test values().", - targets = { - @TestTarget( - methodName = "values", - methodArgs = {} - ) - }) + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test values().", + method = "values", + args = {} + ) public void testValues() { DetailedState[] expected = DetailedState.values(); assertEquals(10, expected.length); diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java index b03c3f0215..2f58784708 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java @@ -17,9 +17,10 @@ package android.net.cts; import android.test.AndroidTestCase; -import dalvik.annotation.TestInfo; +import dalvik.annotation.TestTargets; import dalvik.annotation.TestStatus; -import dalvik.annotation.TestTarget; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; import android.net.NetworkInfo.State; @@ -31,15 +32,12 @@ public class NetworkInfo_StateTest extends AndroidTestCase { super.setUp(); } - @TestInfo( - status = TestStatus.TBR, - notes = "Test valueOf(String name).", - targets = { - @TestTarget( - methodName = "valueOf", - methodArgs = {String.class} - ) - }) + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test valueOf(String name).", + method = "valueOf", + args = {java.lang.String.class} + ) public void testValueOf() { assertEquals(State.CONNECTED, State.valueOf("CONNECTED")); assertEquals(State.CONNECTING, State.valueOf("CONNECTING")); @@ -49,15 +47,12 @@ public class NetworkInfo_StateTest extends AndroidTestCase { assertEquals(State.UNKNOWN, State.valueOf("UNKNOWN")); } - @TestInfo( - status = TestStatus.TBR, - notes = "Test values().", - targets = { - @TestTarget( - methodName = "values", - methodArgs = {} - ) - }) + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test values().", + method = "values", + args = {} + ) public void testValues() { State[] expected = State.values(); assertEquals(6, expected.length); diff --git a/tests/cts/net/src/android/net/cts/UriTest.java b/tests/cts/net/src/android/net/cts/UriTest.java index 84b58c081a..067ce52372 100644 --- a/tests/cts/net/src/android/net/cts/UriTest.java +++ b/tests/cts/net/src/android/net/cts/UriTest.java @@ -30,7 +30,7 @@ import java.util.Arrays; @TestTargetClass(Uri.class) public class UriTest extends AndroidTestCase { @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test write to and read frome parcel.", method = "writeToParcel", args = {android.os.Parcel.class, android.net.Uri.class} @@ -61,7 +61,7 @@ public class UriTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test buildUpon", method = "buildUpon", args = {} @@ -94,73 +94,73 @@ public class UriTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getSchemeSpecificPart", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getEncodedSchemeSpecificPart", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getEncodedPath", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getPath", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getEncodedQuery", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getQuery", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getEncodedFragment", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getHost", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getPort", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getUserInfo", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "getEncodedUserInfo", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test string uri.", method = "parse", args = {java.lang.String.class} @@ -203,7 +203,7 @@ public class UriTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test compareTo", method = "compareTo", args = {android.net.Uri.class} @@ -220,13 +220,13 @@ public class UriTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test equals and hashCode.", method = "equals", args = {java.lang.Object.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test equals and hashCode.", method = "hashCode", args = {} @@ -262,19 +262,19 @@ public class UriTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test encode and decode.", method = "encode", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test encode and decode.", method = "encode", args = {java.lang.String.class, java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test encode and decode.", method = "decode", args = {java.lang.String.class} @@ -301,7 +301,7 @@ public class UriTest extends AndroidTestCase { } @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test fromFile.", method = "fromFile", args = {java.io.File.class} @@ -318,13 +318,13 @@ public class UriTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test get query parameters.", method = "getQueryParameter", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test get query parameters.", method = "getQueryParameters", args = {java.lang.String.class} @@ -347,19 +347,19 @@ public class UriTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "", method = "getPathSegments", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "", method = "getLastPathSegment", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "", method = "withAppendedPath", args = {android.net.Uri.class, java.lang.String.class} @@ -404,55 +404,55 @@ public class UriTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "isAbsolute", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "isOpaque", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "isRelative", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "getHost", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "getPort", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "getScheme", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "getSchemeSpecificPart", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "fromParts", args = {java.lang.String.class, java.lang.String.class, java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test opaque uri.", method = "toString", args = {} @@ -514,91 +514,91 @@ public class UriTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getAuthority", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getScheme", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getEncodedAuthority", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getPath", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getEncodedPath", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getQuery", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getEncodedQuery", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getFragment", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getEncodedFragment", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "getSchemeSpecificPart", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "isAbsolute", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "isHierarchical", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "isOpaque", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "isRelative", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test hierarchical uris.", method = "toString", args = {} diff --git a/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java b/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java index 8a1b42341b..66bdb074b0 100644 --- a/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java +++ b/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java @@ -28,103 +28,103 @@ import android.net.Uri; public class Uri_BuilderTest extends TestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "Uri.Builder", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "build", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "scheme", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "authority", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "path", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "query", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "opaquePart", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "fragment", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "appendEncodedPath", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "appendPath", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "appendQueryParameter", args = {java.lang.String.class, java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "encodedAuthority", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "encodedFragment", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "encodedPath", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "encodedQuery", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "encodedOpaquePart", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test Builder operations.", method = "toString", args = {} @@ -171,4 +171,3 @@ public class Uri_BuilderTest extends TestCase { assertEquals("nobody", uri.getEncodedSchemeSpecificPart()); } } - diff --git a/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java b/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java index 6e23419de9..91ca876fda 100644 --- a/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java +++ b/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java @@ -46,13 +46,14 @@ public class SslCertificateTest extends TestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test constructor(s) of SslCertificate.", method = "SslCertificate", - args = {java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class} + args = {java.lang.String.class, java.lang.String.class, java.lang.String.class, + java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test constructor(s) of SslCertificate.", method = "SslCertificate", args = {java.security.cert.X509Certificate.class} @@ -205,13 +206,13 @@ public class SslCertificateTest extends TestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test saveState and restoreState(SslCertificate certificate).", method = "saveState", args = {android.net.http.SslCertificate.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test saveState and restoreState(SslCertificate certificate).", method = "restoreState", args = {android.os.Bundle.class} @@ -240,31 +241,31 @@ public class SslCertificateTest extends TestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getIssuedTo().", method = "getIssuedTo", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getIssuedTo().", method = "getIssuedBy", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getIssuedTo().", method = "getValidNotAfter", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getIssuedTo().", method = "getValidNotBefore", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test getIssuedTo().", method = "toString", args = {} diff --git a/tests/cts/net/src/android/net/http/cts/SslCertificate_DNameTest.java b/tests/cts/net/src/android/net/http/cts/SslCertificate_DNameTest.java index 7562e3a847..848bf7b95a 100644 --- a/tests/cts/net/src/android/net/http/cts/SslCertificate_DNameTest.java +++ b/tests/cts/net/src/android/net/http/cts/SslCertificate_DNameTest.java @@ -32,31 +32,31 @@ public class SslCertificate_DNameTest extends TestCase { @TestTargets({ @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test DName.", method = "SslCertificate.DName", args = {java.lang.String.class} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test DName.", method = "getCName", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test DName.", method = "getDName", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test DName.", method = "getOName", args = {} ), @TestTargetNew( - level = TestLevel.TODO, + level = TestLevel.COMPLETE, notes = "Test DName.", method = "getUName", args = {} From c9ef937af0967fd7913c1ccbdaa79c4c45a4966b Mon Sep 17 00:00:00 2001 From: Scott Su <> Date: Thu, 9 Apr 2009 22:21:00 -0700 Subject: [PATCH 0006/1109] AI 145668: CTS: add test cases for net.UrlQuerySanitizer. Automated import of CL 145668 --- .../net/cts/UrlQuerySanitizerTest.java | 416 ++++++++++++++++++ ...er_IllegalCharacterValueSanitizerTest.java | 48 ++ ...QuerySanitizer_ParameterValuePairTest.java | 43 ++ 3 files changed, 507 insertions(+) create mode 100644 tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java create mode 100644 tests/cts/net/src/android/net/cts/UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java create mode 100644 tests/cts/net/src/android/net/cts/UrlQuerySanitizer_ParameterValuePairTest.java diff --git a/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java b/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java new file mode 100644 index 0000000000..e9ae95c303 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java @@ -0,0 +1,416 @@ +/* + * Copyright (C) 2009 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 java.util.List; +import java.util.Set; +import android.net.UrlQuerySanitizer; +import android.net.UrlQuerySanitizer.IllegalCharacterValueSanitizer; +import android.net.UrlQuerySanitizer.ParameterValuePair; +import android.net.UrlQuerySanitizer.ValueSanitizer; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; + +@TestTargetClass(UrlQuerySanitizer.class) +public class UrlQuerySanitizerTest extends AndroidTestCase { + private static final int ALL_OK = IllegalCharacterValueSanitizer.ALL_OK; + + // URL for test. + private static final String TEST_URL = "http://example.com/?name=Joe+User&age=20&height=175"; + + // Default sanitizer's change when "+". + private static final String EXPECTED_UNDERLINE_NAME = "Joe_User"; + + // IllegalCharacterValueSanitizer sanitizer's change when "+". + private static final String EXPECTED_SPACE_NAME = "Joe User"; + private static final String EXPECTED_AGE = "20"; + private static final String EXPECTED_HEIGHT = "175"; + private static final String NAME = "name"; + private static final String AGE = "age"; + private static final String HEIGHT = "height"; + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test constructor(s) of {@link UrlQuerySanitizer}", + method = "UrlQuerySanitizer", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test constructor(s) of {@link UrlQuerySanitizer}", + method = "UrlQuerySanitizer", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: parseUrl", + method = "parseUrl", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: parseQuery", + method = "parseQuery", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: parseEntry", + method = "parseEntry", + args = {String.class, String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getValue", + method = "getValue", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: addSanitizedEntry", + method = "addSanitizedEntry", + args = {String.class, String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: hasParameter", + method = "hasParameter", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getParameterSet", + method = "getParameterSet", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getParameterList", + method = "getParameterList", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: setUnregisteredParameterValueSanitizer", + method = "setUnregisteredParameterValueSanitizer", + args = {ValueSanitizer.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getUnregisteredParameterValueSanitizer", + method = "getUnregisteredParameterValueSanitizer", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getAllButNulAndAngleBracketsLegal", + method = "getAllButNulAndAngleBracketsLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getAllButNulLegal", + method = "getAllButNulLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getAllButWhitespaceLegal", + method = "getAllButWhitespaceLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getAllIllegal", + method = "getAllIllegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getAmpAndSpaceLegal", + method = "getAmpAndSpaceLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getAmpLegal", + method = "getAmpLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getSpaceLegal", + method = "getSpaceLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getUrlAndSpaceLegal", + method = "getUrlAndSpaceLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getUrlLegal", + method = "getUrlLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test mehtod: unescape", + method = "unescape", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test mehtod: isHexDigit", + method = "isHexDigit", + args = {char.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test mehtod: decodeHexDigit", + method = "decodeHexDigit", + args = {char.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: setAllowUnregisteredParamaters", + method = "setAllowUnregisteredParamaters", + args = {boolean.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getAllowUnregisteredParamaters", + method = "getAllowUnregisteredParamaters", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: registerParameter", + method = "registerParameter", + args = {String.class, ValueSanitizer.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: registerParameters", + method = "registerParameters", + args = {String[].class, ValueSanitizer.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getEffectiveValueSanitizer", + method = "getEffectiveValueSanitizer", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getValueSanitizer", + method = "getValueSanitizer", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: clear", + method = "clear", + args = {} + ) + }) + public void testUrlQuerySanitizer() { + MockUrlQuerySanitizer uqs = new MockUrlQuerySanitizer(); + assertFalse(uqs.getAllowUnregisteredParamaters()); + + final String query = "book=thinking in java&price=108"; + final String book = "book"; + final String bookName = "thinking in java"; + final String price = "price"; + final String bookPrice = "108"; + final String notExistPar = "notExistParameter"; + uqs.registerParameters(new String[]{book, price}, UrlQuerySanitizer.getSpaceLegal()); + uqs.parseQuery(query); + assertTrue(uqs.hasParameter(book)); + assertTrue(uqs.hasParameter(price)); + assertFalse(uqs.hasParameter(notExistPar)); + assertEquals(bookName, uqs.getValue(book)); + assertEquals(bookPrice, uqs.getValue(price)); + assertNull(uqs.getValue(notExistPar)); + uqs.clear(); + assertFalse(uqs.hasParameter(book)); + assertFalse(uqs.hasParameter(price)); + + uqs.parseEntry(book, bookName); + assertTrue(uqs.hasParameter(book)); + assertEquals(bookName, uqs.getValue(book)); + uqs.parseEntry(price, bookPrice); + assertTrue(uqs.hasParameter(price)); + assertEquals(bookPrice, uqs.getValue(price)); + assertFalse(uqs.hasParameter(notExistPar)); + assertNull(uqs.getValue(notExistPar)); + + uqs = new MockUrlQuerySanitizer(TEST_URL); + assertTrue(uqs.getAllowUnregisteredParamaters()); + + assertTrue(uqs.hasParameter(NAME)); + assertTrue(uqs.hasParameter(AGE)); + assertTrue(uqs.hasParameter(HEIGHT)); + assertFalse(uqs.hasParameter(notExistPar)); + + assertEquals(EXPECTED_UNDERLINE_NAME, uqs.getValue(NAME)); + assertEquals(EXPECTED_AGE, uqs.getValue(AGE)); + assertEquals(EXPECTED_HEIGHT, uqs.getValue(HEIGHT)); + assertNull(uqs.getValue(notExistPar)); + + final int ContainerLen = 3; + Set urlSet = uqs.getParameterSet(); + assertEquals(ContainerLen, urlSet.size()); + assertTrue(urlSet.contains(NAME)); + assertTrue(urlSet.contains(AGE)); + assertTrue(urlSet.contains(HEIGHT)); + assertFalse(urlSet.contains(notExistPar)); + + List urlList = uqs.getParameterList(); + assertEquals(ContainerLen, urlList.size()); + ParameterValuePair pvp = urlList.get(0); + assertEquals(NAME, pvp.mParameter); + assertEquals(EXPECTED_UNDERLINE_NAME, pvp.mValue); + pvp = urlList.get(1); + assertEquals(AGE, pvp.mParameter); + assertEquals(EXPECTED_AGE, pvp.mValue); + pvp = urlList.get(2); + assertEquals(HEIGHT, pvp.mParameter); + assertEquals(EXPECTED_HEIGHT, pvp.mValue); + + assertFalse(uqs.getPreferFirstRepeatedParameter()); + uqs.addSanitizedEntry(HEIGHT, EXPECTED_HEIGHT + 1); + assertEquals(ContainerLen, urlSet.size()); + assertEquals(ContainerLen + 1, urlList.size()); + assertEquals(EXPECTED_HEIGHT + 1, uqs.getValue(HEIGHT)); + + uqs.setPreferFirstRepeatedParameter(true); + assertTrue(uqs.getPreferFirstRepeatedParameter()); + uqs.addSanitizedEntry(HEIGHT, EXPECTED_HEIGHT); + assertEquals(ContainerLen, urlSet.size()); + assertEquals(ContainerLen + 2, urlList.size()); + assertEquals(EXPECTED_HEIGHT + 1, uqs.getValue(HEIGHT)); + + uqs.registerParameter(NAME, null); + assertNull(uqs.getValueSanitizer(NAME)); + assertNotNull(uqs.getEffectiveValueSanitizer(NAME)); + + uqs.setAllowUnregisteredParamaters(false); + assertFalse(uqs.getAllowUnregisteredParamaters()); + uqs.registerParameter(NAME, null); + assertNull(uqs.getEffectiveValueSanitizer(NAME)); + + ValueSanitizer vs = new IllegalCharacterValueSanitizer(ALL_OK); + uqs.registerParameter(NAME, vs); + uqs.parseUrl(TEST_URL); + assertEquals(EXPECTED_SPACE_NAME, uqs.getValue(NAME)); + assertNotSame(EXPECTED_AGE, uqs.getValue(AGE)); + + String[] register = {NAME, AGE}; + uqs.registerParameters(register, vs); + uqs.parseUrl(TEST_URL); + assertEquals(EXPECTED_SPACE_NAME, uqs.getValue(NAME)); + assertEquals(EXPECTED_AGE, uqs.getValue(AGE)); + assertNotSame(EXPECTED_HEIGHT, uqs.getValue(HEIGHT)); + + uqs.setUnregisteredParameterValueSanitizer(vs); + assertEquals(vs, uqs.getUnregisteredParameterValueSanitizer()); + + vs = UrlQuerySanitizer.getAllIllegal(); + assertEquals("Joe_User", vs.sanitize("Joe\0User")); + vs = UrlQuerySanitizer.getAllButNulLegal(); + assertEquals("Joe User", vs.sanitize("Joe\0User")); + vs = UrlQuerySanitizer.getAllButWhitespaceLegal(); + assertEquals("Joe_User", vs.sanitize("Joe User")); + vs = UrlQuerySanitizer.getAmpAndSpaceLegal(); + assertEquals("Joe User&", vs.sanitize("Joe User&")); + vs = UrlQuerySanitizer.getAmpLegal(); + assertEquals("Joe_User&", vs.sanitize("Joe User&")); + vs = UrlQuerySanitizer.getSpaceLegal(); + assertEquals("Joe User ", vs.sanitize("Joe User&")); + vs = UrlQuerySanitizer.getUrlAndSpaceLegal(); + assertEquals("Joe User&Smith%B5'\'", vs.sanitize("Joe User&Smith%B5'\'")); + vs = UrlQuerySanitizer.getUrlLegal(); + assertEquals("Joe_User&Smith%B5'\'", vs.sanitize("Joe User&Smith%B5'\'")); + + String escape = "Joe"; + assertEquals(escape, uqs.unescape(escape)); + String expectedPlus = "Joe User"; + String expectedPercentSignHex = "title=" + Character.toString((char)181); + String initialPlus = "Joe+User"; + String initialPercentSign = "title=%B5"; + assertEquals(expectedPlus, uqs.unescape(initialPlus)); + assertEquals(expectedPercentSignHex, uqs.unescape(initialPercentSign)); + + assertTrue(uqs.decodeHexDigit('0') >= 0); + assertTrue(uqs.decodeHexDigit('b') >= 0); + assertTrue(uqs.decodeHexDigit('F') >= 0); + assertTrue(uqs.decodeHexDigit('$') < 0); + + assertTrue(uqs.isHexDigit('0')); + assertTrue(uqs.isHexDigit('b')); + assertTrue(uqs.isHexDigit('F')); + assertFalse(uqs.isHexDigit('$')); + + uqs.clear(); + assertEquals(0, urlSet.size()); + assertEquals(0, urlList.size()); + } + + class MockUrlQuerySanitizer extends UrlQuerySanitizer { + public MockUrlQuerySanitizer() { + super(); + } + + public MockUrlQuerySanitizer(String url) { + super(url); + } + + @Override + protected void addSanitizedEntry(String parameter, String value) { + super.addSanitizedEntry(parameter, value); + } + + @Override + protected void clear() { + super.clear(); + } + + @Override + protected int decodeHexDigit(char c) { + return super.decodeHexDigit(c); + } + + @Override + protected boolean isHexDigit(char c) { + return super.isHexDigit(c); + } + + @Override + protected void parseEntry(String parameter, String value) { + super.parseEntry(parameter, value); + } + } +} diff --git a/tests/cts/net/src/android/net/cts/UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java b/tests/cts/net/src/android/net/cts/UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java new file mode 100644 index 0000000000..f85a5347e0 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2009 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.net.UrlQuerySanitizer; +import android.net.UrlQuerySanitizer.IllegalCharacterValueSanitizer; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; + +@TestTargetClass(UrlQuerySanitizer.IllegalCharacterValueSanitizer.class) +public class UrlQuerySanitizer_IllegalCharacterValueSanitizerTest extends AndroidTestCase { + static final int SPACE_OK = IllegalCharacterValueSanitizer.SPACE_OK; + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test constructor(s) of {@link IllegalCharacterValueSanitizer}", + method = "IllegalCharacterValueSanitizer", + args = {int.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: sanitize", + method = "sanitize", + args = {String.class} + ) + }) + public void testSanitize() { + IllegalCharacterValueSanitizer sanitizer = new IllegalCharacterValueSanitizer(SPACE_OK); + assertEquals("Joe User", sanitizer.sanitize("Joe Date: Thu, 9 Apr 2009 22:36:44 -0700 Subject: [PATCH 0007/1109] AI 145675: CTS: fixed the fail bug in android.net.cts.NetworkInfoTest Automated import of CL 145675 --- .../src/android/net/cts/NetworkInfoTest.java | 115 +++++++----------- 1 file changed, 46 insertions(+), 69 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java index 46da3ca74f..62a5f3fad9 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2009 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. @@ -16,72 +16,68 @@ package android.net.cts; -import dalvik.annotation.ToBeFixed; - import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; -import android.os.Parcel; import android.test.AndroidTestCase; -import dalvik.annotation.TestTargets; -import dalvik.annotation.TestStatus; -import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; @TestTargetClass(NetworkInfo.class) public class NetworkInfoTest extends AndroidTestCase { - ConnectivityManager mConnectivityManager; - @Override - protected void setUp() throws Exception { - super.setUp(); - mConnectivityManager = (ConnectivityManager) mContext - .getSystemService(Context.CONNECTIVITY_SERVICE); + public static final int TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE; + public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI; + public static final String MOBILE_TYPE_NAME = "MOBILE"; + public static final String WIFI_TYPE_NAME = "WIFI"; + + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test constructor(s) of NetworkInfo.", + method = "NetworkInfo", + args = {int.class} + ) + public void testConstructor() { + new NetworkInfo(ConnectivityManager.TYPE_MOBILE); } @TestTargets({ @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "isConnectedOrConnecting", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "setFailover", args = {boolean.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "isFailover", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "getType", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "getTypeName", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "setIsAvailable", args = {boolean.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "isAvailable", args = {} ), @@ -93,88 +89,69 @@ public class NetworkInfoTest extends AndroidTestCase { ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", - method = "describeContents", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "getDetailedState", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "getState", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "getReason", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "getExtraInfo", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "toString", args = {} ) }) public void testAccessNetworkInfoProperties() { - NetworkInfo[] ni = mConnectivityManager.getAllNetworkInfo(); + ConnectivityManager cm = (ConnectivityManager) getContext().getSystemService( + Context.CONNECTIVITY_SERVICE); + + NetworkInfo[] ni = cm.getAllNetworkInfo(); assertTrue(ni.length >= 2); - assertFalse(ni[ConnectivityManager.TYPE_MOBILE].isFailover()); - assertFalse(ni[ConnectivityManager.TYPE_WIFI].isFailover()); + + assertFalse(ni[TYPE_MOBILE].isFailover()); + assertFalse(ni[TYPE_WIFI].isFailover()); // test environment:connect as TYPE_MOBILE, and connect to internet. - assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getType(), - ConnectivityManager.TYPE_MOBILE); - assertEquals(ni[ConnectivityManager.TYPE_WIFI].getType(), ConnectivityManager.TYPE_WIFI); - assertEquals("MOBILE", ni[ConnectivityManager.TYPE_MOBILE].getTypeName()); - assertEquals("WIFI", ni[ConnectivityManager.TYPE_WIFI].getTypeName()); - assertTrue(ni[ConnectivityManager.TYPE_MOBILE].isConnectedOrConnecting()); - assertFalse(ni[ConnectivityManager.TYPE_WIFI].isConnectedOrConnecting()); - assertTrue(ni[ConnectivityManager.TYPE_MOBILE].isAvailable()); - assertFalse(ni[ConnectivityManager.TYPE_WIFI].isAvailable()); - assertTrue(ni[ConnectivityManager.TYPE_MOBILE].isConnected()); - assertFalse(ni[ConnectivityManager.TYPE_WIFI].isConnected()); + assertEquals(ni[TYPE_MOBILE].getType(), TYPE_MOBILE); + assertEquals(ni[TYPE_WIFI].getType(), TYPE_WIFI); - assertEquals(ni[ConnectivityManager.TYPE_MOBILE].describeContents(), 0); - assertEquals(ni[ConnectivityManager.TYPE_WIFI].describeContents(), 0); + assertEquals(MOBILE_TYPE_NAME, ni[TYPE_MOBILE].getTypeName()); + assertEquals(WIFI_TYPE_NAME, ni[TYPE_WIFI].getTypeName()); - assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getState(), State.CONNECTED); - assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getDetailedState(), - DetailedState.CONNECTED); + assertTrue(ni[TYPE_MOBILE].isConnectedOrConnecting()); + assertFalse(ni[TYPE_WIFI].isConnectedOrConnecting()); - assertNull(ni[ConnectivityManager.TYPE_MOBILE].getReason()); - assertNull(ni[ConnectivityManager.TYPE_WIFI].getReason()); - assertEquals("internet", ni[ConnectivityManager.TYPE_MOBILE].getExtraInfo()); - assertNull(ni[ConnectivityManager.TYPE_WIFI].getExtraInfo()); + assertTrue(ni[TYPE_MOBILE].isAvailable()); + assertFalse(ni[TYPE_WIFI].isAvailable()); - assertNotNull(ni[ConnectivityManager.TYPE_MOBILE].toString()); - assertNotNull(ni[ConnectivityManager.TYPE_WIFI].toString()); - } + assertTrue(ni[TYPE_MOBILE].isConnected()); + assertFalse(ni[TYPE_WIFI].isConnected()); - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test writeToParcel(Parcel dest, int flags).", - method = "writeToParcel", - args = {android.os.Parcel.class, java.lang.Integer.class} - ) - //@ToBeFixed(bug = "1703933", explanation = "Cannot test if the data was written correctly," - public void testWriteToParcel() { - NetworkInfo[] networkInfos = mConnectivityManager.getAllNetworkInfo(); - NetworkInfo mobileInfo = networkInfos[ConnectivityManager.TYPE_MOBILE]; - Parcel p = Parcel.obtain(); + assertEquals(State.CONNECTED, ni[TYPE_MOBILE].getState()); + assertEquals(State.UNKNOWN, ni[TYPE_WIFI].getState()); - mobileInfo.writeToParcel(p, 1); + assertEquals(DetailedState.CONNECTED, ni[TYPE_MOBILE].getDetailedState()); + assertEquals(DetailedState.IDLE, ni[TYPE_WIFI].getDetailedState()); + + assertNotNull(ni[TYPE_MOBILE].getReason()); + assertNull(ni[TYPE_WIFI].getReason()); + + assertNotNull(ni[TYPE_MOBILE].getExtraInfo()); + assertNull(ni[TYPE_WIFI].getExtraInfo()); + + assertNotNull(ni[TYPE_MOBILE].toString()); + assertNotNull(ni[TYPE_WIFI].toString()); } } From d33eb60d31bb15df9635a173b0c3ca3d87db0f21 Mon Sep 17 00:00:00 2001 From: Eric Shienbrood <> Date: Mon, 13 Apr 2009 10:41:53 -0700 Subject: [PATCH 0008/1109] AI 145881: Adding on to CL 145383, unhiding some additional methods and constants that ought to be exposed. Hid and deprecated the single-arg public constructor for NetworkInfo, and modified a CTS test that was testing it. Ran the android.net test package to make sure it still works. BUG=1779439 Automated import of CL 145881 --- tests/cts/net/src/android/net/cts/NetworkInfoTest.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java index 62a5f3fad9..ea1e047d6a 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java @@ -35,16 +35,6 @@ public class NetworkInfoTest extends AndroidTestCase { public static final String MOBILE_TYPE_NAME = "MOBILE"; public static final String WIFI_TYPE_NAME = "WIFI"; - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test constructor(s) of NetworkInfo.", - method = "NetworkInfo", - args = {int.class} - ) - public void testConstructor() { - new NetworkInfo(ConnectivityManager.TYPE_MOBILE); - } - @TestTargets({ @TestTargetNew( level = TestLevel.COMPLETE, From 82bd6d83a231b947d690ad9a97db82729417cbdd Mon Sep 17 00:00:00 2001 From: Scott Su <> Date: Mon, 13 Apr 2009 15:37:58 -0700 Subject: [PATCH 0009/1109] AI 145953: am: CL 145668 CTS: add test cases for net.UrlQuerySanitizer. Original author: sus Merged from: //branches/cupcake/... Automated import of CL 145953 --- .../net/cts/UrlQuerySanitizerTest.java | 416 ++++++++++++++++++ ...er_IllegalCharacterValueSanitizerTest.java | 48 ++ ...QuerySanitizer_ParameterValuePairTest.java | 43 ++ 3 files changed, 507 insertions(+) create mode 100644 tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java create mode 100644 tests/cts/net/src/android/net/cts/UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java create mode 100644 tests/cts/net/src/android/net/cts/UrlQuerySanitizer_ParameterValuePairTest.java diff --git a/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java b/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java new file mode 100644 index 0000000000..e9ae95c303 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java @@ -0,0 +1,416 @@ +/* + * Copyright (C) 2009 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 java.util.List; +import java.util.Set; +import android.net.UrlQuerySanitizer; +import android.net.UrlQuerySanitizer.IllegalCharacterValueSanitizer; +import android.net.UrlQuerySanitizer.ParameterValuePair; +import android.net.UrlQuerySanitizer.ValueSanitizer; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; + +@TestTargetClass(UrlQuerySanitizer.class) +public class UrlQuerySanitizerTest extends AndroidTestCase { + private static final int ALL_OK = IllegalCharacterValueSanitizer.ALL_OK; + + // URL for test. + private static final String TEST_URL = "http://example.com/?name=Joe+User&age=20&height=175"; + + // Default sanitizer's change when "+". + private static final String EXPECTED_UNDERLINE_NAME = "Joe_User"; + + // IllegalCharacterValueSanitizer sanitizer's change when "+". + private static final String EXPECTED_SPACE_NAME = "Joe User"; + private static final String EXPECTED_AGE = "20"; + private static final String EXPECTED_HEIGHT = "175"; + private static final String NAME = "name"; + private static final String AGE = "age"; + private static final String HEIGHT = "height"; + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test constructor(s) of {@link UrlQuerySanitizer}", + method = "UrlQuerySanitizer", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test constructor(s) of {@link UrlQuerySanitizer}", + method = "UrlQuerySanitizer", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: parseUrl", + method = "parseUrl", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: parseQuery", + method = "parseQuery", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: parseEntry", + method = "parseEntry", + args = {String.class, String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getValue", + method = "getValue", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: addSanitizedEntry", + method = "addSanitizedEntry", + args = {String.class, String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: hasParameter", + method = "hasParameter", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getParameterSet", + method = "getParameterSet", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getParameterList", + method = "getParameterList", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: setUnregisteredParameterValueSanitizer", + method = "setUnregisteredParameterValueSanitizer", + args = {ValueSanitizer.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getUnregisteredParameterValueSanitizer", + method = "getUnregisteredParameterValueSanitizer", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getAllButNulAndAngleBracketsLegal", + method = "getAllButNulAndAngleBracketsLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getAllButNulLegal", + method = "getAllButNulLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getAllButWhitespaceLegal", + method = "getAllButWhitespaceLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getAllIllegal", + method = "getAllIllegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getAmpAndSpaceLegal", + method = "getAmpAndSpaceLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getAmpLegal", + method = "getAmpLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getSpaceLegal", + method = "getSpaceLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getUrlAndSpaceLegal", + method = "getUrlAndSpaceLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getUrlLegal", + method = "getUrlLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test mehtod: unescape", + method = "unescape", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test mehtod: isHexDigit", + method = "isHexDigit", + args = {char.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test mehtod: decodeHexDigit", + method = "decodeHexDigit", + args = {char.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: setAllowUnregisteredParamaters", + method = "setAllowUnregisteredParamaters", + args = {boolean.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getAllowUnregisteredParamaters", + method = "getAllowUnregisteredParamaters", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: registerParameter", + method = "registerParameter", + args = {String.class, ValueSanitizer.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: registerParameters", + method = "registerParameters", + args = {String[].class, ValueSanitizer.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getEffectiveValueSanitizer", + method = "getEffectiveValueSanitizer", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getValueSanitizer", + method = "getValueSanitizer", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: clear", + method = "clear", + args = {} + ) + }) + public void testUrlQuerySanitizer() { + MockUrlQuerySanitizer uqs = new MockUrlQuerySanitizer(); + assertFalse(uqs.getAllowUnregisteredParamaters()); + + final String query = "book=thinking in java&price=108"; + final String book = "book"; + final String bookName = "thinking in java"; + final String price = "price"; + final String bookPrice = "108"; + final String notExistPar = "notExistParameter"; + uqs.registerParameters(new String[]{book, price}, UrlQuerySanitizer.getSpaceLegal()); + uqs.parseQuery(query); + assertTrue(uqs.hasParameter(book)); + assertTrue(uqs.hasParameter(price)); + assertFalse(uqs.hasParameter(notExistPar)); + assertEquals(bookName, uqs.getValue(book)); + assertEquals(bookPrice, uqs.getValue(price)); + assertNull(uqs.getValue(notExistPar)); + uqs.clear(); + assertFalse(uqs.hasParameter(book)); + assertFalse(uqs.hasParameter(price)); + + uqs.parseEntry(book, bookName); + assertTrue(uqs.hasParameter(book)); + assertEquals(bookName, uqs.getValue(book)); + uqs.parseEntry(price, bookPrice); + assertTrue(uqs.hasParameter(price)); + assertEquals(bookPrice, uqs.getValue(price)); + assertFalse(uqs.hasParameter(notExistPar)); + assertNull(uqs.getValue(notExistPar)); + + uqs = new MockUrlQuerySanitizer(TEST_URL); + assertTrue(uqs.getAllowUnregisteredParamaters()); + + assertTrue(uqs.hasParameter(NAME)); + assertTrue(uqs.hasParameter(AGE)); + assertTrue(uqs.hasParameter(HEIGHT)); + assertFalse(uqs.hasParameter(notExistPar)); + + assertEquals(EXPECTED_UNDERLINE_NAME, uqs.getValue(NAME)); + assertEquals(EXPECTED_AGE, uqs.getValue(AGE)); + assertEquals(EXPECTED_HEIGHT, uqs.getValue(HEIGHT)); + assertNull(uqs.getValue(notExistPar)); + + final int ContainerLen = 3; + Set urlSet = uqs.getParameterSet(); + assertEquals(ContainerLen, urlSet.size()); + assertTrue(urlSet.contains(NAME)); + assertTrue(urlSet.contains(AGE)); + assertTrue(urlSet.contains(HEIGHT)); + assertFalse(urlSet.contains(notExistPar)); + + List urlList = uqs.getParameterList(); + assertEquals(ContainerLen, urlList.size()); + ParameterValuePair pvp = urlList.get(0); + assertEquals(NAME, pvp.mParameter); + assertEquals(EXPECTED_UNDERLINE_NAME, pvp.mValue); + pvp = urlList.get(1); + assertEquals(AGE, pvp.mParameter); + assertEquals(EXPECTED_AGE, pvp.mValue); + pvp = urlList.get(2); + assertEquals(HEIGHT, pvp.mParameter); + assertEquals(EXPECTED_HEIGHT, pvp.mValue); + + assertFalse(uqs.getPreferFirstRepeatedParameter()); + uqs.addSanitizedEntry(HEIGHT, EXPECTED_HEIGHT + 1); + assertEquals(ContainerLen, urlSet.size()); + assertEquals(ContainerLen + 1, urlList.size()); + assertEquals(EXPECTED_HEIGHT + 1, uqs.getValue(HEIGHT)); + + uqs.setPreferFirstRepeatedParameter(true); + assertTrue(uqs.getPreferFirstRepeatedParameter()); + uqs.addSanitizedEntry(HEIGHT, EXPECTED_HEIGHT); + assertEquals(ContainerLen, urlSet.size()); + assertEquals(ContainerLen + 2, urlList.size()); + assertEquals(EXPECTED_HEIGHT + 1, uqs.getValue(HEIGHT)); + + uqs.registerParameter(NAME, null); + assertNull(uqs.getValueSanitizer(NAME)); + assertNotNull(uqs.getEffectiveValueSanitizer(NAME)); + + uqs.setAllowUnregisteredParamaters(false); + assertFalse(uqs.getAllowUnregisteredParamaters()); + uqs.registerParameter(NAME, null); + assertNull(uqs.getEffectiveValueSanitizer(NAME)); + + ValueSanitizer vs = new IllegalCharacterValueSanitizer(ALL_OK); + uqs.registerParameter(NAME, vs); + uqs.parseUrl(TEST_URL); + assertEquals(EXPECTED_SPACE_NAME, uqs.getValue(NAME)); + assertNotSame(EXPECTED_AGE, uqs.getValue(AGE)); + + String[] register = {NAME, AGE}; + uqs.registerParameters(register, vs); + uqs.parseUrl(TEST_URL); + assertEquals(EXPECTED_SPACE_NAME, uqs.getValue(NAME)); + assertEquals(EXPECTED_AGE, uqs.getValue(AGE)); + assertNotSame(EXPECTED_HEIGHT, uqs.getValue(HEIGHT)); + + uqs.setUnregisteredParameterValueSanitizer(vs); + assertEquals(vs, uqs.getUnregisteredParameterValueSanitizer()); + + vs = UrlQuerySanitizer.getAllIllegal(); + assertEquals("Joe_User", vs.sanitize("Joe\0User")); + vs = UrlQuerySanitizer.getAllButNulLegal(); + assertEquals("Joe User", vs.sanitize("Joe\0User")); + vs = UrlQuerySanitizer.getAllButWhitespaceLegal(); + assertEquals("Joe_User", vs.sanitize("Joe User")); + vs = UrlQuerySanitizer.getAmpAndSpaceLegal(); + assertEquals("Joe User&", vs.sanitize("Joe User&")); + vs = UrlQuerySanitizer.getAmpLegal(); + assertEquals("Joe_User&", vs.sanitize("Joe User&")); + vs = UrlQuerySanitizer.getSpaceLegal(); + assertEquals("Joe User ", vs.sanitize("Joe User&")); + vs = UrlQuerySanitizer.getUrlAndSpaceLegal(); + assertEquals("Joe User&Smith%B5'\'", vs.sanitize("Joe User&Smith%B5'\'")); + vs = UrlQuerySanitizer.getUrlLegal(); + assertEquals("Joe_User&Smith%B5'\'", vs.sanitize("Joe User&Smith%B5'\'")); + + String escape = "Joe"; + assertEquals(escape, uqs.unescape(escape)); + String expectedPlus = "Joe User"; + String expectedPercentSignHex = "title=" + Character.toString((char)181); + String initialPlus = "Joe+User"; + String initialPercentSign = "title=%B5"; + assertEquals(expectedPlus, uqs.unescape(initialPlus)); + assertEquals(expectedPercentSignHex, uqs.unescape(initialPercentSign)); + + assertTrue(uqs.decodeHexDigit('0') >= 0); + assertTrue(uqs.decodeHexDigit('b') >= 0); + assertTrue(uqs.decodeHexDigit('F') >= 0); + assertTrue(uqs.decodeHexDigit('$') < 0); + + assertTrue(uqs.isHexDigit('0')); + assertTrue(uqs.isHexDigit('b')); + assertTrue(uqs.isHexDigit('F')); + assertFalse(uqs.isHexDigit('$')); + + uqs.clear(); + assertEquals(0, urlSet.size()); + assertEquals(0, urlList.size()); + } + + class MockUrlQuerySanitizer extends UrlQuerySanitizer { + public MockUrlQuerySanitizer() { + super(); + } + + public MockUrlQuerySanitizer(String url) { + super(url); + } + + @Override + protected void addSanitizedEntry(String parameter, String value) { + super.addSanitizedEntry(parameter, value); + } + + @Override + protected void clear() { + super.clear(); + } + + @Override + protected int decodeHexDigit(char c) { + return super.decodeHexDigit(c); + } + + @Override + protected boolean isHexDigit(char c) { + return super.isHexDigit(c); + } + + @Override + protected void parseEntry(String parameter, String value) { + super.parseEntry(parameter, value); + } + } +} diff --git a/tests/cts/net/src/android/net/cts/UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java b/tests/cts/net/src/android/net/cts/UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java new file mode 100644 index 0000000000..f85a5347e0 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2009 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.net.UrlQuerySanitizer; +import android.net.UrlQuerySanitizer.IllegalCharacterValueSanitizer; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; + +@TestTargetClass(UrlQuerySanitizer.IllegalCharacterValueSanitizer.class) +public class UrlQuerySanitizer_IllegalCharacterValueSanitizerTest extends AndroidTestCase { + static final int SPACE_OK = IllegalCharacterValueSanitizer.SPACE_OK; + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test constructor(s) of {@link IllegalCharacterValueSanitizer}", + method = "IllegalCharacterValueSanitizer", + args = {int.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: sanitize", + method = "sanitize", + args = {String.class} + ) + }) + public void testSanitize() { + IllegalCharacterValueSanitizer sanitizer = new IllegalCharacterValueSanitizer(SPACE_OK); + assertEquals("Joe User", sanitizer.sanitize("Joe Date: Mon, 13 Apr 2009 15:47:21 -0700 Subject: [PATCH 0010/1109] AI 145956: am: CL 145675 CTS: fixed the fail bug in android.net.cts.NetworkInfoTest Original author: sus Merged from: //branches/cupcake/... Automated import of CL 145956 --- .../src/android/net/cts/NetworkInfoTest.java | 115 +++++++----------- 1 file changed, 46 insertions(+), 69 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java index 46da3ca74f..62a5f3fad9 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2009 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. @@ -16,72 +16,68 @@ package android.net.cts; -import dalvik.annotation.ToBeFixed; - import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; -import android.os.Parcel; import android.test.AndroidTestCase; -import dalvik.annotation.TestTargets; -import dalvik.annotation.TestStatus; -import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; @TestTargetClass(NetworkInfo.class) public class NetworkInfoTest extends AndroidTestCase { - ConnectivityManager mConnectivityManager; - @Override - protected void setUp() throws Exception { - super.setUp(); - mConnectivityManager = (ConnectivityManager) mContext - .getSystemService(Context.CONNECTIVITY_SERVICE); + public static final int TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE; + public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI; + public static final String MOBILE_TYPE_NAME = "MOBILE"; + public static final String WIFI_TYPE_NAME = "WIFI"; + + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test constructor(s) of NetworkInfo.", + method = "NetworkInfo", + args = {int.class} + ) + public void testConstructor() { + new NetworkInfo(ConnectivityManager.TYPE_MOBILE); } @TestTargets({ @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "isConnectedOrConnecting", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "setFailover", args = {boolean.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "isFailover", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "getType", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "getTypeName", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "setIsAvailable", args = {boolean.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "isAvailable", args = {} ), @@ -93,88 +89,69 @@ public class NetworkInfoTest extends AndroidTestCase { ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", - method = "describeContents", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "getDetailedState", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "getState", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "getReason", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "getExtraInfo", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "toString", args = {} ) }) public void testAccessNetworkInfoProperties() { - NetworkInfo[] ni = mConnectivityManager.getAllNetworkInfo(); + ConnectivityManager cm = (ConnectivityManager) getContext().getSystemService( + Context.CONNECTIVITY_SERVICE); + + NetworkInfo[] ni = cm.getAllNetworkInfo(); assertTrue(ni.length >= 2); - assertFalse(ni[ConnectivityManager.TYPE_MOBILE].isFailover()); - assertFalse(ni[ConnectivityManager.TYPE_WIFI].isFailover()); + + assertFalse(ni[TYPE_MOBILE].isFailover()); + assertFalse(ni[TYPE_WIFI].isFailover()); // test environment:connect as TYPE_MOBILE, and connect to internet. - assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getType(), - ConnectivityManager.TYPE_MOBILE); - assertEquals(ni[ConnectivityManager.TYPE_WIFI].getType(), ConnectivityManager.TYPE_WIFI); - assertEquals("MOBILE", ni[ConnectivityManager.TYPE_MOBILE].getTypeName()); - assertEquals("WIFI", ni[ConnectivityManager.TYPE_WIFI].getTypeName()); - assertTrue(ni[ConnectivityManager.TYPE_MOBILE].isConnectedOrConnecting()); - assertFalse(ni[ConnectivityManager.TYPE_WIFI].isConnectedOrConnecting()); - assertTrue(ni[ConnectivityManager.TYPE_MOBILE].isAvailable()); - assertFalse(ni[ConnectivityManager.TYPE_WIFI].isAvailable()); - assertTrue(ni[ConnectivityManager.TYPE_MOBILE].isConnected()); - assertFalse(ni[ConnectivityManager.TYPE_WIFI].isConnected()); + assertEquals(ni[TYPE_MOBILE].getType(), TYPE_MOBILE); + assertEquals(ni[TYPE_WIFI].getType(), TYPE_WIFI); - assertEquals(ni[ConnectivityManager.TYPE_MOBILE].describeContents(), 0); - assertEquals(ni[ConnectivityManager.TYPE_WIFI].describeContents(), 0); + assertEquals(MOBILE_TYPE_NAME, ni[TYPE_MOBILE].getTypeName()); + assertEquals(WIFI_TYPE_NAME, ni[TYPE_WIFI].getTypeName()); - assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getState(), State.CONNECTED); - assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getDetailedState(), - DetailedState.CONNECTED); + assertTrue(ni[TYPE_MOBILE].isConnectedOrConnecting()); + assertFalse(ni[TYPE_WIFI].isConnectedOrConnecting()); - assertNull(ni[ConnectivityManager.TYPE_MOBILE].getReason()); - assertNull(ni[ConnectivityManager.TYPE_WIFI].getReason()); - assertEquals("internet", ni[ConnectivityManager.TYPE_MOBILE].getExtraInfo()); - assertNull(ni[ConnectivityManager.TYPE_WIFI].getExtraInfo()); + assertTrue(ni[TYPE_MOBILE].isAvailable()); + assertFalse(ni[TYPE_WIFI].isAvailable()); - assertNotNull(ni[ConnectivityManager.TYPE_MOBILE].toString()); - assertNotNull(ni[ConnectivityManager.TYPE_WIFI].toString()); - } + assertTrue(ni[TYPE_MOBILE].isConnected()); + assertFalse(ni[TYPE_WIFI].isConnected()); - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test writeToParcel(Parcel dest, int flags).", - method = "writeToParcel", - args = {android.os.Parcel.class, java.lang.Integer.class} - ) - //@ToBeFixed(bug = "1703933", explanation = "Cannot test if the data was written correctly," - public void testWriteToParcel() { - NetworkInfo[] networkInfos = mConnectivityManager.getAllNetworkInfo(); - NetworkInfo mobileInfo = networkInfos[ConnectivityManager.TYPE_MOBILE]; - Parcel p = Parcel.obtain(); + assertEquals(State.CONNECTED, ni[TYPE_MOBILE].getState()); + assertEquals(State.UNKNOWN, ni[TYPE_WIFI].getState()); - mobileInfo.writeToParcel(p, 1); + assertEquals(DetailedState.CONNECTED, ni[TYPE_MOBILE].getDetailedState()); + assertEquals(DetailedState.IDLE, ni[TYPE_WIFI].getDetailedState()); + + assertNotNull(ni[TYPE_MOBILE].getReason()); + assertNull(ni[TYPE_WIFI].getReason()); + + assertNotNull(ni[TYPE_MOBILE].getExtraInfo()); + assertNull(ni[TYPE_WIFI].getExtraInfo()); + + assertNotNull(ni[TYPE_MOBILE].toString()); + assertNotNull(ni[TYPE_WIFI].toString()); } } From 537a83c57a505b23dfc5a6b6635b8fc9ad891cb8 Mon Sep 17 00:00:00 2001 From: Eric Shienbrood <> Date: Mon, 13 Apr 2009 18:12:46 -0700 Subject: [PATCH 0011/1109] AI 145980: am: CL 145881 Adding on to CL 145383, unhiding some additional methods and constants that ought to be exposed. Hid and deprecated the single-arg public constructor for NetworkInfo, and modified a CTS test that was testing it. Ran the android.net test package to make sure it still works. Original author: ers Merged from: //branches/cupcake/... Automated import of CL 145980 --- tests/cts/net/src/android/net/cts/NetworkInfoTest.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java index 62a5f3fad9..ea1e047d6a 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java @@ -35,16 +35,6 @@ public class NetworkInfoTest extends AndroidTestCase { public static final String MOBILE_TYPE_NAME = "MOBILE"; public static final String WIFI_TYPE_NAME = "WIFI"; - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test constructor(s) of NetworkInfo.", - method = "NetworkInfo", - args = {int.class} - ) - public void testConstructor() { - new NetworkInfo(ConnectivityManager.TYPE_MOBILE); - } - @TestTargets({ @TestTargetNew( level = TestLevel.COMPLETE, From 316ee5f68ba3bbd3df43b67848219e45df4e83e1 Mon Sep 17 00:00:00 2001 From: Scott Su <> Date: Mon, 13 Apr 2009 23:23:32 -0700 Subject: [PATCH 0012/1109] AI 146071: CTS: Clean up test annotations BUG=1654276 Automated import of CL 146071 --- .../net/cts/LocalServerSocketTest.java | 1 - .../cts/NetworkInfo_DetailedStateTest.java | 1 - .../net/cts/NetworkInfo_StateTest.java | 1 - .../net/src/android/net/cts/ProxyTest.java | 57 ++++++++----------- 4 files changed, 25 insertions(+), 35 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java index a6511e8521..07f29c6783 100644 --- a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java @@ -26,7 +26,6 @@ import android.net.LocalSocketAddress; import android.os.ParcelFileDescriptor; import android.test.AndroidTestCase; import dalvik.annotation.TestTargets; -import dalvik.annotation.TestStatus; import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java index 002adfecaf..0e05b28119 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java @@ -19,7 +19,6 @@ package android.net.cts; import android.net.NetworkInfo.DetailedState; import android.test.AndroidTestCase; import dalvik.annotation.TestTargets; -import dalvik.annotation.TestStatus; import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java index 2f58784708..249df4b588 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java @@ -18,7 +18,6 @@ package android.net.cts; import android.test.AndroidTestCase; import dalvik.annotation.TestTargets; -import dalvik.annotation.TestStatus; import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; diff --git a/tests/cts/net/src/android/net/cts/ProxyTest.java b/tests/cts/net/src/android/net/cts/ProxyTest.java index d9f7c1a942..9345ac2485 100644 --- a/tests/cts/net/src/android/net/cts/ProxyTest.java +++ b/tests/cts/net/src/android/net/cts/ProxyTest.java @@ -20,9 +20,9 @@ import android.content.Context; import android.net.Proxy; import android.provider.Settings; import android.test.AndroidTestCase; -import dalvik.annotation.TestInfo; -import dalvik.annotation.TestStatus; -import dalvik.annotation.TestTarget; +import dalvik.annotation.TestTargets; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestTargetClass; @TestTargetClass(Proxy.class) @@ -33,15 +33,11 @@ public class ProxyTest extends AndroidTestCase { } - @TestInfo( - status = TestStatus.TBR, - notes = "Test constructor(s) of Proxy.", - targets = { - @TestTarget( - methodName = "Proxy", - methodArgs = {} - ) - }) + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "Proxy", + args = {} + ) public void testConstructor() { try { @@ -51,29 +47,26 @@ public class ProxyTest extends AndroidTestCase { } } - @TestInfo( - status = TestStatus.TBR, - notes = "Test getDefaultPort().", - targets = { - @TestTarget( - methodName = "getDefaultPort", - methodArgs = {} + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getDefaultPort", + args = {} ), - @TestTarget( - methodName = "getDefaultHost", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getDefaultHost", + args = {} ), - @TestTarget( - methodName = "getHost", - methodArgs = {Context.class} + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getHost", + args = {Context.class} ), - @TestTarget( - methodName = "getHost", - methodArgs = {Context.class} - ), - @TestTarget( - methodName = "getPort", - methodArgs = {Context.class} + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getPort", + args = {Context.class} ) }) public void testAccessProperties() { From 3ae3101a2aeded72922213669e25345658c3d2b4 Mon Sep 17 00:00:00 2001 From: Scott Su <> Date: Mon, 13 Apr 2009 23:24:06 -0700 Subject: [PATCH 0013/1109] AI 146072: am: CL 146071 CTS: Clean up test annotations Original author: sus Merged from: //branches/cupcake/... Automated import of CL 146072 --- .../net/cts/LocalServerSocketTest.java | 1 - .../cts/NetworkInfo_DetailedStateTest.java | 1 - .../net/cts/NetworkInfo_StateTest.java | 1 - .../net/src/android/net/cts/ProxyTest.java | 57 ++++++++----------- 4 files changed, 25 insertions(+), 35 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java index a6511e8521..07f29c6783 100644 --- a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java @@ -26,7 +26,6 @@ import android.net.LocalSocketAddress; import android.os.ParcelFileDescriptor; import android.test.AndroidTestCase; import dalvik.annotation.TestTargets; -import dalvik.annotation.TestStatus; import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java index 002adfecaf..0e05b28119 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java @@ -19,7 +19,6 @@ package android.net.cts; import android.net.NetworkInfo.DetailedState; import android.test.AndroidTestCase; import dalvik.annotation.TestTargets; -import dalvik.annotation.TestStatus; import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java index 2f58784708..249df4b588 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java @@ -18,7 +18,6 @@ package android.net.cts; import android.test.AndroidTestCase; import dalvik.annotation.TestTargets; -import dalvik.annotation.TestStatus; import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; diff --git a/tests/cts/net/src/android/net/cts/ProxyTest.java b/tests/cts/net/src/android/net/cts/ProxyTest.java index d9f7c1a942..9345ac2485 100644 --- a/tests/cts/net/src/android/net/cts/ProxyTest.java +++ b/tests/cts/net/src/android/net/cts/ProxyTest.java @@ -20,9 +20,9 @@ import android.content.Context; import android.net.Proxy; import android.provider.Settings; import android.test.AndroidTestCase; -import dalvik.annotation.TestInfo; -import dalvik.annotation.TestStatus; -import dalvik.annotation.TestTarget; +import dalvik.annotation.TestTargets; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestTargetClass; @TestTargetClass(Proxy.class) @@ -33,15 +33,11 @@ public class ProxyTest extends AndroidTestCase { } - @TestInfo( - status = TestStatus.TBR, - notes = "Test constructor(s) of Proxy.", - targets = { - @TestTarget( - methodName = "Proxy", - methodArgs = {} - ) - }) + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "Proxy", + args = {} + ) public void testConstructor() { try { @@ -51,29 +47,26 @@ public class ProxyTest extends AndroidTestCase { } } - @TestInfo( - status = TestStatus.TBR, - notes = "Test getDefaultPort().", - targets = { - @TestTarget( - methodName = "getDefaultPort", - methodArgs = {} + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getDefaultPort", + args = {} ), - @TestTarget( - methodName = "getDefaultHost", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getDefaultHost", + args = {} ), - @TestTarget( - methodName = "getHost", - methodArgs = {Context.class} + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getHost", + args = {Context.class} ), - @TestTarget( - methodName = "getHost", - methodArgs = {Context.class} - ), - @TestTarget( - methodName = "getPort", - methodArgs = {Context.class} + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getPort", + args = {Context.class} ) }) public void testAccessProperties() { From 871df54abaca97ff4bc26d70449a9621bcfae2b6 Mon Sep 17 00:00:00 2001 From: Scott Su <> Date: Tue, 14 Apr 2009 12:15:18 -0700 Subject: [PATCH 0014/1109] AI 146168: am: CL 145953 am: CL 145668 CTS: add test cases for net.UrlQuerySanitizer. Original author: sus Merged from: //branches/cupcake/... Original author: android-build Automated import of CL 146168 --- .../net/cts/UrlQuerySanitizerTest.java | 416 ++++++++++++++++++ ...er_IllegalCharacterValueSanitizerTest.java | 48 ++ ...QuerySanitizer_ParameterValuePairTest.java | 43 ++ 3 files changed, 507 insertions(+) create mode 100644 tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java create mode 100644 tests/cts/net/src/android/net/cts/UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java create mode 100644 tests/cts/net/src/android/net/cts/UrlQuerySanitizer_ParameterValuePairTest.java diff --git a/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java b/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java new file mode 100644 index 0000000000..e9ae95c303 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java @@ -0,0 +1,416 @@ +/* + * Copyright (C) 2009 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 java.util.List; +import java.util.Set; +import android.net.UrlQuerySanitizer; +import android.net.UrlQuerySanitizer.IllegalCharacterValueSanitizer; +import android.net.UrlQuerySanitizer.ParameterValuePair; +import android.net.UrlQuerySanitizer.ValueSanitizer; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; + +@TestTargetClass(UrlQuerySanitizer.class) +public class UrlQuerySanitizerTest extends AndroidTestCase { + private static final int ALL_OK = IllegalCharacterValueSanitizer.ALL_OK; + + // URL for test. + private static final String TEST_URL = "http://example.com/?name=Joe+User&age=20&height=175"; + + // Default sanitizer's change when "+". + private static final String EXPECTED_UNDERLINE_NAME = "Joe_User"; + + // IllegalCharacterValueSanitizer sanitizer's change when "+". + private static final String EXPECTED_SPACE_NAME = "Joe User"; + private static final String EXPECTED_AGE = "20"; + private static final String EXPECTED_HEIGHT = "175"; + private static final String NAME = "name"; + private static final String AGE = "age"; + private static final String HEIGHT = "height"; + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test constructor(s) of {@link UrlQuerySanitizer}", + method = "UrlQuerySanitizer", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test constructor(s) of {@link UrlQuerySanitizer}", + method = "UrlQuerySanitizer", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: parseUrl", + method = "parseUrl", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: parseQuery", + method = "parseQuery", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: parseEntry", + method = "parseEntry", + args = {String.class, String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getValue", + method = "getValue", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: addSanitizedEntry", + method = "addSanitizedEntry", + args = {String.class, String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: hasParameter", + method = "hasParameter", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getParameterSet", + method = "getParameterSet", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getParameterList", + method = "getParameterList", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: setUnregisteredParameterValueSanitizer", + method = "setUnregisteredParameterValueSanitizer", + args = {ValueSanitizer.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getUnregisteredParameterValueSanitizer", + method = "getUnregisteredParameterValueSanitizer", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getAllButNulAndAngleBracketsLegal", + method = "getAllButNulAndAngleBracketsLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getAllButNulLegal", + method = "getAllButNulLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getAllButWhitespaceLegal", + method = "getAllButWhitespaceLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getAllIllegal", + method = "getAllIllegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getAmpAndSpaceLegal", + method = "getAmpAndSpaceLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getAmpLegal", + method = "getAmpLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getSpaceLegal", + method = "getSpaceLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getUrlAndSpaceLegal", + method = "getUrlAndSpaceLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getUrlLegal", + method = "getUrlLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test mehtod: unescape", + method = "unescape", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test mehtod: isHexDigit", + method = "isHexDigit", + args = {char.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test mehtod: decodeHexDigit", + method = "decodeHexDigit", + args = {char.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: setAllowUnregisteredParamaters", + method = "setAllowUnregisteredParamaters", + args = {boolean.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getAllowUnregisteredParamaters", + method = "getAllowUnregisteredParamaters", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: registerParameter", + method = "registerParameter", + args = {String.class, ValueSanitizer.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: registerParameters", + method = "registerParameters", + args = {String[].class, ValueSanitizer.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getEffectiveValueSanitizer", + method = "getEffectiveValueSanitizer", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: getValueSanitizer", + method = "getValueSanitizer", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: clear", + method = "clear", + args = {} + ) + }) + public void testUrlQuerySanitizer() { + MockUrlQuerySanitizer uqs = new MockUrlQuerySanitizer(); + assertFalse(uqs.getAllowUnregisteredParamaters()); + + final String query = "book=thinking in java&price=108"; + final String book = "book"; + final String bookName = "thinking in java"; + final String price = "price"; + final String bookPrice = "108"; + final String notExistPar = "notExistParameter"; + uqs.registerParameters(new String[]{book, price}, UrlQuerySanitizer.getSpaceLegal()); + uqs.parseQuery(query); + assertTrue(uqs.hasParameter(book)); + assertTrue(uqs.hasParameter(price)); + assertFalse(uqs.hasParameter(notExistPar)); + assertEquals(bookName, uqs.getValue(book)); + assertEquals(bookPrice, uqs.getValue(price)); + assertNull(uqs.getValue(notExistPar)); + uqs.clear(); + assertFalse(uqs.hasParameter(book)); + assertFalse(uqs.hasParameter(price)); + + uqs.parseEntry(book, bookName); + assertTrue(uqs.hasParameter(book)); + assertEquals(bookName, uqs.getValue(book)); + uqs.parseEntry(price, bookPrice); + assertTrue(uqs.hasParameter(price)); + assertEquals(bookPrice, uqs.getValue(price)); + assertFalse(uqs.hasParameter(notExistPar)); + assertNull(uqs.getValue(notExistPar)); + + uqs = new MockUrlQuerySanitizer(TEST_URL); + assertTrue(uqs.getAllowUnregisteredParamaters()); + + assertTrue(uqs.hasParameter(NAME)); + assertTrue(uqs.hasParameter(AGE)); + assertTrue(uqs.hasParameter(HEIGHT)); + assertFalse(uqs.hasParameter(notExistPar)); + + assertEquals(EXPECTED_UNDERLINE_NAME, uqs.getValue(NAME)); + assertEquals(EXPECTED_AGE, uqs.getValue(AGE)); + assertEquals(EXPECTED_HEIGHT, uqs.getValue(HEIGHT)); + assertNull(uqs.getValue(notExistPar)); + + final int ContainerLen = 3; + Set urlSet = uqs.getParameterSet(); + assertEquals(ContainerLen, urlSet.size()); + assertTrue(urlSet.contains(NAME)); + assertTrue(urlSet.contains(AGE)); + assertTrue(urlSet.contains(HEIGHT)); + assertFalse(urlSet.contains(notExistPar)); + + List urlList = uqs.getParameterList(); + assertEquals(ContainerLen, urlList.size()); + ParameterValuePair pvp = urlList.get(0); + assertEquals(NAME, pvp.mParameter); + assertEquals(EXPECTED_UNDERLINE_NAME, pvp.mValue); + pvp = urlList.get(1); + assertEquals(AGE, pvp.mParameter); + assertEquals(EXPECTED_AGE, pvp.mValue); + pvp = urlList.get(2); + assertEquals(HEIGHT, pvp.mParameter); + assertEquals(EXPECTED_HEIGHT, pvp.mValue); + + assertFalse(uqs.getPreferFirstRepeatedParameter()); + uqs.addSanitizedEntry(HEIGHT, EXPECTED_HEIGHT + 1); + assertEquals(ContainerLen, urlSet.size()); + assertEquals(ContainerLen + 1, urlList.size()); + assertEquals(EXPECTED_HEIGHT + 1, uqs.getValue(HEIGHT)); + + uqs.setPreferFirstRepeatedParameter(true); + assertTrue(uqs.getPreferFirstRepeatedParameter()); + uqs.addSanitizedEntry(HEIGHT, EXPECTED_HEIGHT); + assertEquals(ContainerLen, urlSet.size()); + assertEquals(ContainerLen + 2, urlList.size()); + assertEquals(EXPECTED_HEIGHT + 1, uqs.getValue(HEIGHT)); + + uqs.registerParameter(NAME, null); + assertNull(uqs.getValueSanitizer(NAME)); + assertNotNull(uqs.getEffectiveValueSanitizer(NAME)); + + uqs.setAllowUnregisteredParamaters(false); + assertFalse(uqs.getAllowUnregisteredParamaters()); + uqs.registerParameter(NAME, null); + assertNull(uqs.getEffectiveValueSanitizer(NAME)); + + ValueSanitizer vs = new IllegalCharacterValueSanitizer(ALL_OK); + uqs.registerParameter(NAME, vs); + uqs.parseUrl(TEST_URL); + assertEquals(EXPECTED_SPACE_NAME, uqs.getValue(NAME)); + assertNotSame(EXPECTED_AGE, uqs.getValue(AGE)); + + String[] register = {NAME, AGE}; + uqs.registerParameters(register, vs); + uqs.parseUrl(TEST_URL); + assertEquals(EXPECTED_SPACE_NAME, uqs.getValue(NAME)); + assertEquals(EXPECTED_AGE, uqs.getValue(AGE)); + assertNotSame(EXPECTED_HEIGHT, uqs.getValue(HEIGHT)); + + uqs.setUnregisteredParameterValueSanitizer(vs); + assertEquals(vs, uqs.getUnregisteredParameterValueSanitizer()); + + vs = UrlQuerySanitizer.getAllIllegal(); + assertEquals("Joe_User", vs.sanitize("Joe\0User")); + vs = UrlQuerySanitizer.getAllButNulLegal(); + assertEquals("Joe User", vs.sanitize("Joe\0User")); + vs = UrlQuerySanitizer.getAllButWhitespaceLegal(); + assertEquals("Joe_User", vs.sanitize("Joe User")); + vs = UrlQuerySanitizer.getAmpAndSpaceLegal(); + assertEquals("Joe User&", vs.sanitize("Joe User&")); + vs = UrlQuerySanitizer.getAmpLegal(); + assertEquals("Joe_User&", vs.sanitize("Joe User&")); + vs = UrlQuerySanitizer.getSpaceLegal(); + assertEquals("Joe User ", vs.sanitize("Joe User&")); + vs = UrlQuerySanitizer.getUrlAndSpaceLegal(); + assertEquals("Joe User&Smith%B5'\'", vs.sanitize("Joe User&Smith%B5'\'")); + vs = UrlQuerySanitizer.getUrlLegal(); + assertEquals("Joe_User&Smith%B5'\'", vs.sanitize("Joe User&Smith%B5'\'")); + + String escape = "Joe"; + assertEquals(escape, uqs.unescape(escape)); + String expectedPlus = "Joe User"; + String expectedPercentSignHex = "title=" + Character.toString((char)181); + String initialPlus = "Joe+User"; + String initialPercentSign = "title=%B5"; + assertEquals(expectedPlus, uqs.unescape(initialPlus)); + assertEquals(expectedPercentSignHex, uqs.unescape(initialPercentSign)); + + assertTrue(uqs.decodeHexDigit('0') >= 0); + assertTrue(uqs.decodeHexDigit('b') >= 0); + assertTrue(uqs.decodeHexDigit('F') >= 0); + assertTrue(uqs.decodeHexDigit('$') < 0); + + assertTrue(uqs.isHexDigit('0')); + assertTrue(uqs.isHexDigit('b')); + assertTrue(uqs.isHexDigit('F')); + assertFalse(uqs.isHexDigit('$')); + + uqs.clear(); + assertEquals(0, urlSet.size()); + assertEquals(0, urlList.size()); + } + + class MockUrlQuerySanitizer extends UrlQuerySanitizer { + public MockUrlQuerySanitizer() { + super(); + } + + public MockUrlQuerySanitizer(String url) { + super(url); + } + + @Override + protected void addSanitizedEntry(String parameter, String value) { + super.addSanitizedEntry(parameter, value); + } + + @Override + protected void clear() { + super.clear(); + } + + @Override + protected int decodeHexDigit(char c) { + return super.decodeHexDigit(c); + } + + @Override + protected boolean isHexDigit(char c) { + return super.isHexDigit(c); + } + + @Override + protected void parseEntry(String parameter, String value) { + super.parseEntry(parameter, value); + } + } +} diff --git a/tests/cts/net/src/android/net/cts/UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java b/tests/cts/net/src/android/net/cts/UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java new file mode 100644 index 0000000000..f85a5347e0 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2009 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.net.UrlQuerySanitizer; +import android.net.UrlQuerySanitizer.IllegalCharacterValueSanitizer; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; + +@TestTargetClass(UrlQuerySanitizer.IllegalCharacterValueSanitizer.class) +public class UrlQuerySanitizer_IllegalCharacterValueSanitizerTest extends AndroidTestCase { + static final int SPACE_OK = IllegalCharacterValueSanitizer.SPACE_OK; + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test constructor(s) of {@link IllegalCharacterValueSanitizer}", + method = "IllegalCharacterValueSanitizer", + args = {int.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: sanitize", + method = "sanitize", + args = {String.class} + ) + }) + public void testSanitize() { + IllegalCharacterValueSanitizer sanitizer = new IllegalCharacterValueSanitizer(SPACE_OK); + assertEquals("Joe User", sanitizer.sanitize("Joe Date: Tue, 14 Apr 2009 12:23:31 -0700 Subject: [PATCH 0015/1109] AI 146171: am: CL 145956 am: CL 145675 CTS: fixed the fail bug in android.net.cts.NetworkInfoTest Original author: sus Merged from: //branches/cupcake/... Original author: android-build Automated import of CL 146171 --- .../src/android/net/cts/NetworkInfoTest.java | 115 +++++++----------- 1 file changed, 46 insertions(+), 69 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java index 46da3ca74f..62a5f3fad9 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2009 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. @@ -16,72 +16,68 @@ package android.net.cts; -import dalvik.annotation.ToBeFixed; - import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; -import android.os.Parcel; import android.test.AndroidTestCase; -import dalvik.annotation.TestTargets; -import dalvik.annotation.TestStatus; -import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; @TestTargetClass(NetworkInfo.class) public class NetworkInfoTest extends AndroidTestCase { - ConnectivityManager mConnectivityManager; - @Override - protected void setUp() throws Exception { - super.setUp(); - mConnectivityManager = (ConnectivityManager) mContext - .getSystemService(Context.CONNECTIVITY_SERVICE); + public static final int TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE; + public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI; + public static final String MOBILE_TYPE_NAME = "MOBILE"; + public static final String WIFI_TYPE_NAME = "WIFI"; + + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test constructor(s) of NetworkInfo.", + method = "NetworkInfo", + args = {int.class} + ) + public void testConstructor() { + new NetworkInfo(ConnectivityManager.TYPE_MOBILE); } @TestTargets({ @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "isConnectedOrConnecting", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "setFailover", args = {boolean.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "isFailover", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "getType", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "getTypeName", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "setIsAvailable", args = {boolean.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "isAvailable", args = {} ), @@ -93,88 +89,69 @@ public class NetworkInfoTest extends AndroidTestCase { ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", - method = "describeContents", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "getDetailedState", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "getState", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "getReason", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "getExtraInfo", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "toString", args = {} ) }) public void testAccessNetworkInfoProperties() { - NetworkInfo[] ni = mConnectivityManager.getAllNetworkInfo(); + ConnectivityManager cm = (ConnectivityManager) getContext().getSystemService( + Context.CONNECTIVITY_SERVICE); + + NetworkInfo[] ni = cm.getAllNetworkInfo(); assertTrue(ni.length >= 2); - assertFalse(ni[ConnectivityManager.TYPE_MOBILE].isFailover()); - assertFalse(ni[ConnectivityManager.TYPE_WIFI].isFailover()); + + assertFalse(ni[TYPE_MOBILE].isFailover()); + assertFalse(ni[TYPE_WIFI].isFailover()); // test environment:connect as TYPE_MOBILE, and connect to internet. - assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getType(), - ConnectivityManager.TYPE_MOBILE); - assertEquals(ni[ConnectivityManager.TYPE_WIFI].getType(), ConnectivityManager.TYPE_WIFI); - assertEquals("MOBILE", ni[ConnectivityManager.TYPE_MOBILE].getTypeName()); - assertEquals("WIFI", ni[ConnectivityManager.TYPE_WIFI].getTypeName()); - assertTrue(ni[ConnectivityManager.TYPE_MOBILE].isConnectedOrConnecting()); - assertFalse(ni[ConnectivityManager.TYPE_WIFI].isConnectedOrConnecting()); - assertTrue(ni[ConnectivityManager.TYPE_MOBILE].isAvailable()); - assertFalse(ni[ConnectivityManager.TYPE_WIFI].isAvailable()); - assertTrue(ni[ConnectivityManager.TYPE_MOBILE].isConnected()); - assertFalse(ni[ConnectivityManager.TYPE_WIFI].isConnected()); + assertEquals(ni[TYPE_MOBILE].getType(), TYPE_MOBILE); + assertEquals(ni[TYPE_WIFI].getType(), TYPE_WIFI); - assertEquals(ni[ConnectivityManager.TYPE_MOBILE].describeContents(), 0); - assertEquals(ni[ConnectivityManager.TYPE_WIFI].describeContents(), 0); + assertEquals(MOBILE_TYPE_NAME, ni[TYPE_MOBILE].getTypeName()); + assertEquals(WIFI_TYPE_NAME, ni[TYPE_WIFI].getTypeName()); - assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getState(), State.CONNECTED); - assertEquals(ni[ConnectivityManager.TYPE_MOBILE].getDetailedState(), - DetailedState.CONNECTED); + assertTrue(ni[TYPE_MOBILE].isConnectedOrConnecting()); + assertFalse(ni[TYPE_WIFI].isConnectedOrConnecting()); - assertNull(ni[ConnectivityManager.TYPE_MOBILE].getReason()); - assertNull(ni[ConnectivityManager.TYPE_WIFI].getReason()); - assertEquals("internet", ni[ConnectivityManager.TYPE_MOBILE].getExtraInfo()); - assertNull(ni[ConnectivityManager.TYPE_WIFI].getExtraInfo()); + assertTrue(ni[TYPE_MOBILE].isAvailable()); + assertFalse(ni[TYPE_WIFI].isAvailable()); - assertNotNull(ni[ConnectivityManager.TYPE_MOBILE].toString()); - assertNotNull(ni[ConnectivityManager.TYPE_WIFI].toString()); - } + assertTrue(ni[TYPE_MOBILE].isConnected()); + assertFalse(ni[TYPE_WIFI].isConnected()); - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test writeToParcel(Parcel dest, int flags).", - method = "writeToParcel", - args = {android.os.Parcel.class, java.lang.Integer.class} - ) - //@ToBeFixed(bug = "1703933", explanation = "Cannot test if the data was written correctly," - public void testWriteToParcel() { - NetworkInfo[] networkInfos = mConnectivityManager.getAllNetworkInfo(); - NetworkInfo mobileInfo = networkInfos[ConnectivityManager.TYPE_MOBILE]; - Parcel p = Parcel.obtain(); + assertEquals(State.CONNECTED, ni[TYPE_MOBILE].getState()); + assertEquals(State.UNKNOWN, ni[TYPE_WIFI].getState()); - mobileInfo.writeToParcel(p, 1); + assertEquals(DetailedState.CONNECTED, ni[TYPE_MOBILE].getDetailedState()); + assertEquals(DetailedState.IDLE, ni[TYPE_WIFI].getDetailedState()); + + assertNotNull(ni[TYPE_MOBILE].getReason()); + assertNull(ni[TYPE_WIFI].getReason()); + + assertNotNull(ni[TYPE_MOBILE].getExtraInfo()); + assertNull(ni[TYPE_WIFI].getExtraInfo()); + + assertNotNull(ni[TYPE_MOBILE].toString()); + assertNotNull(ni[TYPE_WIFI].toString()); } } From f4c5ba485607468d90d277cff08c3a70347edc7e Mon Sep 17 00:00:00 2001 From: Eric Shienbrood <> Date: Tue, 14 Apr 2009 15:40:19 -0700 Subject: [PATCH 0016/1109] AI 146222: Manual merge of 145980 from donutburger => master. Automated import of CL 146222 --- tests/cts/net/src/android/net/cts/NetworkInfoTest.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java index 62a5f3fad9..ea1e047d6a 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java @@ -35,16 +35,6 @@ public class NetworkInfoTest extends AndroidTestCase { public static final String MOBILE_TYPE_NAME = "MOBILE"; public static final String WIFI_TYPE_NAME = "WIFI"; - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test constructor(s) of NetworkInfo.", - method = "NetworkInfo", - args = {int.class} - ) - public void testConstructor() { - new NetworkInfo(ConnectivityManager.TYPE_MOBILE); - } - @TestTargets({ @TestTargetNew( level = TestLevel.COMPLETE, From 71f2c4fa150cc7bb8c80f1c155e5f3c6abab7c9f Mon Sep 17 00:00:00 2001 From: Scott Su <> Date: Tue, 14 Apr 2009 23:34:23 -0700 Subject: [PATCH 0017/1109] AI 146287: CTS: fixed failed problem in ProxyTest Automated import of CL 146287 --- .../net/src/android/net/cts/ProxyTest.java | 63 ++++++++++++------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ProxyTest.java b/tests/cts/net/src/android/net/cts/ProxyTest.java index 9345ac2485..fd25084eb6 100644 --- a/tests/cts/net/src/android/net/cts/ProxyTest.java +++ b/tests/cts/net/src/android/net/cts/ProxyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2009 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. @@ -18,33 +18,49 @@ package android.net.cts; import android.content.Context; import android.net.Proxy; -import android.provider.Settings; +import android.provider.Settings.Secure; import android.test.AndroidTestCase; import dalvik.annotation.TestTargets; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; @TestTargetClass(Proxy.class) public class ProxyTest extends AndroidTestCase { + + private Context mContext; + private String mOriginHost; + private int mOriginPort; + @Override protected void setUp() throws Exception { super.setUp(); + mContext = getContext(); + mOriginHost = Proxy.getHost(mContext); + mOriginPort = Proxy.getPort(mContext); + } + + @Override + protected void tearDown() throws Exception { + // Secure.putString should run only on device + Secure.putString(mContext.getContentResolver(), + Secure.HTTP_PROXY, + mOriginHost + ":" + mOriginPort); + + super.tearDown(); } @TestTargetNew( level = TestLevel.COMPLETE, + notes = "Test constructor(s) of Proxy.", method = "Proxy", args = {} ) public void testConstructor() { - - try { - Proxy proxy = new Proxy(); - } catch (Exception e) { - fail("shouldn't throw exception"); - } + new Proxy(); } @TestTargets({ @@ -60,30 +76,31 @@ public class ProxyTest extends AndroidTestCase { ), @TestTargetNew( level = TestLevel.COMPLETE, - method = "getHost", + method = "getPort", args = {Context.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - method = "getPort", + method = "getHost", args = {Context.class} ) }) public void testAccessProperties() { - String mHost = "www.google.com"; - int mPort = 8080; - String mHttpProxy = mHost + ":" + mPort; + final int minValidPort = 0; + final int maxValidPort = 65535; + int defaultPort = Proxy.getDefaultPort(); + if(null == Proxy.getDefaultHost()) { + assertEquals(-1, defaultPort); + } else { + assertTrue(defaultPort >= minValidPort && defaultPort <= maxValidPort); + } - Settings.System.putString(mContext.getContentResolver(), - Settings.System.HTTP_PROXY, null); - assertNull(Proxy.getHost(mContext)); - assertEquals(-1,Proxy.getPort(mContext)); + final String host = "proxy.example.com"; + final int port = 2008; - Settings.System.putString(mContext.getContentResolver(), - Settings.System.HTTP_PROXY, mHttpProxy); - assertEquals(mHost,Proxy.getHost(mContext)); - assertEquals(mPort,Proxy.getPort(mContext)); + // Secure.putString should run only on device + Secure.putString(mContext.getContentResolver(), Secure.HTTP_PROXY, host + ":" + port); + assertEquals(host, Proxy.getHost(mContext)); + assertEquals(port, Proxy.getPort(mContext)); } - } - From 9c2e78b1284855cde87c4139e11028d79dcb52ca Mon Sep 17 00:00:00 2001 From: Scott Su <> Date: Tue, 14 Apr 2009 23:34:43 -0700 Subject: [PATCH 0018/1109] AI 146288: am: CL 146287 CTS: fixed failed problem in ProxyTest Original author: sus Merged from: //branches/cupcake/... Automated import of CL 146288 --- .../net/src/android/net/cts/ProxyTest.java | 63 ++++++++++++------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ProxyTest.java b/tests/cts/net/src/android/net/cts/ProxyTest.java index 9345ac2485..fd25084eb6 100644 --- a/tests/cts/net/src/android/net/cts/ProxyTest.java +++ b/tests/cts/net/src/android/net/cts/ProxyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2009 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. @@ -18,33 +18,49 @@ package android.net.cts; import android.content.Context; import android.net.Proxy; -import android.provider.Settings; +import android.provider.Settings.Secure; import android.test.AndroidTestCase; import dalvik.annotation.TestTargets; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; @TestTargetClass(Proxy.class) public class ProxyTest extends AndroidTestCase { + + private Context mContext; + private String mOriginHost; + private int mOriginPort; + @Override protected void setUp() throws Exception { super.setUp(); + mContext = getContext(); + mOriginHost = Proxy.getHost(mContext); + mOriginPort = Proxy.getPort(mContext); + } + + @Override + protected void tearDown() throws Exception { + // Secure.putString should run only on device + Secure.putString(mContext.getContentResolver(), + Secure.HTTP_PROXY, + mOriginHost + ":" + mOriginPort); + + super.tearDown(); } @TestTargetNew( level = TestLevel.COMPLETE, + notes = "Test constructor(s) of Proxy.", method = "Proxy", args = {} ) public void testConstructor() { - - try { - Proxy proxy = new Proxy(); - } catch (Exception e) { - fail("shouldn't throw exception"); - } + new Proxy(); } @TestTargets({ @@ -60,30 +76,31 @@ public class ProxyTest extends AndroidTestCase { ), @TestTargetNew( level = TestLevel.COMPLETE, - method = "getHost", + method = "getPort", args = {Context.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - method = "getPort", + method = "getHost", args = {Context.class} ) }) public void testAccessProperties() { - String mHost = "www.google.com"; - int mPort = 8080; - String mHttpProxy = mHost + ":" + mPort; + final int minValidPort = 0; + final int maxValidPort = 65535; + int defaultPort = Proxy.getDefaultPort(); + if(null == Proxy.getDefaultHost()) { + assertEquals(-1, defaultPort); + } else { + assertTrue(defaultPort >= minValidPort && defaultPort <= maxValidPort); + } - Settings.System.putString(mContext.getContentResolver(), - Settings.System.HTTP_PROXY, null); - assertNull(Proxy.getHost(mContext)); - assertEquals(-1,Proxy.getPort(mContext)); + final String host = "proxy.example.com"; + final int port = 2008; - Settings.System.putString(mContext.getContentResolver(), - Settings.System.HTTP_PROXY, mHttpProxy); - assertEquals(mHost,Proxy.getHost(mContext)); - assertEquals(mPort,Proxy.getPort(mContext)); + // Secure.putString should run only on device + Secure.putString(mContext.getContentResolver(), Secure.HTTP_PROXY, host + ":" + port); + assertEquals(host, Proxy.getHost(mContext)); + assertEquals(port, Proxy.getPort(mContext)); } - } - From daff20c5e615e1fdc547538b7b5b64f2b79003e9 Mon Sep 17 00:00:00 2001 From: Scott Su <> Date: Thu, 16 Apr 2009 12:01:02 -0700 Subject: [PATCH 0019/1109] AI 146516: am: CL 146072 am: CL 146071 CTS: Clean up test annotations Original author: sus Merged from: //branches/cupcake/... Original author: android-build Automated import of CL 146516 --- .../net/cts/LocalServerSocketTest.java | 1 - .../cts/NetworkInfo_DetailedStateTest.java | 1 - .../net/cts/NetworkInfo_StateTest.java | 1 - .../net/src/android/net/cts/ProxyTest.java | 57 ++++++++----------- 4 files changed, 25 insertions(+), 35 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java index a6511e8521..07f29c6783 100644 --- a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java @@ -26,7 +26,6 @@ import android.net.LocalSocketAddress; import android.os.ParcelFileDescriptor; import android.test.AndroidTestCase; import dalvik.annotation.TestTargets; -import dalvik.annotation.TestStatus; import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java index 002adfecaf..0e05b28119 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java @@ -19,7 +19,6 @@ package android.net.cts; import android.net.NetworkInfo.DetailedState; import android.test.AndroidTestCase; import dalvik.annotation.TestTargets; -import dalvik.annotation.TestStatus; import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java index 2f58784708..249df4b588 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java @@ -18,7 +18,6 @@ package android.net.cts; import android.test.AndroidTestCase; import dalvik.annotation.TestTargets; -import dalvik.annotation.TestStatus; import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; diff --git a/tests/cts/net/src/android/net/cts/ProxyTest.java b/tests/cts/net/src/android/net/cts/ProxyTest.java index d9f7c1a942..9345ac2485 100644 --- a/tests/cts/net/src/android/net/cts/ProxyTest.java +++ b/tests/cts/net/src/android/net/cts/ProxyTest.java @@ -20,9 +20,9 @@ import android.content.Context; import android.net.Proxy; import android.provider.Settings; import android.test.AndroidTestCase; -import dalvik.annotation.TestInfo; -import dalvik.annotation.TestStatus; -import dalvik.annotation.TestTarget; +import dalvik.annotation.TestTargets; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestTargetClass; @TestTargetClass(Proxy.class) @@ -33,15 +33,11 @@ public class ProxyTest extends AndroidTestCase { } - @TestInfo( - status = TestStatus.TBR, - notes = "Test constructor(s) of Proxy.", - targets = { - @TestTarget( - methodName = "Proxy", - methodArgs = {} - ) - }) + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "Proxy", + args = {} + ) public void testConstructor() { try { @@ -51,29 +47,26 @@ public class ProxyTest extends AndroidTestCase { } } - @TestInfo( - status = TestStatus.TBR, - notes = "Test getDefaultPort().", - targets = { - @TestTarget( - methodName = "getDefaultPort", - methodArgs = {} + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getDefaultPort", + args = {} ), - @TestTarget( - methodName = "getDefaultHost", - methodArgs = {} + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getDefaultHost", + args = {} ), - @TestTarget( - methodName = "getHost", - methodArgs = {Context.class} + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getHost", + args = {Context.class} ), - @TestTarget( - methodName = "getHost", - methodArgs = {Context.class} - ), - @TestTarget( - methodName = "getPort", - methodArgs = {Context.class} + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getPort", + args = {Context.class} ) }) public void testAccessProperties() { From 0a30b3a77ee56edb925b0c42137585dde859956f Mon Sep 17 00:00:00 2001 From: Scott Su <> Date: Sat, 18 Apr 2009 20:48:00 -0700 Subject: [PATCH 0020/1109] AI 146564: am: CL 146288 am: CL 146287 CTS: fixed failed problem in ProxyTest Original author: sus Merged from: //branches/cupcake/... Original author: android-build Automated import of CL 146564 --- .../net/src/android/net/cts/ProxyTest.java | 63 ++++++++++++------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ProxyTest.java b/tests/cts/net/src/android/net/cts/ProxyTest.java index 9345ac2485..fd25084eb6 100644 --- a/tests/cts/net/src/android/net/cts/ProxyTest.java +++ b/tests/cts/net/src/android/net/cts/ProxyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2009 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. @@ -18,33 +18,49 @@ package android.net.cts; import android.content.Context; import android.net.Proxy; -import android.provider.Settings; +import android.provider.Settings.Secure; import android.test.AndroidTestCase; import dalvik.annotation.TestTargets; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; @TestTargetClass(Proxy.class) public class ProxyTest extends AndroidTestCase { + + private Context mContext; + private String mOriginHost; + private int mOriginPort; + @Override protected void setUp() throws Exception { super.setUp(); + mContext = getContext(); + mOriginHost = Proxy.getHost(mContext); + mOriginPort = Proxy.getPort(mContext); + } + + @Override + protected void tearDown() throws Exception { + // Secure.putString should run only on device + Secure.putString(mContext.getContentResolver(), + Secure.HTTP_PROXY, + mOriginHost + ":" + mOriginPort); + + super.tearDown(); } @TestTargetNew( level = TestLevel.COMPLETE, + notes = "Test constructor(s) of Proxy.", method = "Proxy", args = {} ) public void testConstructor() { - - try { - Proxy proxy = new Proxy(); - } catch (Exception e) { - fail("shouldn't throw exception"); - } + new Proxy(); } @TestTargets({ @@ -60,30 +76,31 @@ public class ProxyTest extends AndroidTestCase { ), @TestTargetNew( level = TestLevel.COMPLETE, - method = "getHost", + method = "getPort", args = {Context.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - method = "getPort", + method = "getHost", args = {Context.class} ) }) public void testAccessProperties() { - String mHost = "www.google.com"; - int mPort = 8080; - String mHttpProxy = mHost + ":" + mPort; + final int minValidPort = 0; + final int maxValidPort = 65535; + int defaultPort = Proxy.getDefaultPort(); + if(null == Proxy.getDefaultHost()) { + assertEquals(-1, defaultPort); + } else { + assertTrue(defaultPort >= minValidPort && defaultPort <= maxValidPort); + } - Settings.System.putString(mContext.getContentResolver(), - Settings.System.HTTP_PROXY, null); - assertNull(Proxy.getHost(mContext)); - assertEquals(-1,Proxy.getPort(mContext)); + final String host = "proxy.example.com"; + final int port = 2008; - Settings.System.putString(mContext.getContentResolver(), - Settings.System.HTTP_PROXY, mHttpProxy); - assertEquals(mHost,Proxy.getHost(mContext)); - assertEquals(mPort,Proxy.getPort(mContext)); + // Secure.putString should run only on device + Secure.putString(mContext.getContentResolver(), Secure.HTTP_PROXY, host + ":" + port); + assertEquals(host, Proxy.getHost(mContext)); + assertEquals(port, Proxy.getPort(mContext)); } - } - From 3165096c2d71aa3cb13d7d739df49a8abf5ec52a Mon Sep 17 00:00:00 2001 From: Phil Dubach <> Date: Mon, 20 Apr 2009 17:57:22 -0700 Subject: [PATCH 0021/1109] AI 147059: CTS: Fix LOCAL_MODULE_TAGS for CTS tests CTS tests should use local module tag 'tests' such that they are not built and included in the image by default. BUG=1778334 Automated import of CL 147059 --- tests/cts/net/Android.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index 0a2a6f382b..a2bbc9c316 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -16,7 +16,7 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) -LOCAL_MODULE_TAGS := ctstests_net +LOCAL_MODULE_TAGS := tests LOCAL_JAVA_LIBRARIES := android.test.runner From 2774b0fab0e6d7c910baa997d12e65b7fa65d886 Mon Sep 17 00:00:00 2001 From: Phil Dubach <> Date: Mon, 20 Apr 2009 18:00:20 -0700 Subject: [PATCH 0022/1109] AI 147064: am: CL 147060 am: CL 147059 CTS: Fix LOCAL_MODULE_TAGS for CTS tests CTS tests should use local module tag 'tests' such that they are not built and included in the image by default. Original author: phillipd Merged from: //branches/cupcake/... Original author: android-build Automated import of CL 147064 --- tests/cts/net/Android.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index 0a2a6f382b..a2bbc9c316 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -16,7 +16,7 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) -LOCAL_MODULE_TAGS := ctstests_net +LOCAL_MODULE_TAGS := tests LOCAL_JAVA_LIBRARIES := android.test.runner From 3da72df1599b6ae9c20dca66ddfb11954643d200 Mon Sep 17 00:00:00 2001 From: Phil Dubach <> Date: Tue, 21 Apr 2009 01:02:54 -0700 Subject: [PATCH 0023/1109] AI 147060: am: CL 147059 CTS: Fix LOCAL_MODULE_TAGS for CTS tests CTS tests should use local module tag 'tests' such that they are not built and included in the image by default. Original author: phillipd Merged from: //branches/cupcake/... Automated import of CL 147060 --- tests/cts/net/Android.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index 0a2a6f382b..a2bbc9c316 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -16,7 +16,7 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) -LOCAL_MODULE_TAGS := ctstests_net +LOCAL_MODULE_TAGS := tests LOCAL_JAVA_LIBRARIES := android.test.runner From 0f009ffc55bf3404f43dba000031d2293a14e061 Mon Sep 17 00:00:00 2001 From: Scott Su <> Date: Wed, 29 Apr 2009 03:12:14 -0700 Subject: [PATCH 0024/1109] AI 147986: Change CTS tests to use InstrumentationCoreTestRunner, which has handled the @BrokenTest Automated import of CL 147986 --- tests/cts/net/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index 6c2dfbdf65..f6db2feb70 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -22,7 +22,7 @@ - From 68b8cda17af0cb88732ddbc264cfbeab86304d9b Mon Sep 17 00:00:00 2001 From: Scott Su Date: Thu, 30 Apr 2009 16:53:23 -0700 Subject: [PATCH 0025/1109] AI 148053: CTS: fixed failed testcases Automated import of CL 148053 --- .../net/cts/ConnectivityManagerTest.java | 29 ++++------- .../src/android/net/cts/NetworkInfoTest.java | 50 ++++++++++++------- .../net/src/android/net/cts/ProxyTest.java | 21 ++------ 3 files changed, 46 insertions(+), 54 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index e8697bebab..abcfb2261c 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2009 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. @@ -16,6 +16,7 @@ package android.net.cts; +import dalvik.annotation.BrokenTest; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; import dalvik.annotation.TestTargetNew; @@ -31,13 +32,15 @@ import android.test.AndroidTestCase; @TestTargetClass(ConnectivityManager.class) public class ConnectivityManagerTest extends AndroidTestCase { + public static final int TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE; + public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI; private static final int HOST_ADDRESS = 0x7f000001;// represent ip 127.0.0.1 private ConnectivityManager mCm; + @Override protected void setUp() throws Exception { super.setUp(); - mCm = (ConnectivityManager) getContext().getSystemService( - Context.CONNECTIVITY_SERVICE); + mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); } @TestTargetNew( @@ -98,17 +101,16 @@ public class ConnectivityManagerTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( level = TestLevel.COMPLETE, - notes = "", method = "getNetworkPreference", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "", method = "setNetworkPreference", args = {int.class} ) }) + @BrokenTest("Cannot write secure settings table") public void testAccessNetworkPreference() { final int expected = 1; @@ -150,15 +152,11 @@ public class ConnectivityManagerTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test startUsingNetworkFeature(int networkType, String feature)." - + "Only test failure case.", method = "startUsingNetworkFeature", args = {int.class, java.lang.String.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test stopUsingNetworkFeature(int networkType, String feature)." - + "Only test failure case.", method = "stopUsingNetworkFeature", args = {int.class, java.lang.String.class} ) @@ -166,20 +164,15 @@ public class ConnectivityManagerTest extends AndroidTestCase { public void testStartUsingNetworkFeature() { final String invalidateFeature = "invalidateFeature"; - // TODO: MMS feature string is not public final String mmsFeature = "enableMMS"; final int failureCode = -1; - assertEquals(failureCode, mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, - invalidateFeature)); - assertEquals(failureCode, mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, - invalidateFeature)); + assertEquals(failureCode, mCm.startUsingNetworkFeature(TYPE_MOBILE, invalidateFeature)); + assertEquals(failureCode, mCm.stopUsingNetworkFeature(TYPE_MOBILE, invalidateFeature)); // Should return failure(-1) because MMS is not supported on WIFI. - assertEquals(failureCode, - mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_WIFI, mmsFeature)); - assertEquals(failureCode, - mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_WIFI, mmsFeature)); + assertEquals(failureCode, mCm.startUsingNetworkFeature(TYPE_WIFI, mmsFeature)); + assertEquals(failureCode, mCm.stopUsingNetworkFeature(TYPE_WIFI, mmsFeature)); } @TestTargetNew( diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java index ea1e047d6a..2c3d73c75a 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java @@ -73,7 +73,6 @@ public class NetworkInfoTest extends AndroidTestCase { ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isConnectedOrConnecting().", method = "isConnected", args = {} ), @@ -114,32 +113,47 @@ public class NetworkInfoTest extends AndroidTestCase { assertFalse(ni[TYPE_WIFI].isFailover()); // test environment:connect as TYPE_MOBILE, and connect to internet. - assertEquals(ni[TYPE_MOBILE].getType(), TYPE_MOBILE); - assertEquals(ni[TYPE_WIFI].getType(), TYPE_WIFI); + assertEquals(TYPE_MOBILE, ni[TYPE_MOBILE].getType()); + assertEquals(TYPE_WIFI, ni[TYPE_WIFI].getType()); assertEquals(MOBILE_TYPE_NAME, ni[TYPE_MOBILE].getTypeName()); assertEquals(WIFI_TYPE_NAME, ni[TYPE_WIFI].getTypeName()); - assertTrue(ni[TYPE_MOBILE].isConnectedOrConnecting()); - assertFalse(ni[TYPE_WIFI].isConnectedOrConnecting()); + if(ni[TYPE_MOBILE].isConnectedOrConnecting()) { + assertTrue(ni[TYPE_MOBILE].isAvailable()); + assertTrue(ni[TYPE_MOBILE].isConnected()); + assertEquals(State.CONNECTED, ni[TYPE_MOBILE].getState()); + assertEquals(DetailedState.CONNECTED, ni[TYPE_MOBILE].getDetailedState()); + assertNotNull(ni[TYPE_MOBILE].getReason()); + assertNotNull(ni[TYPE_MOBILE].getExtraInfo()); + } else { + assertFalse(ni[TYPE_MOBILE].isAvailable()); + assertFalse(ni[TYPE_MOBILE].isConnected()); - assertTrue(ni[TYPE_MOBILE].isAvailable()); - assertFalse(ni[TYPE_WIFI].isAvailable()); + // mobile state is undefined - assertTrue(ni[TYPE_MOBILE].isConnected()); - assertFalse(ni[TYPE_WIFI].isConnected()); + assertEquals(DetailedState.IDLE, ni[TYPE_MOBILE].getDetailedState()); + assertNull(ni[TYPE_MOBILE].getReason()); + assertNull(ni[TYPE_MOBILE].getExtraInfo()); + } - assertEquals(State.CONNECTED, ni[TYPE_MOBILE].getState()); - assertEquals(State.UNKNOWN, ni[TYPE_WIFI].getState()); + if(ni[TYPE_WIFI].isConnectedOrConnecting()) { + assertTrue(ni[TYPE_WIFI].isAvailable()); + assertTrue(ni[TYPE_WIFI].isConnected()); + assertEquals(State.CONNECTED, ni[TYPE_WIFI].getState()); + assertEquals(DetailedState.CONNECTED, ni[TYPE_WIFI].getDetailedState()); + assertNotNull(ni[TYPE_WIFI].getReason()); + assertNotNull(ni[TYPE_WIFI].getExtraInfo()); + } else { + assertFalse(ni[TYPE_WIFI].isAvailable()); + assertFalse(ni[TYPE_WIFI].isConnected()); - assertEquals(DetailedState.CONNECTED, ni[TYPE_MOBILE].getDetailedState()); - assertEquals(DetailedState.IDLE, ni[TYPE_WIFI].getDetailedState()); + // wifi state is undefined - assertNotNull(ni[TYPE_MOBILE].getReason()); - assertNull(ni[TYPE_WIFI].getReason()); - - assertNotNull(ni[TYPE_MOBILE].getExtraInfo()); - assertNull(ni[TYPE_WIFI].getExtraInfo()); + assertEquals(DetailedState.IDLE, ni[TYPE_WIFI].getDetailedState()); + assertNull(ni[TYPE_WIFI].getReason()); + assertNull(ni[TYPE_WIFI].getExtraInfo()); + } assertNotNull(ni[TYPE_MOBILE].toString()); assertNotNull(ni[TYPE_WIFI].toString()); diff --git a/tests/cts/net/src/android/net/cts/ProxyTest.java b/tests/cts/net/src/android/net/cts/ProxyTest.java index fd25084eb6..357935adb0 100644 --- a/tests/cts/net/src/android/net/cts/ProxyTest.java +++ b/tests/cts/net/src/android/net/cts/ProxyTest.java @@ -20,9 +20,9 @@ import android.content.Context; import android.net.Proxy; import android.provider.Settings.Secure; import android.test.AndroidTestCase; -import dalvik.annotation.TestTargets; + +import dalvik.annotation.BrokenTest; import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestTargetClass; import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestTargets; @@ -31,31 +31,16 @@ import dalvik.annotation.TestTargets; public class ProxyTest extends AndroidTestCase { private Context mContext; - private String mOriginHost; - private int mOriginPort; @Override protected void setUp() throws Exception { super.setUp(); mContext = getContext(); - mOriginHost = Proxy.getHost(mContext); - mOriginPort = Proxy.getPort(mContext); - } - - @Override - protected void tearDown() throws Exception { - // Secure.putString should run only on device - Secure.putString(mContext.getContentResolver(), - Secure.HTTP_PROXY, - mOriginHost + ":" + mOriginPort); - - super.tearDown(); } @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test constructor(s) of Proxy.", method = "Proxy", args = {} ) @@ -85,6 +70,7 @@ public class ProxyTest extends AndroidTestCase { args = {Context.class} ) }) + @BrokenTest("Cannot write secure settings table") public void testAccessProperties() { final int minValidPort = 0; final int maxValidPort = 65535; @@ -98,7 +84,6 @@ public class ProxyTest extends AndroidTestCase { final String host = "proxy.example.com"; final int port = 2008; - // Secure.putString should run only on device Secure.putString(mContext.getContentResolver(), Secure.HTTP_PROXY, host + ":" + port); assertEquals(host, Proxy.getHost(mContext)); assertEquals(port, Proxy.getPort(mContext)); From e480582d829a87e2d7097cb79b7afb9e4ccbf74a Mon Sep 17 00:00:00 2001 From: Phil Dubach Date: Thu, 7 May 2009 10:34:41 -0700 Subject: [PATCH 0026/1109] AI 148455: CTS: Change tests in Android plan to use new InstrumentationCtsTestRunner BUG=1537738 Automated import of CL 148455 --- tests/cts/net/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index f6db2feb70..a1f632effb 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -22,7 +22,7 @@ - From 665f512ebc9b376e8ca503bdfa77d656c914b0f0 Mon Sep 17 00:00:00 2001 From: Brett Chabot Date: Thu, 14 May 2009 15:55:21 -0700 Subject: [PATCH 0027/1109] Change cts tests to use InstrumentationTestRunner. --- tests/cts/net/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index a1f632effb..6c2dfbdf65 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -22,7 +22,7 @@ - From e7a02b243e27420df5273e0276442225dd50839e Mon Sep 17 00:00:00 2001 From: Brett Chabot Date: Tue, 19 May 2009 18:08:05 -0700 Subject: [PATCH 0028/1109] Revert "Change cts tests to use InstrumentationTestRunner." This reverts commit 665f512ebc9b376e8ca503bdfa77d656c914b0f0. --- tests/cts/net/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index 6c2dfbdf65..a1f632effb 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -22,7 +22,7 @@ - From a87bf95576ef45a304447e55172373049a0350fe Mon Sep 17 00:00:00 2001 From: Phil Dubach Date: Tue, 19 May 2009 11:43:39 -0700 Subject: [PATCH 0029/1109] Integrate unsubmitted cupcake change 131139: CTS: add test cases for net.wifi.ScanResult, SupplicantState, WifiConfiguration, WifiInfo and WifiManager. Added new tests as per mondrian comments. Cleaned code to get rid of eclipse warnings. --- .../android/net/wifi/cts/ScanResultTest.java | 126 ++++++ .../net/wifi/cts/SupplicantStateTest.java | 50 ++ .../net/wifi/cts/WifiConfigurationTest.java | 60 +++ .../android/net/wifi/cts/WifiInfoTest.java | 194 ++++++++ .../android/net/wifi/cts/WifiManagerTest.java | 427 ++++++++++++++++++ .../wifi/cts/WifiManager_WifiLockTest.java | 107 +++++ 6 files changed, 964 insertions(+) create mode 100644 tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java create mode 100644 tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java create mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java create mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java create mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java create mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java diff --git a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java new file mode 100644 index 0000000000..0ab71c70e4 --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2008 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.wifi.cts; + +import java.util.List; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.wifi.ScanResult; +import android.net.wifi.WifiManager; +import android.net.wifi.WifiManager.WifiLock; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; + +@TestTargetClass(ScanResult.class) +public class ScanResultTest extends AndroidTestCase { + private static class MySync { + int expectedState = STATE_NULL; + } + + private WifiManager mWifiManager; + private WifiLock mWifiLock; + private static MySync mMySync; + + private static final int STATE_NULL = 0; + private static final int STATE_WIFI_CHANGING = 1; + private static final int STATE_WIFI_CHANGED = 2; + + private static final String TAG = "WifiInfoTest"; + private static final int TIMEOUT_MSEC = 6000; + private static final int WAIT_MSEC = 60; + private static final int DURATION = 10000; + private IntentFilter mIntentFilter; + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) { + synchronized (mMySync) { + mMySync.expectedState = STATE_WIFI_CHANGED; + mMySync.notify(); + } + } + } + }; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mMySync = new MySync(); + mIntentFilter = new IntentFilter(); + mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); + mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); + mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.ACTION_PICK_WIFI_NETWORK); + + mContext.registerReceiver(mReceiver, mIntentFilter); + mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); + assertNotNull(mWifiManager); + mWifiLock = mWifiManager.createWifiLock(TAG); + mWifiLock.acquire(); + if (!mWifiManager.isWifiEnabled()) + setWifiEnabled(true); + Thread.sleep(DURATION); + assertTrue(mWifiManager.isWifiEnabled()); + mMySync.expectedState = STATE_NULL; + } + + @Override + protected void tearDown() throws Exception { + mWifiLock.release(); + mContext.unregisterReceiver(mReceiver); + if (!mWifiManager.isWifiEnabled()) + setWifiEnabled(true); + Thread.sleep(DURATION); + super.tearDown(); + } + + private void setWifiEnabled(boolean enable) throws Exception { + synchronized (mMySync) { + mMySync.expectedState = STATE_WIFI_CHANGING; + assertTrue(mWifiManager.setWifiEnabled(enable)); + long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; + while (System.currentTimeMillis() < timeout + && mMySync.expectedState == STATE_WIFI_CHANGING) + mMySync.wait(WAIT_MSEC); + } + } + + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "toString", + args = {} + ) + public void testScanResultProperties() { + List scanResults = mWifiManager.getScanResults(); + // this test case should in Wifi environment + for (int i = 0; i < scanResults.size(); i++) { + ScanResult mScanResult = scanResults.get(i); + assertNotNull(mScanResult.toString()); + } + } + +} diff --git a/tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java b/tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java new file mode 100644 index 0000000000..4e03f5e9ce --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2008 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.wifi.cts; + +import android.net.wifi.SupplicantState; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; + +@TestTargetClass(SupplicantState.class) +public class SupplicantStateTest extends AndroidTestCase { + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "isValidState", + args = {android.net.wifi.SupplicantState.class} + ) + }) + public void testIsValidState() { + assertTrue(SupplicantState.isValidState(SupplicantState.DISCONNECTED)); + assertTrue(SupplicantState.isValidState(SupplicantState.INACTIVE)); + assertTrue(SupplicantState.isValidState(SupplicantState.SCANNING)); + assertTrue(SupplicantState.isValidState(SupplicantState.ASSOCIATING)); + assertTrue(SupplicantState.isValidState(SupplicantState.ASSOCIATED)); + assertTrue(SupplicantState.isValidState(SupplicantState.FOUR_WAY_HANDSHAKE)); + assertTrue(SupplicantState.isValidState(SupplicantState.GROUP_HANDSHAKE)); + assertTrue(SupplicantState.isValidState(SupplicantState.COMPLETED)); + assertTrue(SupplicantState.isValidState(SupplicantState.DORMANT)); + assertFalse(SupplicantState.isValidState(SupplicantState.UNINITIALIZED)); + assertFalse(SupplicantState.isValidState(SupplicantState.INVALID)); + } + +} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java new file mode 100644 index 0000000000..3018907092 --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2008 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.wifi.cts; + +import java.util.List; + +import android.content.Context; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiManager; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; + +@TestTargetClass(WifiConfiguration.class) +public class WifiConfigurationTest extends AndroidTestCase { + private WifiManager mWifiManager; + @Override + protected void setUp() throws Exception { + super.setUp(); + mWifiManager = (WifiManager) mContext + .getSystemService(Context.WIFI_SERVICE); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "WifiConfiguration", + args = {} + ), + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "toString", + args = {} + ) + }) + public void testWifiConfiguration() { + List wifiConfigurations = mWifiManager.getConfiguredNetworks(); + for (int i = 0; i < wifiConfigurations.size(); i++) { + WifiConfiguration wifiConfiguration = wifiConfigurations.get(i); + assertNotNull(wifiConfiguration); + assertNotNull(wifiConfiguration.toString()); + } + } +} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java new file mode 100644 index 0000000000..42243c890d --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2008 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.wifi.cts; + +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; +import dalvik.annotation.ToBeFixed; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.wifi.SupplicantState; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; +import android.net.wifi.WifiManager.WifiLock; +import android.test.AndroidTestCase; + +@TestTargetClass(WifiInfo.class) +public class WifiInfoTest extends AndroidTestCase { + private static class MySync { + int expectedState = STATE_NULL; + } + + private WifiManager mWifiManager; + private WifiLock mWifiLock; + private static MySync mMySync; + + private static final int STATE_NULL = 0; + private static final int STATE_WIFI_CHANGING = 1; + private static final int STATE_WIFI_CHANGED = 2; + + private static final String TAG = "WifiInfoTest"; + private static final int TIMEOUT_MSEC = 6000; + private static final int WAIT_MSEC = 60; + private static final int DURATION = 10000; + private IntentFilter mIntentFilter; + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) { + synchronized (mMySync) { + mMySync.expectedState = STATE_WIFI_CHANGED; + mMySync.notify(); + } + } + } + }; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mMySync = new MySync(); + mIntentFilter = new IntentFilter(); + mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); + mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); + mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.ACTION_PICK_WIFI_NETWORK); + + mContext.registerReceiver(mReceiver, mIntentFilter); + mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); + assertNotNull(mWifiManager); + mWifiLock = mWifiManager.createWifiLock(TAG); + mWifiLock.acquire(); + if (!mWifiManager.isWifiEnabled()) + setWifiEnabled(true); + Thread.sleep(DURATION); + assertTrue(mWifiManager.isWifiEnabled()); + mMySync.expectedState = STATE_NULL; + } + + @Override + protected void tearDown() throws Exception { + mWifiLock.release(); + mContext.unregisterReceiver(mReceiver); + if (!mWifiManager.isWifiEnabled()) + setWifiEnabled(true); + Thread.sleep(DURATION); + super.tearDown(); + } + + private void setWifiEnabled(boolean enable) throws Exception { + synchronized (mMySync) { + mMySync.expectedState = STATE_WIFI_CHANGING; + assertTrue(mWifiManager.setWifiEnabled(enable)); + long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; + while (System.currentTimeMillis() < timeout + && mMySync.expectedState == STATE_WIFI_CHANGING) + mMySync.wait(WAIT_MSEC); + } + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getMacAddress", + args = {} + ), + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getIpAddress", + args = {} + ), + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getDetailedStateOf", + args = {android.net.wifi.SupplicantState.class} + ), + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getNetworkId", + args = {} + ), + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getSSID", + args = {} + ), + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getBSSID", + args = {} + ), + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getSupplicantState", + args = {} + ), + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getLinkSpeed", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "toString", + args = {} + ), + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getRssi", + args = {} + ), + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getHiddenSSID", + args = {} + ) + }) + @ToBeFixed(bug="1871573", explanation="android.net.wifi.WifiInfo#getNetworkId() return -1 when" + + " there is wifi connection") + public void testWifiInfoProperties() throws Exception { + // this test case should in Wifi environment + WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); + + assertNotNull(wifiInfo); + assertNotNull(wifiInfo.toString()); + SupplicantState.isValidState(wifiInfo.getSupplicantState()); + WifiInfo.getDetailedStateOf(SupplicantState.DISCONNECTED); + wifiInfo.getSSID(); + wifiInfo.getBSSID(); + wifiInfo.getIpAddress(); + wifiInfo.getLinkSpeed(); + wifiInfo.getRssi(); + wifiInfo.getHiddenSSID(); + wifiInfo.getMacAddress(); + setWifiEnabled(false); + Thread.sleep(DURATION); + wifiInfo = mWifiManager.getConnectionInfo(); + assertEquals(-1, wifiInfo.getNetworkId()); + } + +} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java new file mode 100644 index 0000000000..132ca9247d --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -0,0 +1,427 @@ +/* + * Copyright (C) 2009 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.wifi.cts; + +import java.util.List; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.wifi.ScanResult; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiManager; +import android.net.wifi.WifiConfiguration.Status; +import android.net.wifi.WifiManager.WifiLock; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; + +@TestTargetClass(WifiManager.class) +public class WifiManagerTest extends AndroidTestCase { + private static class MySync { + int expectedState = STATE_NULL; + } + + private WifiManager mWifiManager; + private WifiLock mWifiLock; + private static MySync mMySync; + private List mScanResult = null; + + // Please refer to WifiManager + private static final int MIN_RSSI = -100; + private static final int MAX_RSSI = -55; + + private static final int STATE_NULL = 0; + private static final int STATE_WIFI_CHANGING = 1; + private static final int STATE_WIFI_CHANGED = 2; + private static final int STATE_SCANING = 3; + private static final int STATE_SCAN_RESULTS_AVAILABLE = 4; + + private static final String TAG = "WifiManagerTest"; + private static final String SSID1 = "\"WifiManagerTest\""; + private static final String SSID2 = "\"WifiManagerTestModified\""; + private static final int TIMEOUT_MSEC = 6000; + private static final int WAIT_MSEC = 60; + private static final int DURATION = 10000; + private IntentFilter mIntentFilter; + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { + synchronized (mMySync) { + if (mWifiManager.getScanResults() != null) { + mScanResult = mWifiManager.getScanResults(); + mMySync.expectedState = STATE_SCAN_RESULTS_AVAILABLE; + mScanResult = mWifiManager.getScanResults(); + mMySync.notify(); + } + } + } else if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) { + synchronized (mMySync) { + mMySync.expectedState = STATE_WIFI_CHANGED; + mMySync.notify(); + } + } + } + }; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mMySync = new MySync(); + mIntentFilter = new IntentFilter(); + mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); + mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); + mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.ACTION_PICK_WIFI_NETWORK); + + mContext.registerReceiver(mReceiver, mIntentFilter); + mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); + assertNotNull(mWifiManager); + mWifiLock = mWifiManager.createWifiLock(TAG); + mWifiLock.acquire(); + if (!mWifiManager.isWifiEnabled()) + setWifiEnabled(true); + Thread.sleep(DURATION); + assertTrue(mWifiManager.isWifiEnabled()); + mMySync.expectedState = STATE_NULL; + } + + @Override + protected void tearDown() throws Exception { + mWifiLock.release(); + mContext.unregisterReceiver(mReceiver); + if (!mWifiManager.isWifiEnabled()) + setWifiEnabled(true); + Thread.sleep(DURATION); + super.tearDown(); + } + + private void setWifiEnabled(boolean enable) throws Exception { + synchronized (mMySync) { + mMySync.expectedState = STATE_WIFI_CHANGING; + assertTrue(mWifiManager.setWifiEnabled(enable)); + long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; + while (System.currentTimeMillis() < timeout + && mMySync.expectedState == STATE_WIFI_CHANGING) + mMySync.wait(WAIT_MSEC); + } + } + + private void startScan() throws Exception { + synchronized (mMySync) { + mMySync.expectedState = STATE_SCANING; + assertTrue(mWifiManager.startScan()); + long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; + while (System.currentTimeMillis() < timeout && mMySync.expectedState == STATE_SCANING) + mMySync.wait(WAIT_MSEC); + } + } + + private boolean existSSID(String ssid) { + for (final WifiConfiguration w : mWifiManager.getConfiguredNetworks()) { + if (w.SSID.equals(ssid)) + return true; + } + return false; + } + + private int findConfiguredNetworks(String SSID, List networks) { + for (final WifiConfiguration w : networks) { + if (w.SSID.equals(SSID)) + return networks.indexOf(w); + } + return -1; + } + + private void assertDisableOthers(WifiConfiguration wifiConfiguration, boolean disableOthers) { + for (WifiConfiguration w : mWifiManager.getConfiguredNetworks()) { + if ((!w.SSID.equals(wifiConfiguration.SSID)) && w.status != Status.CURRENT) { + if (disableOthers) + assertEquals(Status.DISABLED, w.status); + } + } + } + + /** + * test point of wifiManager actions: + * 1.reconnect + * 2.reassociate + * 3.disconnect + * 4.pingSupplicant + * 5.satrtScan + */ + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "isWifiEnabled", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "setWifiEnabled", + args = {boolean.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "startScan", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getScanResults", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "pingSupplicant", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "reassociate", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "reconnect", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "disconnect", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "createWifiLock", + args = {int.class, String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "createWifiLock", + args = {String.class} + ) + }) + public void testWifiManagerActions() throws Exception { + assertTrue(mWifiManager.reconnect()); + assertTrue(mWifiManager.reassociate()); + assertTrue(mWifiManager.disconnect()); + assertTrue(mWifiManager.pingSupplicant()); + startScan(); + setWifiEnabled(false); + Thread.sleep(DURATION); + assertFalse(mWifiManager.pingSupplicant()); + final String TAG = "Test"; + assertNotNull(mWifiManager.createWifiLock(TAG)); + assertNotNull(mWifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, TAG)); + } + + /** + * test point of wifiManager properties: + * 1.enable properties + * 2.DhcpInfo properties + * 3.wifi state + * 4.ConnectionInfo + */ + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "isWifiEnabled", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getWifiState", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "setWifiEnabled", + args = {boolean.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getConnectionInfo", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getDhcpInfo", + args = {} + ) + }) + public void testWifiManagerProperties() throws Exception { + setWifiEnabled(true); + assertTrue(mWifiManager.isWifiEnabled()); + assertNotNull(mWifiManager.getDhcpInfo()); + assertEquals(WifiManager.WIFI_STATE_ENABLED, mWifiManager.getWifiState()); + mWifiManager.getConnectionInfo(); + setWifiEnabled(false); + assertFalse(mWifiManager.isWifiEnabled()); + } + + /** + * test point of wifiManager NetWork: + * 1.add NetWork + * 2.update NetWork + * 3.remove NetWork + * 4.enable NetWork + * 5.disable NetWork + * 6.configured Networks + * 7.save configure; + */ + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "isWifiEnabled", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "setWifiEnabled", + args = {boolean.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getConfiguredNetworks", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "addNetwork", + args = {android.net.wifi.WifiConfiguration.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "updateNetwork", + args = {android.net.wifi.WifiConfiguration.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "removeNetwork", + args = {int.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "enableNetwork", + args = {int.class, boolean.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "disableNetwork", + args = {int.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "saveConfiguration", + args = {} + ) + }) + public void testWifiManagerNetWork() throws Exception { + WifiConfiguration wifiConfiguration; + // add a WifiConfig + final int notExist = -1; + List wifiConfiguredNetworks = mWifiManager.getConfiguredNetworks(); + int pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); + if (notExist != pos) { + wifiConfiguration = wifiConfiguredNetworks.get(pos); + mWifiManager.removeNetwork(wifiConfiguration.networkId); + } + pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); + assertEquals(notExist, pos); + final int size = wifiConfiguredNetworks.size(); + + wifiConfiguration = new WifiConfiguration(); + wifiConfiguration.SSID = SSID1; + int netId = mWifiManager.addNetwork(wifiConfiguration); + assertTrue(existSSID(SSID1)); + + wifiConfiguredNetworks = mWifiManager.getConfiguredNetworks(); + assertEquals(size + 1, wifiConfiguredNetworks.size()); + pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); + assertTrue(notExist != pos); + + // Enable & disable network + boolean disableOthers = false; + assertTrue(mWifiManager.enableNetwork(netId, disableOthers)); + wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); + assertDisableOthers(wifiConfiguration, disableOthers); + assertEquals(Status.ENABLED, wifiConfiguration.status); + disableOthers = true; + assertTrue(mWifiManager.enableNetwork(netId, disableOthers)); + wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); + assertDisableOthers(wifiConfiguration, disableOthers); + + assertTrue(mWifiManager.disableNetwork(netId)); + wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); + assertEquals(Status.DISABLED, wifiConfiguration.status); + + // Update a WifiConfig + wifiConfiguration = wifiConfiguredNetworks.get(pos); + wifiConfiguration.SSID = SSID2; + netId = mWifiManager.updateNetwork(wifiConfiguration); + assertFalse(existSSID(SSID1)); + assertTrue(existSSID(SSID2)); + + // Remove a WifiConfig + assertTrue(mWifiManager.removeNetwork(netId)); + assertFalse(mWifiManager.removeNetwork(notExist)); + assertFalse(existSSID(SSID1)); + assertFalse(existSSID(SSID2)); + + assertTrue(mWifiManager.saveConfiguration()); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "compareSignalLevel", + args = {int.class, int.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "calculateSignalLevel", + args = {int.class, int.class} + ) + }) + public void testSignal() { + final int numLevels = 9; + int expectLevel = 0; + assertEquals(expectLevel, WifiManager.calculateSignalLevel(MIN_RSSI, numLevels)); + assertEquals(numLevels - 1, WifiManager.calculateSignalLevel(MAX_RSSI, numLevels)); + expectLevel = 4; + assertEquals(expectLevel, WifiManager.calculateSignalLevel((MIN_RSSI + MAX_RSSI) / 2, + numLevels)); + int rssiA = 4; + int rssiB = 5; + assertTrue(WifiManager.compareSignalLevel(rssiA, rssiB) < 0); + rssiB = 4; + assertTrue(WifiManager.compareSignalLevel(rssiA, rssiB) == 0); + rssiA = 5; + rssiB = 4; + assertTrue(WifiManager.compareSignalLevel(rssiA, rssiB) > 0); + } +} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java new file mode 100644 index 0000000000..53150c9650 --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2008 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.wifi.cts; + +import android.content.Context; +import android.net.wifi.WifiManager; +import android.net.wifi.WifiManager.WifiLock; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; + +@TestTargetClass(WifiManager.WifiLock.class) +public class WifiManager_WifiLockTest extends AndroidTestCase { + + private static final String WIFI_TAG = "WifiManager_WifiLockTest"; + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "acquire", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "finalize", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "isHeld", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "release", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "setReferenceCounted", + args = {boolean.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "toString", + args = {} + ) + }) + public void testWifiLock() { + WifiManager wm = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); + WifiLock wl = wm.createWifiLock(WIFI_TAG); + + wl.setReferenceCounted(true); + assertFalse(wl.isHeld()); + wl.acquire(); + assertTrue(wl.isHeld()); + wl.release(); + assertFalse(wl.isHeld()); + wl.acquire(); + wl.acquire(); + assertTrue(wl.isHeld()); + wl.release(); + assertTrue(wl.isHeld()); + wl.release(); + assertFalse(wl.isHeld()); + assertNotNull(wl.toString()); + try { + wl.release(); + fail("should throw out exception because release is called" + +" a greater number of times than acquire"); + } catch (RuntimeException e) { + // expected + } + + wl = wm.createWifiLock(WIFI_TAG); + wl.setReferenceCounted(false); + assertFalse(wl.isHeld()); + wl.acquire(); + assertTrue(wl.isHeld()); + wl.release(); + assertFalse(wl.isHeld()); + wl.acquire(); + wl.acquire(); + assertTrue(wl.isHeld()); + wl.release(); + assertFalse(wl.isHeld()); + assertNotNull(wl.toString()); + // should be ignored + wl.release(); + } +} From 1c52e1c796e81a9947b044ed4c64760bf740eff5 Mon Sep 17 00:00:00 2001 From: Phil Dubach Date: Tue, 2 Jun 2009 14:46:51 -0700 Subject: [PATCH 0030/1109] Integrate unsubmitted cupcake change 123653: CTS: add test cases for net.SSLCertificateSocketFactory --- .../cts/SSLCertificateSocketFactoryTest.java | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java diff --git a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java new file mode 100644 index 0000000000..b81dd37007 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2008 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 java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; + +import javax.net.SocketFactory; + +import android.net.SSLCertificateSocketFactory; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; +import dalvik.annotation.ToBeFixed; + +@TestTargetClass(SSLCertificateSocketFactory.class) +public class SSLCertificateSocketFactoryTest extends AndroidTestCase { + private SSLCertificateSocketFactory mFactory; + private int mTimeout; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mTimeout = 1000; + mFactory = (SSLCertificateSocketFactory) SSLCertificateSocketFactory.getDefault(mTimeout); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getSupportedCipherSuites", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getDefault", + args = {int.class} + ), + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getDefaultCipherSuites", + args = {} + ) + }) + @ToBeFixed(bug="1695243", explanation="Android API javadocs are incomplete") + public void testAccessProperties() throws Exception { + mFactory.getSupportedCipherSuites(); + mFactory.getDefaultCipherSuites(); + SocketFactory sf = SSLCertificateSocketFactory.getDefault(mTimeout); + assertNotNull(sf); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "createSocket", + args = {java.net.InetAddress.class, int.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "createSocket", + args = {java.net.Socket.class, java.lang.String.class, int.class, boolean.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "createSocket", + args = {java.lang.String.class, int.class} + ), + @TestTargetNew( + level = TestLevel.NOT_FEASIBLE, + method = "createSocket", + args = {java.lang.String.class, int.class, java.net.InetAddress.class, int.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "createSocket", + args = {java.net.InetAddress.class, int.class, java.net.InetAddress.class, int.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "SSLCertificateSocketFactory", + args = {int.class} + ) + }) + public void testCreateSocket() throws Exception { + new SSLCertificateSocketFactory(100); + int port = 443; + String host = "www.fortify.net"; + InetAddress inetAddress = null; + inetAddress = InetAddress.getLocalHost(); + try { + mFactory.createSocket(inetAddress, port); + fail("should throw exception!"); + } catch (IOException e) { + // expected + } + + try { + InetAddress inetAddress1 = InetAddress.getLocalHost(); + InetAddress inetAddress2 = InetAddress.getLocalHost(); + mFactory.createSocket(inetAddress1, port, inetAddress2, port); + fail("should throw exception!"); + } catch (IOException e) { + // expected + } + + try { + Socket socket = new Socket(); + mFactory.createSocket(socket, host, port, true); + fail("should throw exception!"); + } catch (IOException e) { + // expected + } + Socket socket = null; + socket = mFactory.createSocket(host, port); + assertNotNull(socket); + assertNotNull(socket.getOutputStream()); + assertNotNull(socket.getInputStream()); + + // it throw exception when calling createSocket(String, int, InetAddress, int) + // The socket level is invalid. + } + +} From 8b360f568a040e1452dfa0e4c89009435d57c2c7 Mon Sep 17 00:00:00 2001 From: Phil Dubach Date: Thu, 11 Jun 2009 14:02:10 -0700 Subject: [PATCH 0031/1109] Integrate unsubmitted cupcake change 147342: CTS: clean up code in android.net package --- .../net/cts/ConnectivityManagerTest.java | 81 ++++++++++++------- .../src/android/net/cts/CredentialsTest.java | 4 - .../net/src/android/net/cts/DhcpInfoTest.java | 5 +- .../net/cts/LocalServerSocketTest.java | 27 ++----- .../net/cts/LocalSocketAddressTest.java | 11 +-- .../cts/LocalSocketAddress_NamespaceTest.java | 10 +-- .../src/android/net/cts/NetworkInfoTest.java | 52 +++++++----- .../cts/NetworkInfo_DetailedStateTest.java | 31 +++---- .../net/cts/NetworkInfo_StateTest.java | 13 +-- .../net/cts/UrlQuerySanitizerTest.java | 65 ++++++++------- 10 files changed, 142 insertions(+), 157 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index abcfb2261c..a8a149f250 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -16,11 +16,11 @@ package android.net.cts; -import dalvik.annotation.BrokenTest; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestTargets; +import dalvik.annotation.ToBeFixed; import android.content.Context; import android.net.ConnectivityManager; @@ -45,7 +45,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test getNetworkInfo(int networkType).", method = "getNetworkInfo", args = {int.class} ) @@ -77,13 +76,11 @@ public class ConnectivityManagerTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isNetworkTypeValid(int networkType).", method = "isNetworkTypeValid", args = {int.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test isNetworkTypeValid(int networkType).", method = "getAllNetworkInfo", args = {} ) @@ -105,33 +102,58 @@ public class ConnectivityManagerTest extends AndroidTestCase { args = {} ), @TestTargetNew( - level = TestLevel.COMPLETE, + level = TestLevel.SUFFICIENT, method = "setNetworkPreference", args = {int.class} ) }) - @BrokenTest("Cannot write secure settings table") public void testAccessNetworkPreference() { + int initialSetting = mCm.getNetworkPreference(); - final int expected = 1; - int per = mCm.getNetworkPreference(); - mCm.setNetworkPreference(expected); - assertEquals(expected, mCm.getNetworkPreference()); + // Changing the network preference requires android.permission.WRITE_SECURE_SETTINGS, + // which is only available to signed or system applications. - mCm.setNetworkPreference(0); - assertEquals(0, mCm.getNetworkPreference()); + // Setting the same preference that is already set is a no-op and does not throw + // a SecurityException. + mCm.setNetworkPreference(initialSetting); + assertEquals(initialSetting, mCm.getNetworkPreference()); + // find a valid setting that is different from the initial setting + int validSetting = -1; + NetworkInfo[] ni = mCm.getAllNetworkInfo(); + for (NetworkInfo n : ni) { + int type = n.getType(); + if (type != initialSetting) { + validSetting = type; + break; + } + } + if (validSetting >= 0) { + try { + mCm.setNetworkPreference(validSetting); + fail("Trying to change the network preference should throw SecurityException"); + } catch (SecurityException expected) { + // expected + } + } + + // find an invalid setting + int invalidSetting = -1; + for (int i = 0; i < 10; i++) { + if (!ConnectivityManager.isNetworkTypeValid(i)) { + invalidSetting = i; + break; + } + } + if (invalidSetting >= 0) { + // illegal setting should be ignored + mCm.setNetworkPreference(invalidSetting); + assertEquals(initialSetting, mCm.getNetworkPreference()); + } + + // illegal setting should be ignored mCm.setNetworkPreference(-1); - assertEquals(0, mCm.getNetworkPreference()); - - mCm.setNetworkPreference(2); - assertEquals(0, mCm.getNetworkPreference()); - - mCm.setNetworkPreference(1); - - assertEquals(1, mCm.getNetworkPreference()); - - mCm.setNetworkPreference(per); + assertEquals(initialSetting, mCm.getNetworkPreference()); } @TestTargetNew( @@ -177,7 +199,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test requestRouteToHost(int networkType, int hostAddress).", method = "requestRouteToHost", args = {int.class, int.class} ) @@ -193,18 +214,24 @@ public class ConnectivityManagerTest extends AndroidTestCase { @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test getActiveNetworkInfo().", method = "getActiveNetworkInfo", args = {} ) + @ToBeFixed(bug="1695243", explanation="No Javadoc") public void testGetActiveNetworkInfo() { - NetworkInfo ni = mCm.getActiveNetworkInfo(); + if (ni != null) { assertTrue(ni.getType() >= 0); - } else { - fail("There is no active network connected, should be at least one kind of network"); } } + @TestTargetNew( + level = TestLevel.SUFFICIENT, + method = "getBackgroundDataSetting", + args = {} + ) + public void testTest() { + mCm.getBackgroundDataSetting(); + } } diff --git a/tests/cts/net/src/android/net/cts/CredentialsTest.java b/tests/cts/net/src/android/net/cts/CredentialsTest.java index fe65805294..6cf8c2351e 100644 --- a/tests/cts/net/src/android/net/cts/CredentialsTest.java +++ b/tests/cts/net/src/android/net/cts/CredentialsTest.java @@ -29,25 +29,21 @@ public class CredentialsTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test constructor of Credentials, and test getGid, getPid, getUid.", method = "Credentials", args = {int.class, int.class, int.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test constructor of Credentials, and test getGid, getPid, getUid.", method = "getGid", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test constructor of Credentials, and test getGid, getPid, getUid.", method = "getPid", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test constructor of Credentials, and test getGid, getPid, getUid.", method = "getUid", args = {} ) diff --git a/tests/cts/net/src/android/net/cts/DhcpInfoTest.java b/tests/cts/net/src/android/net/cts/DhcpInfoTest.java index 1a1ad477fd..97bd27a970 100644 --- a/tests/cts/net/src/android/net/cts/DhcpInfoTest.java +++ b/tests/cts/net/src/android/net/cts/DhcpInfoTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2009 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. @@ -18,10 +18,9 @@ package android.net.cts; import android.net.DhcpInfo; import android.test.AndroidTestCase; -import dalvik.annotation.TestTargets; import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; @TestTargetClass(DhcpInfo.class) public class DhcpInfoTest extends AndroidTestCase { diff --git a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java index 07f29c6783..21c7d5e299 100644 --- a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2009 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. @@ -15,58 +15,50 @@ */ package android.net.cts; -import java.io.FileDescriptor; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.net.Socket; import android.net.LocalServerSocket; import android.net.LocalSocket; import android.net.LocalSocketAddress; -import android.os.ParcelFileDescriptor; import android.test.AndroidTestCase; -import dalvik.annotation.TestTargets; -import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; import dalvik.annotation.ToBeFixed; @TestTargetClass(LocalServerSocket.class) public class LocalServerSocketTest extends AndroidTestCase { + @TestTargets({ @TestTargetNew( level = TestLevel.COMPLETE, - notes = "test LocalServerSocket", method = "accept", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "test LocalServerSocket", method = "close", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "test LocalServerSocket", method = "getFileDescriptor", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "test LocalServerSocket", method = "getLocalSocketAddress", args = {} ), @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test LocalServerSocket", + level = TestLevel.NOT_FEASIBLE, method = "LocalServerSocket", args = {java.io.FileDescriptor.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "test LocalServerSocket", method = "LocalServerSocket", args = {java.lang.String.class} ) @@ -77,15 +69,6 @@ public class LocalServerSocketTest extends AndroidTestCase { LocalServerSocket localServerSocket = new LocalServerSocket(LocalSocketTest.mSockAddr); assertNotNull(localServerSocket.getLocalSocketAddress()); commonFunctions(localServerSocket); - - Socket socket = new Socket("www.google.com", 80); - ParcelFileDescriptor parcelFD = ParcelFileDescriptor.fromSocket(socket); - FileDescriptor fd = parcelFD.getFileDescriptor(); - - // enable the following after bug 1520987 fixed -// localServerSocket = new LocalServerSocket(fd); -// assertNull(localServerSocket.getLocalSocketAddress()); -// commonFunctions(localServerSocket); } public void commonFunctions(LocalServerSocket localServerSocket) throws IOException { diff --git a/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java b/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java index 75232c4fff..e3141d57e5 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java @@ -27,11 +27,6 @@ import dalvik.annotation.TestTargetClass; @TestTargetClass(LocalSocketAddress.class) public class LocalSocketAddressTest extends AndroidTestCase { - @Override - protected void setUp() throws Exception { - super.setUp(); - } - @TestTargets({ @TestTargetNew( level = TestLevel.COMPLETE, @@ -65,17 +60,17 @@ public class LocalSocketAddressTest extends AndroidTestCase { assertEquals(Namespace.ABSTRACT, localSocketAddress.getNamespace()); // specify the namespace - LocalSocketAddress localSocketAddress2 = + LocalSocketAddress localSocketAddress2 = new LocalSocketAddress("name2", Namespace.ABSTRACT); assertEquals("name2", localSocketAddress2.getName()); assertEquals(Namespace.ABSTRACT, localSocketAddress2.getNamespace()); - LocalSocketAddress localSocketAddress3 = + LocalSocketAddress localSocketAddress3 = new LocalSocketAddress("name3", Namespace.FILESYSTEM); assertEquals("name3", localSocketAddress3.getName()); assertEquals(Namespace.FILESYSTEM, localSocketAddress3.getNamespace()); - LocalSocketAddress localSocketAddress4 = + LocalSocketAddress localSocketAddress4 = new LocalSocketAddress("name4", Namespace.RESERVED); assertEquals("name4", localSocketAddress4.getName()); assertEquals(Namespace.RESERVED, localSocketAddress4.getNamespace()); diff --git a/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java b/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java index 5d29c81895..fc9de5b14c 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2009 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. @@ -18,19 +18,13 @@ package android.net.cts; import android.net.LocalSocketAddress.Namespace; import android.test.AndroidTestCase; -import dalvik.annotation.TestTargets; import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; @TestTargetClass(Namespace.class) public class LocalSocketAddress_NamespaceTest extends AndroidTestCase { - @Override - protected void setUp() throws Exception { - super.setUp(); - } - @TestTargetNew( level = TestLevel.COMPLETE, notes = "Test valueOf(String name).", diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java index 2c3d73c75a..d2de4e4be2 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java @@ -51,16 +51,31 @@ public class NetworkInfoTest extends AndroidTestCase { method = "isFailover", args = {} ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "isRoaming", + args = {} + ), @TestTargetNew( level = TestLevel.COMPLETE, method = "getType", args = {} ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getSubtype", + args = {} + ), @TestTargetNew( level = TestLevel.COMPLETE, method = "getTypeName", args = {} ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getSubtypeName", + args = {} + ), @TestTargetNew( level = TestLevel.COMPLETE, method = "setIsAvailable", @@ -116,25 +131,24 @@ public class NetworkInfoTest extends AndroidTestCase { assertEquals(TYPE_MOBILE, ni[TYPE_MOBILE].getType()); assertEquals(TYPE_WIFI, ni[TYPE_WIFI].getType()); + // don't know the return value + ni[TYPE_MOBILE].getSubtype(); + ni[TYPE_WIFI].getSubtype(); + assertEquals(MOBILE_TYPE_NAME, ni[TYPE_MOBILE].getTypeName()); assertEquals(WIFI_TYPE_NAME, ni[TYPE_WIFI].getTypeName()); + // don't know the return value + ni[TYPE_MOBILE].getSubtypeName(); + ni[TYPE_WIFI].getSubtypeName(); + if(ni[TYPE_MOBILE].isConnectedOrConnecting()) { assertTrue(ni[TYPE_MOBILE].isAvailable()); assertTrue(ni[TYPE_MOBILE].isConnected()); assertEquals(State.CONNECTED, ni[TYPE_MOBILE].getState()); assertEquals(DetailedState.CONNECTED, ni[TYPE_MOBILE].getDetailedState()); - assertNotNull(ni[TYPE_MOBILE].getReason()); - assertNotNull(ni[TYPE_MOBILE].getExtraInfo()); - } else { - assertFalse(ni[TYPE_MOBILE].isAvailable()); - assertFalse(ni[TYPE_MOBILE].isConnected()); - - // mobile state is undefined - - assertEquals(DetailedState.IDLE, ni[TYPE_MOBILE].getDetailedState()); - assertNull(ni[TYPE_MOBILE].getReason()); - assertNull(ni[TYPE_MOBILE].getExtraInfo()); + ni[TYPE_MOBILE].getReason(); + ni[TYPE_MOBILE].getExtraInfo(); } if(ni[TYPE_WIFI].isConnectedOrConnecting()) { @@ -142,19 +156,13 @@ public class NetworkInfoTest extends AndroidTestCase { assertTrue(ni[TYPE_WIFI].isConnected()); assertEquals(State.CONNECTED, ni[TYPE_WIFI].getState()); assertEquals(DetailedState.CONNECTED, ni[TYPE_WIFI].getDetailedState()); - assertNotNull(ni[TYPE_WIFI].getReason()); - assertNotNull(ni[TYPE_WIFI].getExtraInfo()); - } else { - assertFalse(ni[TYPE_WIFI].isAvailable()); - assertFalse(ni[TYPE_WIFI].isConnected()); - - // wifi state is undefined - - assertEquals(DetailedState.IDLE, ni[TYPE_WIFI].getDetailedState()); - assertNull(ni[TYPE_WIFI].getReason()); - assertNull(ni[TYPE_WIFI].getExtraInfo()); + ni[TYPE_WIFI].getReason(); + ni[TYPE_WIFI].getExtraInfo(); } + assertFalse(ni[TYPE_MOBILE].isRoaming()); + assertFalse(ni[TYPE_WIFI].isRoaming()); + assertNotNull(ni[TYPE_MOBILE].toString()); assertNotNull(ni[TYPE_WIFI].toString()); } diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java index 0e05b28119..196e102dee 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2009 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. @@ -18,19 +18,13 @@ package android.net.cts; import android.net.NetworkInfo.DetailedState; import android.test.AndroidTestCase; -import dalvik.annotation.TestTargets; -import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; @TestTargetClass(DetailedState.class) public class NetworkInfo_DetailedStateTest extends AndroidTestCase { - @Override - protected void setUp() throws Exception { - super.setUp(); - } - @TestTargetNew( level = TestLevel.COMPLETE, notes = "Test valueOf(String name).", @@ -38,23 +32,16 @@ public class NetworkInfo_DetailedStateTest extends AndroidTestCase { args = {java.lang.String.class} ) public void testValueOf() { - assertEquals(DetailedState.AUTHENTICATING, DetailedState - .valueOf("AUTHENTICATING")); - assertEquals(DetailedState.CONNECTED, DetailedState - .valueOf("CONNECTED")); - assertEquals(DetailedState.CONNECTING, DetailedState - .valueOf("CONNECTING")); - assertEquals(DetailedState.DISCONNECTED, DetailedState - .valueOf("DISCONNECTED")); - assertEquals(DetailedState.DISCONNECTING, DetailedState - .valueOf("DISCONNECTING")); + assertEquals(DetailedState.AUTHENTICATING, DetailedState.valueOf("AUTHENTICATING")); + assertEquals(DetailedState.CONNECTED, DetailedState.valueOf("CONNECTED")); + assertEquals(DetailedState.CONNECTING, DetailedState.valueOf("CONNECTING")); + assertEquals(DetailedState.DISCONNECTED, DetailedState.valueOf("DISCONNECTED")); + assertEquals(DetailedState.DISCONNECTING, DetailedState.valueOf("DISCONNECTING")); assertEquals(DetailedState.FAILED, DetailedState.valueOf("FAILED")); assertEquals(DetailedState.IDLE, DetailedState.valueOf("IDLE")); - assertEquals(DetailedState.OBTAINING_IPADDR, DetailedState - .valueOf("OBTAINING_IPADDR")); + assertEquals(DetailedState.OBTAINING_IPADDR, DetailedState.valueOf("OBTAINING_IPADDR")); assertEquals(DetailedState.SCANNING, DetailedState.valueOf("SCANNING")); - assertEquals(DetailedState.SUSPENDED, DetailedState - .valueOf("SUSPENDED")); + assertEquals(DetailedState.SUSPENDED, DetailedState.valueOf("SUSPENDED")); } @TestTargetNew( diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java index 249df4b588..1a51acd091 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2009 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. @@ -16,21 +16,15 @@ package android.net.cts; +import android.net.NetworkInfo.State; import android.test.AndroidTestCase; -import dalvik.annotation.TestTargets; -import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; -import android.net.NetworkInfo.State; +import dalvik.annotation.TestTargetNew; @TestTargetClass(State.class) public class NetworkInfo_StateTest extends AndroidTestCase { - @Override - protected void setUp() throws Exception { - super.setUp(); - } - @TestTargetNew( level = TestLevel.COMPLETE, notes = "Test valueOf(String name).", @@ -62,5 +56,4 @@ public class NetworkInfo_StateTest extends AndroidTestCase { assertEquals(State.DISCONNECTED, expected[4]); assertEquals(State.UNKNOWN, expected[5]); } - } diff --git a/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java b/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java index e9ae95c303..0dd5db1886 100644 --- a/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java +++ b/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java @@ -49,189 +49,168 @@ public class UrlQuerySanitizerTest extends AndroidTestCase { @TestTargets({ @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test constructor(s) of {@link UrlQuerySanitizer}", method = "UrlQuerySanitizer", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test constructor(s) of {@link UrlQuerySanitizer}", method = "UrlQuerySanitizer", args = {String.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: parseUrl", method = "parseUrl", args = {String.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: parseQuery", method = "parseQuery", args = {String.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: parseEntry", method = "parseEntry", args = {String.class, String.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: getValue", method = "getValue", args = {String.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: addSanitizedEntry", method = "addSanitizedEntry", args = {String.class, String.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: hasParameter", method = "hasParameter", args = {String.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: getParameterSet", method = "getParameterSet", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: getParameterList", method = "getParameterList", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: setUnregisteredParameterValueSanitizer", method = "setUnregisteredParameterValueSanitizer", args = {ValueSanitizer.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: getUnregisteredParameterValueSanitizer", method = "getUnregisteredParameterValueSanitizer", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: getAllButNulAndAngleBracketsLegal", method = "getAllButNulAndAngleBracketsLegal", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: getAllButNulLegal", method = "getAllButNulLegal", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: getAllButWhitespaceLegal", method = "getAllButWhitespaceLegal", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: getAllIllegal", method = "getAllIllegal", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: getAmpAndSpaceLegal", method = "getAmpAndSpaceLegal", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: getAmpLegal", method = "getAmpLegal", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: getSpaceLegal", method = "getSpaceLegal", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: getUrlAndSpaceLegal", method = "getUrlAndSpaceLegal", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: getUrlLegal", method = "getUrlLegal", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test mehtod: unescape", method = "unescape", args = {String.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test mehtod: isHexDigit", method = "isHexDigit", args = {char.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test mehtod: decodeHexDigit", method = "decodeHexDigit", args = {char.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: setAllowUnregisteredParamaters", method = "setAllowUnregisteredParamaters", args = {boolean.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: getAllowUnregisteredParamaters", method = "getAllowUnregisteredParamaters", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: registerParameter", method = "registerParameter", args = {String.class, ValueSanitizer.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: registerParameters", method = "registerParameters", args = {String[].class, ValueSanitizer.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: getEffectiveValueSanitizer", method = "getEffectiveValueSanitizer", args = {String.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: getValueSanitizer", method = "getValueSanitizer", args = {String.class} ), @TestTargetNew( level = TestLevel.COMPLETE, - notes = "Test method: clear", method = "clear", args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "setPreferFirstRepeatedParameter", + args = {boolean.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getPreferFirstRepeatedParameter", + args = {} ) }) public void testUrlQuerySanitizer() { @@ -377,6 +356,30 @@ public class UrlQuerySanitizerTest extends AndroidTestCase { uqs.clear(); assertEquals(0, urlSet.size()); assertEquals(0, urlList.size()); + + uqs.setPreferFirstRepeatedParameter(true); + assertTrue(uqs.getPreferFirstRepeatedParameter()); + uqs.setPreferFirstRepeatedParameter(false); + assertFalse(uqs.getPreferFirstRepeatedParameter()); + + UrlQuerySanitizer uq = new UrlQuerySanitizer(); + uq.setPreferFirstRepeatedParameter(true); + final String PARA_ANSWER = "answer"; + uq.registerParameter(PARA_ANSWER, new MockValueSanitizer()); + uq.parseUrl("http://www.google.com/question?answer=13&answer=42"); + assertEquals("13", uq.getValue(PARA_ANSWER)); + + uq.setPreferFirstRepeatedParameter(false); + uq.parseQuery("http://www.google.com/question?answer=13&answer=42"); + assertEquals("42", uq.getValue(PARA_ANSWER)); + + } + + private static class MockValueSanitizer implements ValueSanitizer{ + + public String sanitize(String value) { + return value; + } } class MockUrlQuerySanitizer extends UrlQuerySanitizer { From bda6b58510265c32453985bc49624786fca56e64 Mon Sep 17 00:00:00 2001 From: Brett Chabot Date: Thu, 13 Aug 2009 21:23:28 -0700 Subject: [PATCH 0032/1109] More CTS cleanup - Mark currently failing CTS tests as BrokenTests. - Fix race condition in LocationManagerTest - tweak host config to run tests in batch mode - fix genDefaultTestPlan and rename java package so permission2 tests get included properly, BUG 2053939 --- .../src/android/net/cts/SSLCertificateSocketFactoryTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java index b81dd37007..6cd5d6f10b 100644 --- a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java +++ b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java @@ -24,6 +24,8 @@ import javax.net.SocketFactory; import android.net.SSLCertificateSocketFactory; import android.test.AndroidTestCase; + +import dalvik.annotation.BrokenTest; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; import dalvik.annotation.TestTargetNew; @@ -99,6 +101,7 @@ public class SSLCertificateSocketFactoryTest extends AndroidTestCase { args = {int.class} ) }) + @BrokenTest("flaky") public void testCreateSocket() throws Exception { new SSLCertificateSocketFactory(100); int port = 443; From f4ffdb9732bd8640606fa96569eef09b535ae0be Mon Sep 17 00:00:00 2001 From: Brett Chabot Date: Thu, 13 Aug 2009 20:55:28 -0700 Subject: [PATCH 0033/1109] Remove a bunch of unused CTS tests from continuous test build to save space. BUG 2053298 --- tests/cts/net/Android.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index a2bbc9c316..26188afcfc 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -16,7 +16,7 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) -LOCAL_MODULE_TAGS := tests +LOCAL_MODULE_TAGS := optional LOCAL_JAVA_LIBRARIES := android.test.runner From 1505142f7b42e606562eeb51ed1879c70a67d150 Mon Sep 17 00:00:00 2001 From: Brett Chabot Date: Fri, 28 Aug 2009 12:22:23 -0700 Subject: [PATCH 0034/1109] Change CTS makefiles so apps are built in data not system partition. BUG 2053298 Change-Id: I2c541c03f7c33c69cde7b0567b080710658c8d28 --- tests/cts/net/Android.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index 26188afcfc..d23cee81cc 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -16,7 +16,10 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) +# don't include this package in any target LOCAL_MODULE_TAGS := optional +# and when built explicitly put it in the data partition +LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) LOCAL_JAVA_LIBRARIES := android.test.runner From dcccc5488842ec9fe70106d6bff616d04270656b Mon Sep 17 00:00:00 2001 From: Brett Chabot Date: Fri, 11 Sep 2009 15:26:23 -0700 Subject: [PATCH 0035/1109] Change CTS tests to not build against SDK. Most CTS test packages reference test related annotations in dalvik.annotation which are not part of SDK. This was previously allowed due to bug in build build system. For now, temporarily change CTS makefiles so they are not built against SDK. BUG 2114936 --- tests/cts/net/Android.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index d23cee81cc..1fd9ba0c40 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -29,7 +29,8 @@ LOCAL_PACKAGE_NAME := CtsNetTestCases LOCAL_INSTRUMENTATION_FOR := CtsTestStubs -LOCAL_SDK_VERSION := current +# uncomment when dalvik.annotation.Test* are removed or part of SDK +#LOCAL_SDK_VERSION := current include $(BUILD_PACKAGE) From 1bf60c89bbe02b33fd6977ec85eae2035e1aad37 Mon Sep 17 00:00:00 2001 From: Brett Chabot Date: Tue, 3 Nov 2009 15:57:26 -0800 Subject: [PATCH 0036/1109] Fix MailToTest. Changed the toString assertions to be parameter order independent. --- .../net/src/android/net/cts/MailToTest.java | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/MailToTest.java b/tests/cts/net/src/android/net/cts/MailToTest.java index e64aaf46e0..01ede1aea0 100644 --- a/tests/cts/net/src/android/net/cts/MailToTest.java +++ b/tests/cts/net/src/android/net/cts/MailToTest.java @@ -28,7 +28,7 @@ import dalvik.annotation.TestTargetClass; public class MailToTest extends AndroidTestCase { private static final String MAILTOURI_1 = "mailto:chris@example.com"; private static final String MAILTOURI_2 = "mailto:infobot@example.com?subject=current-issue"; - private static final String MAILTOURI_3 = + private static final String MAILTOURI_3 = "mailto:infobot@example.com?body=send%20current-issue"; private static final String MAILTOURI_4 = "mailto:infobot@example.com?body=send%20current-" + "issue%0D%0Asend%20index"; @@ -115,8 +115,10 @@ public class MailToTest extends AndroidTestCase { assertEquals("current-issue", mailTo_2.getSubject()); assertNull(mailTo_2.getBody()); assertNull(mailTo_2.getCc()); - assertEquals("mailto:?to=infobot%40example.com&subject=current-issue&", - mailTo_2.toString()); + String stringUrl = mailTo_2.toString(); + assertTrue(stringUrl.startsWith("mailto:?")); + assertTrue(stringUrl.contains("to=infobot%40example.com&")); + assertTrue(stringUrl.contains("subject=current-issue&")); assertTrue(MailTo.isMailTo(MAILTOURI_3)); MailTo mailTo_3 = MailTo.parse(MAILTOURI_3); @@ -126,8 +128,10 @@ public class MailToTest extends AndroidTestCase { assertEquals("send current-issue", mailTo_3.getBody()); assertNull(mailTo_3.getCc()); assertNull(mailTo_3.getSubject()); - assertEquals("mailto:?body=send%20current-issue&to=infobot%40example.com&", - mailTo_3.toString()); + stringUrl = mailTo_3.toString(); + assertTrue(stringUrl.startsWith("mailto:?")); + assertTrue(stringUrl.contains("to=infobot%40example.com&")); + assertTrue(stringUrl.contains("body=send%20current-issue&")); assertTrue(MailTo.isMailTo(MAILTOURI_4)); MailTo mailTo_4 = MailTo.parse(MAILTOURI_4); @@ -137,9 +141,11 @@ public class MailToTest extends AndroidTestCase { assertEquals("send current-issue\r\nsend index", mailTo_4.getBody()); assertNull(mailTo_4.getCc()); assertNull(mailTo_4.getSubject()); - assertEquals( - "mailto:?body=send%20current-issue%0D%0Asend%20index&to=infobot%40example.com&", - mailTo_4.toString()); + stringUrl = mailTo_4.toString(); + assertTrue(stringUrl.startsWith("mailto:?")); + assertTrue(stringUrl.contains("to=infobot%40example.com&")); + assertTrue(stringUrl.contains("body=send%20current-issue%0D%0Asend%20index&")); + assertTrue(MailTo.isMailTo(MAILTOURI_5)); MailTo mailTo_5 = MailTo.parse(MAILTOURI_5); @@ -150,8 +156,11 @@ public class MailToTest extends AndroidTestCase { assertEquals("bob@example.com", mailTo_5.getCc()); assertEquals("hello", mailTo_5.getBody()); assertNull(mailTo_5.getSubject()); - assertEquals("mailto:?cc=bob%40example.com&body=hello&to=joe%40example.com&", - mailTo_5.toString()); + stringUrl = mailTo_5.toString(); + assertTrue(stringUrl.startsWith("mailto:?")); + assertTrue(stringUrl.contains("cc=bob%40example.com&")); + assertTrue(stringUrl.contains("body=hello&")); + assertTrue(stringUrl.contains("to=joe%40example.com&")); assertTrue(MailTo.isMailTo(MAILTOURI_6)); MailTo mailTo_6 = MailTo.parse(MAILTOURI_6); @@ -162,7 +171,10 @@ public class MailToTest extends AndroidTestCase { assertEquals("bob@example.com", mailTo_6.getCc()); assertEquals("hello", mailTo_6.getBody()); assertNull(mailTo_6.getSubject()); - assertEquals("mailto:?cc=bob%40example.com&body=hello&to=%2C%20joe%40example.com&", - mailTo_6.toString()); + stringUrl = mailTo_6.toString(); + assertTrue(stringUrl.startsWith("mailto:?")); + assertTrue(stringUrl.contains("cc=bob%40example.com&")); + assertTrue(stringUrl.contains("body=hello&")); + assertTrue(stringUrl.contains("to=%2C%20joe%40example.com&")); } } From 7aa0090ef51543318399afa9a9a3d6065ae7cfdd Mon Sep 17 00:00:00 2001 From: Brett Chabot Date: Tue, 8 Dec 2009 19:52:35 -0800 Subject: [PATCH 0037/1109] Fix ConnectivityManagerTest testRequestRouteToHost and testGetAllNetworkInfo. Bugs 2138046 and 2138034. Change-Id: I2c3973be9166892caaf2deb07bc15344b897b552 --- .../android/net/cts/ConnectivityManagerTest.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index a8a149f250..edcea9a24e 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -36,6 +36,8 @@ public class ConnectivityManagerTest extends AndroidTestCase { public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI; private static final int HOST_ADDRESS = 0x7f000001;// represent ip 127.0.0.1 private ConnectivityManager mCm; + // must include both mobile data + wifi + private static final int MIN_NUM_NETWORK_TYPES = 2; @Override protected void setUp() throws Exception { @@ -51,7 +53,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { public void testGetNetworkInfo() { // this test assumes that there are at least two network types. - assertTrue(mCm.getAllNetworkInfo().length >= 2); + assertTrue(mCm.getAllNetworkInfo().length >= MIN_NUM_NETWORK_TYPES); NetworkInfo ni = mCm.getNetworkInfo(1); State state = ni.getState(); assertTrue(State.UNKNOWN.ordinal() >= state.ordinal() @@ -163,12 +165,8 @@ public class ConnectivityManagerTest extends AndroidTestCase { args = {} ) public void testGetAllNetworkInfo() { - NetworkInfo[] ni = mCm.getAllNetworkInfo(); - assertEquals(2, ni.length); - - assertTrue(ni[0].getType() >= 0 && ni[0].getType() <= 1); - assertTrue(ni[1].getType() >= 0 && ni[1].getType() <= 1); + assertTrue(ni.length >= MIN_NUM_NETWORK_TYPES); } @TestTargets({ @@ -206,7 +204,10 @@ public class ConnectivityManagerTest extends AndroidTestCase { NetworkInfo[] ni = mCm.getAllNetworkInfo(); for (NetworkInfo n : ni) { - assertTrue(mCm.requestRouteToHost(n.getType(), HOST_ADDRESS)); + // make sure network is up + if (n.isConnected()) { + assertTrue(mCm.requestRouteToHost(n.getType(), HOST_ADDRESS)); + } } assertFalse(mCm.requestRouteToHost(-1, HOST_ADDRESS)); From 16a5fa3ce2d3585d3f15b316e40262f3fa38f54f Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Mon, 11 Jan 2010 14:33:36 -0800 Subject: [PATCH 0038/1109] empty initial commit From 8c81965feba9036e62bac2c21ba19b902ac2e615 Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Tue, 12 Jan 2010 15:18:07 -0800 Subject: [PATCH 0039/1109] android-2.1_r1 snapshot --- tests/cts/net/Android.mk | 36 + tests/cts/net/AndroidManifest.xml | 30 + .../net/cts/ConnectivityManagerTest.java | 238 ++++++ .../src/android/net/cts/CredentialsTest.java | 71 ++ .../net/src/android/net/cts/DhcpInfoTest.java | 79 ++ .../net/cts/LocalServerSocketTest.java | 99 +++ .../net/cts/LocalSocketAddressTest.java | 78 ++ .../cts/LocalSocketAddress_NamespaceTest.java | 52 ++ .../src/android/net/cts/LocalSocketTest.java | 342 ++++++++ .../net/src/android/net/cts/MailToTest.java | 180 +++++ .../src/android/net/cts/NetworkInfoTest.java | 169 ++++ .../cts/NetworkInfo_DetailedStateTest.java | 68 ++ .../net/cts/NetworkInfo_StateTest.java | 59 ++ .../net/src/android/net/cts/ProxyTest.java | 91 +++ .../cts/SSLCertificateSocketFactoryTest.java | 144 ++++ .../cts/net/src/android/net/cts/UriTest.java | 727 ++++++++++++++++++ .../src/android/net/cts/Uri_BuilderTest.java | 173 +++++ .../net/cts/UrlQuerySanitizerTest.java | 419 ++++++++++ ...er_IllegalCharacterValueSanitizerTest.java | 48 ++ ...QuerySanitizer_ParameterValuePairTest.java | 43 ++ .../net/http/cts/SslCertificateTest.java | 303 ++++++++ .../http/cts/SslCertificate_DNameTest.java | 83 ++ .../android/net/wifi/cts/ScanResultTest.java | 126 +++ .../net/wifi/cts/SupplicantStateTest.java | 50 ++ .../net/wifi/cts/WifiConfigurationTest.java | 60 ++ .../android/net/wifi/cts/WifiInfoTest.java | 194 +++++ .../android/net/wifi/cts/WifiManagerTest.java | 427 ++++++++++ .../wifi/cts/WifiManager_WifiLockTest.java | 107 +++ 28 files changed, 4496 insertions(+) create mode 100644 tests/cts/net/Android.mk create mode 100644 tests/cts/net/AndroidManifest.xml create mode 100644 tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java create mode 100644 tests/cts/net/src/android/net/cts/CredentialsTest.java create mode 100644 tests/cts/net/src/android/net/cts/DhcpInfoTest.java create mode 100644 tests/cts/net/src/android/net/cts/LocalServerSocketTest.java create mode 100644 tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java create mode 100644 tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java create mode 100644 tests/cts/net/src/android/net/cts/LocalSocketTest.java create mode 100644 tests/cts/net/src/android/net/cts/MailToTest.java create mode 100644 tests/cts/net/src/android/net/cts/NetworkInfoTest.java create mode 100644 tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java create mode 100644 tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java create mode 100644 tests/cts/net/src/android/net/cts/ProxyTest.java create mode 100644 tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java create mode 100644 tests/cts/net/src/android/net/cts/UriTest.java create mode 100644 tests/cts/net/src/android/net/cts/Uri_BuilderTest.java create mode 100644 tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java create mode 100644 tests/cts/net/src/android/net/cts/UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java create mode 100644 tests/cts/net/src/android/net/cts/UrlQuerySanitizer_ParameterValuePairTest.java create mode 100644 tests/cts/net/src/android/net/http/cts/SslCertificateTest.java create mode 100644 tests/cts/net/src/android/net/http/cts/SslCertificate_DNameTest.java create mode 100644 tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java create mode 100644 tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java create mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java create mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java create mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java create mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk new file mode 100644 index 0000000000..1fd9ba0c40 --- /dev/null +++ b/tests/cts/net/Android.mk @@ -0,0 +1,36 @@ +# Copyright (C) 2008 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. + +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +# don't include this package in any target +LOCAL_MODULE_TAGS := optional +# and when built explicitly put it in the data partition +LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) + +LOCAL_JAVA_LIBRARIES := android.test.runner + +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_PACKAGE_NAME := CtsNetTestCases + +LOCAL_INSTRUMENTATION_FOR := CtsTestStubs + +# uncomment when dalvik.annotation.Test* are removed or part of SDK +#LOCAL_SDK_VERSION := current + +include $(BUILD_PACKAGE) + diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml new file mode 100644 index 0000000000..a1f632effb --- /dev/null +++ b/tests/cts/net/AndroidManifest.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java new file mode 100644 index 0000000000..edcea9a24e --- /dev/null +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2009 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 dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; +import dalvik.annotation.ToBeFixed; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.net.NetworkInfo.DetailedState; +import android.net.NetworkInfo.State; +import android.test.AndroidTestCase; + +@TestTargetClass(ConnectivityManager.class) +public class ConnectivityManagerTest extends AndroidTestCase { + + public static final int TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE; + public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI; + private static final int HOST_ADDRESS = 0x7f000001;// represent ip 127.0.0.1 + private ConnectivityManager mCm; + // must include both mobile data + wifi + private static final int MIN_NUM_NETWORK_TYPES = 2; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); + } + + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getNetworkInfo", + args = {int.class} + ) + public void testGetNetworkInfo() { + + // this test assumes that there are at least two network types. + assertTrue(mCm.getAllNetworkInfo().length >= MIN_NUM_NETWORK_TYPES); + NetworkInfo ni = mCm.getNetworkInfo(1); + State state = ni.getState(); + assertTrue(State.UNKNOWN.ordinal() >= state.ordinal() + && state.ordinal() >= State.CONNECTING.ordinal()); + DetailedState ds = ni.getDetailedState(); + assertTrue(DetailedState.FAILED.ordinal() >= ds.ordinal() + && ds.ordinal() >= DetailedState.IDLE.ordinal()); + + ni = mCm.getNetworkInfo(0); + state = ni.getState(); + assertTrue(State.UNKNOWN.ordinal() >= state.ordinal() + && state.ordinal() >= State.CONNECTING.ordinal()); + ds = ni.getDetailedState(); + assertTrue(DetailedState.FAILED.ordinal() >= ds.ordinal() + && ds.ordinal() >= DetailedState.IDLE.ordinal()); + + ni = mCm.getNetworkInfo(-1); + assertNull(ni); + + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "isNetworkTypeValid", + args = {int.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getAllNetworkInfo", + args = {} + ) + }) + public void testIsNetworkTypeValid() { + + NetworkInfo[] ni = mCm.getAllNetworkInfo(); + + for (NetworkInfo n : ni) { + assertTrue(ConnectivityManager.isNetworkTypeValid(n.getType())); + } + assertFalse(ConnectivityManager.isNetworkTypeValid(-1)); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getNetworkPreference", + args = {} + ), + @TestTargetNew( + level = TestLevel.SUFFICIENT, + method = "setNetworkPreference", + args = {int.class} + ) + }) + public void testAccessNetworkPreference() { + int initialSetting = mCm.getNetworkPreference(); + + // Changing the network preference requires android.permission.WRITE_SECURE_SETTINGS, + // which is only available to signed or system applications. + + // Setting the same preference that is already set is a no-op and does not throw + // a SecurityException. + mCm.setNetworkPreference(initialSetting); + assertEquals(initialSetting, mCm.getNetworkPreference()); + + // find a valid setting that is different from the initial setting + int validSetting = -1; + NetworkInfo[] ni = mCm.getAllNetworkInfo(); + for (NetworkInfo n : ni) { + int type = n.getType(); + if (type != initialSetting) { + validSetting = type; + break; + } + } + if (validSetting >= 0) { + try { + mCm.setNetworkPreference(validSetting); + fail("Trying to change the network preference should throw SecurityException"); + } catch (SecurityException expected) { + // expected + } + } + + // find an invalid setting + int invalidSetting = -1; + for (int i = 0; i < 10; i++) { + if (!ConnectivityManager.isNetworkTypeValid(i)) { + invalidSetting = i; + break; + } + } + if (invalidSetting >= 0) { + // illegal setting should be ignored + mCm.setNetworkPreference(invalidSetting); + assertEquals(initialSetting, mCm.getNetworkPreference()); + } + + // illegal setting should be ignored + mCm.setNetworkPreference(-1); + assertEquals(initialSetting, mCm.getNetworkPreference()); + } + + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test getAllNetworkInfo().", + method = "getAllNetworkInfo", + args = {} + ) + public void testGetAllNetworkInfo() { + NetworkInfo[] ni = mCm.getAllNetworkInfo(); + assertTrue(ni.length >= MIN_NUM_NETWORK_TYPES); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "startUsingNetworkFeature", + args = {int.class, java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "stopUsingNetworkFeature", + args = {int.class, java.lang.String.class} + ) + }) + public void testStartUsingNetworkFeature() { + + final String invalidateFeature = "invalidateFeature"; + final String mmsFeature = "enableMMS"; + final int failureCode = -1; + + assertEquals(failureCode, mCm.startUsingNetworkFeature(TYPE_MOBILE, invalidateFeature)); + assertEquals(failureCode, mCm.stopUsingNetworkFeature(TYPE_MOBILE, invalidateFeature)); + + // Should return failure(-1) because MMS is not supported on WIFI. + assertEquals(failureCode, mCm.startUsingNetworkFeature(TYPE_WIFI, mmsFeature)); + assertEquals(failureCode, mCm.stopUsingNetworkFeature(TYPE_WIFI, mmsFeature)); + } + + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "requestRouteToHost", + args = {int.class, int.class} + ) + public void testRequestRouteToHost() { + + NetworkInfo[] ni = mCm.getAllNetworkInfo(); + for (NetworkInfo n : ni) { + // make sure network is up + if (n.isConnected()) { + assertTrue(mCm.requestRouteToHost(n.getType(), HOST_ADDRESS)); + } + } + + assertFalse(mCm.requestRouteToHost(-1, HOST_ADDRESS)); + } + + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getActiveNetworkInfo", + args = {} + ) + @ToBeFixed(bug="1695243", explanation="No Javadoc") + public void testGetActiveNetworkInfo() { + NetworkInfo ni = mCm.getActiveNetworkInfo(); + + if (ni != null) { + assertTrue(ni.getType() >= 0); + } + } + + @TestTargetNew( + level = TestLevel.SUFFICIENT, + method = "getBackgroundDataSetting", + args = {} + ) + public void testTest() { + mCm.getBackgroundDataSetting(); + } +} diff --git a/tests/cts/net/src/android/net/cts/CredentialsTest.java b/tests/cts/net/src/android/net/cts/CredentialsTest.java new file mode 100644 index 0000000000..6cf8c2351e --- /dev/null +++ b/tests/cts/net/src/android/net/cts/CredentialsTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2008 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.net.Credentials; +import android.test.AndroidTestCase; +import dalvik.annotation.TestTargets; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargetClass; + +@TestTargetClass(android.net.Credentials.class) +public class CredentialsTest extends AndroidTestCase { + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "Credentials", + args = {int.class, int.class, int.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getGid", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getPid", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getUid", + args = {} + ) + }) + public void testCredentials() { + // new the Credentials instance + // Test with zero inputs + Credentials cred = new Credentials(0, 0, 0); + assertEquals(0, cred.getGid()); + assertEquals(0, cred.getPid()); + assertEquals(0, cred.getUid()); + + // Test with big integer + cred = new Credentials(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE); + assertEquals(Integer.MAX_VALUE, cred.getGid()); + assertEquals(Integer.MAX_VALUE, cred.getPid()); + assertEquals(Integer.MAX_VALUE, cred.getUid()); + + // Test with big negative integer + cred = new Credentials(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE); + assertEquals(Integer.MIN_VALUE, cred.getGid()); + assertEquals(Integer.MIN_VALUE, cred.getPid()); + assertEquals(Integer.MIN_VALUE, cred.getUid()); + } +} diff --git a/tests/cts/net/src/android/net/cts/DhcpInfoTest.java b/tests/cts/net/src/android/net/cts/DhcpInfoTest.java new file mode 100644 index 0000000000..97bd27a970 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/DhcpInfoTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2009 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.net.DhcpInfo; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; + +@TestTargetClass(DhcpInfo.class) +public class DhcpInfoTest extends AndroidTestCase { + + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test DhcpInfo's constructor.", + method = "DhcpInfo", + args = {} + ) + public void testConstructor() { + new DhcpInfo(); + } + + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test toString function.", + method = "toString", + args = {} + ) + public void testToString() { + String expectedDefault = "ipaddr 0.0.0.0 gateway 0.0.0.0 netmask 0.0.0.0 dns1 0.0.0.0 " + + "dns2 0.0.0.0 DHCP server 0.0.0.0 lease 0 seconds"; + String STR_ADDR1 = "255.255.255.255"; + String STR_ADDR2 = "127.0.0.1"; + String STR_ADDR3 = "192.168.1.1"; + String STR_ADDR4 = "192.168.1.0"; + int leaseTime = 9999; + String expected = "ipaddr " + STR_ADDR1 + " gateway " + STR_ADDR2 + " netmask " + + STR_ADDR3 + " dns1 " + STR_ADDR4 + " dns2 " + STR_ADDR4 + " DHCP server " + + STR_ADDR2 + " lease " + leaseTime + " seconds"; + + DhcpInfo dhcpInfo = new DhcpInfo(); + + // Test default string. + assertEquals(expectedDefault, dhcpInfo.toString()); + + dhcpInfo.ipAddress = ipToInteger(STR_ADDR1); + dhcpInfo.gateway = ipToInteger(STR_ADDR2); + dhcpInfo.netmask = ipToInteger(STR_ADDR3); + dhcpInfo.dns1 = ipToInteger(STR_ADDR4); + dhcpInfo.dns2 = ipToInteger(STR_ADDR4); + dhcpInfo.serverAddress = ipToInteger(STR_ADDR2); + dhcpInfo.leaseDuration = leaseTime; + + // Test with new values + assertEquals(expected, dhcpInfo.toString()); + } + + private int ipToInteger(String ipString) { + String ipSegs[] = ipString.split("[.]"); + int tmp = Integer.parseInt(ipSegs[3]) << 24 | Integer.parseInt(ipSegs[2]) << 16 | + Integer.parseInt(ipSegs[1]) << 8 | Integer.parseInt(ipSegs[0]); + return tmp; + } +} diff --git a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java new file mode 100644 index 0000000000..21c7d5e299 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2009 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 java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import android.net.LocalServerSocket; +import android.net.LocalSocket; +import android.net.LocalSocketAddress; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; +import dalvik.annotation.ToBeFixed; + +@TestTargetClass(LocalServerSocket.class) +public class LocalServerSocketTest extends AndroidTestCase { + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "accept", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "close", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getFileDescriptor", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getLocalSocketAddress", + args = {} + ), + @TestTargetNew( + level = TestLevel.NOT_FEASIBLE, + method = "LocalServerSocket", + args = {java.io.FileDescriptor.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "LocalServerSocket", + args = {java.lang.String.class} + ) + }) + @ToBeFixed(bug = "1520987", explanation = "Cannot find a proper FileDescriptor for " + + "android.net.LocalServerSocket constructor") + public void testLocalServerSocket() throws IOException { + LocalServerSocket localServerSocket = new LocalServerSocket(LocalSocketTest.mSockAddr); + assertNotNull(localServerSocket.getLocalSocketAddress()); + commonFunctions(localServerSocket); + } + + public void commonFunctions(LocalServerSocket localServerSocket) throws IOException { + // create client socket + LocalSocket clientSocket = new LocalSocket(); + + // establish connection between client and server + clientSocket.connect(new LocalSocketAddress(LocalSocketTest.mSockAddr)); + LocalSocket serverSocket = localServerSocket.accept(); + + // send data from client to server + OutputStream clientOutStream = clientSocket.getOutputStream(); + clientOutStream.write(12); + InputStream serverInStream = serverSocket.getInputStream(); + assertEquals(12, serverInStream.read()); + + // send data from server to client + OutputStream serverOutStream = serverSocket.getOutputStream(); + serverOutStream.write(3); + InputStream clientInStream = clientSocket.getInputStream(); + assertEquals(3, clientInStream.read()); + + // close server socket + assertNotNull(localServerSocket.getFileDescriptor()); + localServerSocket.close(); + assertNull(localServerSocket.getFileDescriptor()); + } +} diff --git a/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java b/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java new file mode 100644 index 0000000000..e3141d57e5 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2008 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.net.LocalSocketAddress; +import android.net.LocalSocketAddress.Namespace; +import android.test.AndroidTestCase; +import dalvik.annotation.TestTargets; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargetClass; + +@TestTargetClass(LocalSocketAddress.class) +public class LocalSocketAddressTest extends AndroidTestCase { + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test LocalSocketAddress", + method = "LocalSocketAddress", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test LocalSocketAddress", + method = "LocalSocketAddress", + args = {java.lang.String.class, android.net.LocalSocketAddress.Namespace.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test LocalSocketAddress", + method = "getName", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test LocalSocketAddress", + method = "getNamespace", + args = {} + ) + }) + public void testNewLocalSocketAddressWithDefaultNamespace() { + // default namespace + LocalSocketAddress localSocketAddress = new LocalSocketAddress("name"); + assertEquals("name", localSocketAddress.getName()); + assertEquals(Namespace.ABSTRACT, localSocketAddress.getNamespace()); + + // specify the namespace + LocalSocketAddress localSocketAddress2 = + new LocalSocketAddress("name2", Namespace.ABSTRACT); + assertEquals("name2", localSocketAddress2.getName()); + assertEquals(Namespace.ABSTRACT, localSocketAddress2.getNamespace()); + + LocalSocketAddress localSocketAddress3 = + new LocalSocketAddress("name3", Namespace.FILESYSTEM); + assertEquals("name3", localSocketAddress3.getName()); + assertEquals(Namespace.FILESYSTEM, localSocketAddress3.getNamespace()); + + LocalSocketAddress localSocketAddress4 = + new LocalSocketAddress("name4", Namespace.RESERVED); + assertEquals("name4", localSocketAddress4.getName()); + assertEquals(Namespace.RESERVED, localSocketAddress4.getNamespace()); + } +} diff --git a/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java b/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java new file mode 100644 index 0000000000..fc9de5b14c --- /dev/null +++ b/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2009 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.net.LocalSocketAddress.Namespace; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; + +@TestTargetClass(Namespace.class) +public class LocalSocketAddress_NamespaceTest extends AndroidTestCase { + + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test valueOf(String name).", + method = "valueOf", + args = {java.lang.String.class} + ) + public void testValueOf() { + assertEquals(Namespace.ABSTRACT, Namespace.valueOf("ABSTRACT")); + assertEquals(Namespace.RESERVED, Namespace.valueOf("RESERVED")); + assertEquals(Namespace.FILESYSTEM, Namespace.valueOf("FILESYSTEM")); + } + + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test values().", + method = "values", + args = {} + ) + public void testValues() { + Namespace[] expected = Namespace.values(); + assertEquals(Namespace.ABSTRACT, expected[0]); + assertEquals(Namespace.RESERVED, expected[1]); + assertEquals(Namespace.FILESYSTEM, expected[2]); + } +} diff --git a/tests/cts/net/src/android/net/cts/LocalSocketTest.java b/tests/cts/net/src/android/net/cts/LocalSocketTest.java new file mode 100644 index 0000000000..8e3cd6714b --- /dev/null +++ b/tests/cts/net/src/android/net/cts/LocalSocketTest.java @@ -0,0 +1,342 @@ +/* + * Copyright (C) 2008 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 java.io.FileDescriptor; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import android.net.Credentials; +import android.net.LocalServerSocket; +import android.net.LocalSocket; +import android.net.LocalSocketAddress; +import android.test.AndroidTestCase; +import dalvik.annotation.TestTargets; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargetClass; + +@TestTargetClass(LocalSocket.class) +public class LocalSocketTest extends AndroidTestCase{ + public final static String mSockAddr = "com.android.net.LocalSocketTest"; + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test core functions of LocalSocket", + method = "LocalSocket", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test core functions of LocalSocket", + method = "close", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test core functions of LocalSocket", + method = "connect", + args = {android.net.LocalSocketAddress.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test core functions of LocalSocket", + method = "getAncillaryFileDescriptors", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test core functions of LocalSocket", + method = "getFileDescriptor", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test core functions of LocalSocket", + method = "getInputStream", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test core functions of LocalSocket", + method = "getOutputStream", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test core functions of LocalSocket", + method = "getPeerCredentials", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test core functions of LocalSocket", + method = "isConnected", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test core functions of LocalSocket", + method = "setFileDescriptorsForSend", + args = {java.io.FileDescriptor[].class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test core functions of LocalSocket", + method = "shutdownInput", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test core functions of LocalSocket", + method = "shutdownOutput", + args = {} + ) + }) + public void testLocalConnections() throws IOException{ + // create client and server socket + LocalServerSocket localServerSocket = new LocalServerSocket(mSockAddr); + LocalSocket clientSocket = new LocalSocket(); + + // establish connection between client and server + LocalSocketAddress locSockAddr = new LocalSocketAddress(mSockAddr); + assertFalse(clientSocket.isConnected()); + clientSocket.connect(locSockAddr); + assertTrue(clientSocket.isConnected()); + LocalSocket serverSocket = localServerSocket.accept(); + + Credentials credent = clientSocket.getPeerCredentials(); + assertTrue(0 != credent.getPid()); + + // send data from client to server + OutputStream clientOutStream = clientSocket.getOutputStream(); + clientOutStream.write(12); + InputStream serverInStream = serverSocket.getInputStream(); + assertEquals(12, serverInStream.read()); + + //send data from server to client + OutputStream serverOutStream = serverSocket.getOutputStream(); + serverOutStream.write(3); + InputStream clientInStream = clientSocket.getInputStream(); + assertEquals(3, clientInStream.read()); + + // Test sending and receiving file descriptors + clientSocket.setFileDescriptorsForSend(new FileDescriptor[]{FileDescriptor.in}); + clientOutStream.write(32); + assertEquals(32, serverInStream.read()); + + FileDescriptor[] out = serverSocket.getAncillaryFileDescriptors(); + assertEquals(1, out.length); + FileDescriptor fd = clientSocket.getFileDescriptor(); + assertTrue(fd.valid()); + + //shutdown input stream of client + clientSocket.shutdownInput(); + assertEquals(-1, clientInStream.read()); + + //shutdown output stream of client + clientSocket.shutdownOutput(); + try { + clientOutStream.write(10); + fail("testLocalSocket shouldn't come to here"); + } catch (IOException e) { + // expected + } + + //shutdown input stream of server + serverSocket.shutdownInput(); + assertEquals(-1, serverInStream.read()); + + //shutdown output stream of server + serverSocket.shutdownOutput(); + try { + serverOutStream.write(10); + fail("testLocalSocket shouldn't come to here"); + } catch (IOException e) { + // expected + } + + //close client socket + clientSocket.close(); + try { + clientInStream.read(); + fail("testLocalSocket shouldn't come to here"); + } catch (IOException e) { + // expected + } + + //close server socket + serverSocket.close(); + try { + serverInStream.read(); + fail("testLocalSocket shouldn't come to here"); + } catch (IOException e) { + // expected + } + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test secondary functions of LocalSocket", + method = "bind", + args = {android.net.LocalSocketAddress.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test secondary functions of LocalSocket", + method = "connect", + args = {android.net.LocalSocketAddress.class, int.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test secondary functions of LocalSocket", + method = "getLocalSocketAddress", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test secondary functions of LocalSocket", + method = "getReceiveBufferSize", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test secondary functions of LocalSocket", + method = "getRemoteSocketAddress", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test secondary functions of LocalSocket", + method = "getSendBufferSize", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test secondary functions of LocalSocket", + method = "getSoTimeout", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test secondary functions of LocalSocket", + method = "isBound", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test secondary functions of LocalSocket", + method = "isClosed", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test secondary functions of LocalSocket", + method = "isInputShutdown", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test secondary functions of LocalSocket", + method = "isOutputShutdown", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test secondary functions of LocalSocket", + method = "setReceiveBufferSize", + args = {int.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test secondary functions of LocalSocket", + method = "setSendBufferSize", + args = {int.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test secondary functions of LocalSocket", + method = "setSoTimeout", + args = {int.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "test secondary functions of LocalSocket", + method = "toString", + args = {} + ) + }) + public void testAccessors() throws IOException{ + LocalSocket socket = new LocalSocket(); + LocalSocketAddress addr = new LocalSocketAddress("secondary"); + + assertFalse(socket.isBound()); + socket.bind(addr); + assertTrue(socket.isBound()); + assertEquals(addr, socket.getLocalSocketAddress()); + + String str = socket.toString(); + assertTrue(str.contains("impl:android.net.LocalSocketImpl")); + + socket.setReceiveBufferSize(1999); + assertEquals(1999 << 1, socket.getReceiveBufferSize()); + + socket.setSendBufferSize(1998); + assertEquals(1998 << 1, socket.getSendBufferSize()); + + // Timeout is not support at present, so set is ignored + socket.setSoTimeout(1996); + assertEquals(0, socket.getSoTimeout()); + + try { + socket.getRemoteSocketAddress(); + fail("testLocalSocketSecondary shouldn't come to here"); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + socket.isClosed(); + fail("testLocalSocketSecondary shouldn't come to here"); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + socket.isInputShutdown(); + fail("testLocalSocketSecondary shouldn't come to here"); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + socket.isOutputShutdown(); + fail("testLocalSocketSecondary shouldn't come to here"); + } catch (UnsupportedOperationException e) { + // expected + } + + try { + socket.connect(addr, 2005); + fail("testLocalSocketSecondary shouldn't come to here"); + } catch (UnsupportedOperationException e) { + // expected + } + } +} diff --git a/tests/cts/net/src/android/net/cts/MailToTest.java b/tests/cts/net/src/android/net/cts/MailToTest.java new file mode 100644 index 0000000000..01ede1aea0 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/MailToTest.java @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2008 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.net.MailTo; +import android.test.AndroidTestCase; +import android.util.Log; +import dalvik.annotation.TestTargets; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargetClass; + +@TestTargetClass(MailTo.class) +public class MailToTest extends AndroidTestCase { + private static final String MAILTOURI_1 = "mailto:chris@example.com"; + private static final String MAILTOURI_2 = "mailto:infobot@example.com?subject=current-issue"; + private static final String MAILTOURI_3 = + "mailto:infobot@example.com?body=send%20current-issue"; + private static final String MAILTOURI_4 = "mailto:infobot@example.com?body=send%20current-" + + "issue%0D%0Asend%20index"; + private static final String MAILTOURI_5 = "mailto:joe@example.com?" + + "cc=bob@example.com&body=hello"; + private static final String MAILTOURI_6 = "mailto:?to=joe@example.com&" + + "cc=bob@example.com&body=hello"; + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test parse mailto URI.", + method = "parse", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test parse mailto URI.", + method = "isMailTo", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test parse mailto URI.", + method = "getTo", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test parse mailto URI.", + method = "getSubject", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test parse mailto URI.", + method = "getBody", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test parse mailto URI.", + method = "getCc", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test parse mailto URI.", + method = "toString", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test parse mailto URI.", + method = "getHeaders", + args = {} + ) + }) + public void testParseMailToURI() { + assertFalse(MailTo.isMailTo(null)); + assertFalse(MailTo.isMailTo("")); + assertFalse(MailTo.isMailTo("http://www.google.com")); + + assertTrue(MailTo.isMailTo(MAILTOURI_1)); + MailTo mailTo_1 = MailTo.parse(MAILTOURI_1); + Log.d("Trace", mailTo_1.toString()); + assertEquals("chris@example.com", mailTo_1.getTo()); + assertEquals(1, mailTo_1.getHeaders().size()); + assertNull(mailTo_1.getBody()); + assertNull(mailTo_1.getCc()); + assertNull(mailTo_1.getSubject()); + assertEquals("mailto:?to=chris%40example.com&", mailTo_1.toString()); + + assertTrue(MailTo.isMailTo(MAILTOURI_2)); + MailTo mailTo_2 = MailTo.parse(MAILTOURI_2); + Log.d("Trace", mailTo_2.toString()); + assertEquals(2, mailTo_2.getHeaders().size()); + assertEquals("infobot@example.com", mailTo_2.getTo()); + assertEquals("current-issue", mailTo_2.getSubject()); + assertNull(mailTo_2.getBody()); + assertNull(mailTo_2.getCc()); + String stringUrl = mailTo_2.toString(); + assertTrue(stringUrl.startsWith("mailto:?")); + assertTrue(stringUrl.contains("to=infobot%40example.com&")); + assertTrue(stringUrl.contains("subject=current-issue&")); + + assertTrue(MailTo.isMailTo(MAILTOURI_3)); + MailTo mailTo_3 = MailTo.parse(MAILTOURI_3); + Log.d("Trace", mailTo_3.toString()); + assertEquals(2, mailTo_3.getHeaders().size()); + assertEquals("infobot@example.com", mailTo_3.getTo()); + assertEquals("send current-issue", mailTo_3.getBody()); + assertNull(mailTo_3.getCc()); + assertNull(mailTo_3.getSubject()); + stringUrl = mailTo_3.toString(); + assertTrue(stringUrl.startsWith("mailto:?")); + assertTrue(stringUrl.contains("to=infobot%40example.com&")); + assertTrue(stringUrl.contains("body=send%20current-issue&")); + + assertTrue(MailTo.isMailTo(MAILTOURI_4)); + MailTo mailTo_4 = MailTo.parse(MAILTOURI_4); + Log.d("Trace", mailTo_4.toString() + " " + mailTo_4.getBody()); + assertEquals(2, mailTo_4.getHeaders().size()); + assertEquals("infobot@example.com", mailTo_4.getTo()); + assertEquals("send current-issue\r\nsend index", mailTo_4.getBody()); + assertNull(mailTo_4.getCc()); + assertNull(mailTo_4.getSubject()); + stringUrl = mailTo_4.toString(); + assertTrue(stringUrl.startsWith("mailto:?")); + assertTrue(stringUrl.contains("to=infobot%40example.com&")); + assertTrue(stringUrl.contains("body=send%20current-issue%0D%0Asend%20index&")); + + + assertTrue(MailTo.isMailTo(MAILTOURI_5)); + MailTo mailTo_5 = MailTo.parse(MAILTOURI_5); + Log.d("Trace", mailTo_5.toString() + mailTo_5.getHeaders().toString() + + mailTo_5.getHeaders().size()); + assertEquals(3, mailTo_5.getHeaders().size()); + assertEquals("joe@example.com", mailTo_5.getTo()); + assertEquals("bob@example.com", mailTo_5.getCc()); + assertEquals("hello", mailTo_5.getBody()); + assertNull(mailTo_5.getSubject()); + stringUrl = mailTo_5.toString(); + assertTrue(stringUrl.startsWith("mailto:?")); + assertTrue(stringUrl.contains("cc=bob%40example.com&")); + assertTrue(stringUrl.contains("body=hello&")); + assertTrue(stringUrl.contains("to=joe%40example.com&")); + + assertTrue(MailTo.isMailTo(MAILTOURI_6)); + MailTo mailTo_6 = MailTo.parse(MAILTOURI_6); + Log.d("Trace", mailTo_6.toString() + mailTo_6.getHeaders().toString() + + mailTo_6.getHeaders().size()); + assertEquals(3, mailTo_6.getHeaders().size()); + assertEquals(", joe@example.com", mailTo_6.getTo()); + assertEquals("bob@example.com", mailTo_6.getCc()); + assertEquals("hello", mailTo_6.getBody()); + assertNull(mailTo_6.getSubject()); + stringUrl = mailTo_6.toString(); + assertTrue(stringUrl.startsWith("mailto:?")); + assertTrue(stringUrl.contains("cc=bob%40example.com&")); + assertTrue(stringUrl.contains("body=hello&")); + assertTrue(stringUrl.contains("to=%2C%20joe%40example.com&")); + } +} diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java new file mode 100644 index 0000000000..d2de4e4be2 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2009 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.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.net.NetworkInfo.DetailedState; +import android.net.NetworkInfo.State; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; + +@TestTargetClass(NetworkInfo.class) +public class NetworkInfoTest extends AndroidTestCase { + + public static final int TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE; + public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI; + public static final String MOBILE_TYPE_NAME = "MOBILE"; + public static final String WIFI_TYPE_NAME = "WIFI"; + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "isConnectedOrConnecting", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "setFailover", + args = {boolean.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "isFailover", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "isRoaming", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getType", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getSubtype", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getTypeName", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getSubtypeName", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "setIsAvailable", + args = {boolean.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "isAvailable", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "isConnected", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getDetailedState", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getState", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getReason", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getExtraInfo", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "toString", + args = {} + ) + }) + public void testAccessNetworkInfoProperties() { + ConnectivityManager cm = (ConnectivityManager) getContext().getSystemService( + Context.CONNECTIVITY_SERVICE); + + NetworkInfo[] ni = cm.getAllNetworkInfo(); + assertTrue(ni.length >= 2); + + assertFalse(ni[TYPE_MOBILE].isFailover()); + assertFalse(ni[TYPE_WIFI].isFailover()); + + // test environment:connect as TYPE_MOBILE, and connect to internet. + assertEquals(TYPE_MOBILE, ni[TYPE_MOBILE].getType()); + assertEquals(TYPE_WIFI, ni[TYPE_WIFI].getType()); + + // don't know the return value + ni[TYPE_MOBILE].getSubtype(); + ni[TYPE_WIFI].getSubtype(); + + assertEquals(MOBILE_TYPE_NAME, ni[TYPE_MOBILE].getTypeName()); + assertEquals(WIFI_TYPE_NAME, ni[TYPE_WIFI].getTypeName()); + + // don't know the return value + ni[TYPE_MOBILE].getSubtypeName(); + ni[TYPE_WIFI].getSubtypeName(); + + if(ni[TYPE_MOBILE].isConnectedOrConnecting()) { + assertTrue(ni[TYPE_MOBILE].isAvailable()); + assertTrue(ni[TYPE_MOBILE].isConnected()); + assertEquals(State.CONNECTED, ni[TYPE_MOBILE].getState()); + assertEquals(DetailedState.CONNECTED, ni[TYPE_MOBILE].getDetailedState()); + ni[TYPE_MOBILE].getReason(); + ni[TYPE_MOBILE].getExtraInfo(); + } + + if(ni[TYPE_WIFI].isConnectedOrConnecting()) { + assertTrue(ni[TYPE_WIFI].isAvailable()); + assertTrue(ni[TYPE_WIFI].isConnected()); + assertEquals(State.CONNECTED, ni[TYPE_WIFI].getState()); + assertEquals(DetailedState.CONNECTED, ni[TYPE_WIFI].getDetailedState()); + ni[TYPE_WIFI].getReason(); + ni[TYPE_WIFI].getExtraInfo(); + } + + assertFalse(ni[TYPE_MOBILE].isRoaming()); + assertFalse(ni[TYPE_WIFI].isRoaming()); + + assertNotNull(ni[TYPE_MOBILE].toString()); + assertNotNull(ni[TYPE_WIFI].toString()); + } +} diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java new file mode 100644 index 0000000000..196e102dee --- /dev/null +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2009 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.net.NetworkInfo.DetailedState; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; + +@TestTargetClass(DetailedState.class) +public class NetworkInfo_DetailedStateTest extends AndroidTestCase { + + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test valueOf(String name).", + method = "valueOf", + args = {java.lang.String.class} + ) + public void testValueOf() { + assertEquals(DetailedState.AUTHENTICATING, DetailedState.valueOf("AUTHENTICATING")); + assertEquals(DetailedState.CONNECTED, DetailedState.valueOf("CONNECTED")); + assertEquals(DetailedState.CONNECTING, DetailedState.valueOf("CONNECTING")); + assertEquals(DetailedState.DISCONNECTED, DetailedState.valueOf("DISCONNECTED")); + assertEquals(DetailedState.DISCONNECTING, DetailedState.valueOf("DISCONNECTING")); + assertEquals(DetailedState.FAILED, DetailedState.valueOf("FAILED")); + assertEquals(DetailedState.IDLE, DetailedState.valueOf("IDLE")); + assertEquals(DetailedState.OBTAINING_IPADDR, DetailedState.valueOf("OBTAINING_IPADDR")); + assertEquals(DetailedState.SCANNING, DetailedState.valueOf("SCANNING")); + assertEquals(DetailedState.SUSPENDED, DetailedState.valueOf("SUSPENDED")); + } + + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test values().", + method = "values", + args = {} + ) + public void testValues() { + DetailedState[] expected = DetailedState.values(); + assertEquals(10, expected.length); + assertEquals(DetailedState.IDLE, expected[0]); + assertEquals(DetailedState.SCANNING, expected[1]); + assertEquals(DetailedState.CONNECTING, expected[2]); + assertEquals(DetailedState.AUTHENTICATING, expected[3]); + assertEquals(DetailedState.OBTAINING_IPADDR, expected[4]); + assertEquals(DetailedState.CONNECTED, expected[5]); + assertEquals(DetailedState.SUSPENDED, expected[6]); + assertEquals(DetailedState.DISCONNECTING, expected[7]); + assertEquals(DetailedState.DISCONNECTED, expected[8]); + assertEquals(DetailedState.FAILED, expected[9]); + } + +} diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java new file mode 100644 index 0000000000..1a51acd091 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2009 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.net.NetworkInfo.State; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; + +@TestTargetClass(State.class) +public class NetworkInfo_StateTest extends AndroidTestCase { + + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test valueOf(String name).", + method = "valueOf", + args = {java.lang.String.class} + ) + public void testValueOf() { + assertEquals(State.CONNECTED, State.valueOf("CONNECTED")); + assertEquals(State.CONNECTING, State.valueOf("CONNECTING")); + assertEquals(State.DISCONNECTED, State.valueOf("DISCONNECTED")); + assertEquals(State.DISCONNECTING, State.valueOf("DISCONNECTING")); + assertEquals(State.SUSPENDED, State.valueOf("SUSPENDED")); + assertEquals(State.UNKNOWN, State.valueOf("UNKNOWN")); + } + + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test values().", + method = "values", + args = {} + ) + public void testValues() { + State[] expected = State.values(); + assertEquals(6, expected.length); + assertEquals(State.CONNECTING, expected[0]); + assertEquals(State.CONNECTED, expected[1]); + assertEquals(State.SUSPENDED, expected[2]); + assertEquals(State.DISCONNECTING, expected[3]); + assertEquals(State.DISCONNECTED, expected[4]); + assertEquals(State.UNKNOWN, expected[5]); + } +} diff --git a/tests/cts/net/src/android/net/cts/ProxyTest.java b/tests/cts/net/src/android/net/cts/ProxyTest.java new file mode 100644 index 0000000000..357935adb0 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/ProxyTest.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2009 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.content.Context; +import android.net.Proxy; +import android.provider.Settings.Secure; +import android.test.AndroidTestCase; + +import dalvik.annotation.BrokenTest; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; + +@TestTargetClass(Proxy.class) +public class ProxyTest extends AndroidTestCase { + + private Context mContext; + + @Override + protected void setUp() throws Exception { + super.setUp(); + + mContext = getContext(); + } + + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "Proxy", + args = {} + ) + public void testConstructor() { + new Proxy(); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getDefaultPort", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getDefaultHost", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getPort", + args = {Context.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getHost", + args = {Context.class} + ) + }) + @BrokenTest("Cannot write secure settings table") + public void testAccessProperties() { + final int minValidPort = 0; + final int maxValidPort = 65535; + int defaultPort = Proxy.getDefaultPort(); + if(null == Proxy.getDefaultHost()) { + assertEquals(-1, defaultPort); + } else { + assertTrue(defaultPort >= minValidPort && defaultPort <= maxValidPort); + } + + final String host = "proxy.example.com"; + final int port = 2008; + + Secure.putString(mContext.getContentResolver(), Secure.HTTP_PROXY, host + ":" + port); + assertEquals(host, Proxy.getHost(mContext)); + assertEquals(port, Proxy.getPort(mContext)); + } +} diff --git a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java new file mode 100644 index 0000000000..6cd5d6f10b --- /dev/null +++ b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2008 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 java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; + +import javax.net.SocketFactory; + +import android.net.SSLCertificateSocketFactory; +import android.test.AndroidTestCase; + +import dalvik.annotation.BrokenTest; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; +import dalvik.annotation.ToBeFixed; + +@TestTargetClass(SSLCertificateSocketFactory.class) +public class SSLCertificateSocketFactoryTest extends AndroidTestCase { + private SSLCertificateSocketFactory mFactory; + private int mTimeout; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mTimeout = 1000; + mFactory = (SSLCertificateSocketFactory) SSLCertificateSocketFactory.getDefault(mTimeout); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getSupportedCipherSuites", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getDefault", + args = {int.class} + ), + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getDefaultCipherSuites", + args = {} + ) + }) + @ToBeFixed(bug="1695243", explanation="Android API javadocs are incomplete") + public void testAccessProperties() throws Exception { + mFactory.getSupportedCipherSuites(); + mFactory.getDefaultCipherSuites(); + SocketFactory sf = SSLCertificateSocketFactory.getDefault(mTimeout); + assertNotNull(sf); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "createSocket", + args = {java.net.InetAddress.class, int.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "createSocket", + args = {java.net.Socket.class, java.lang.String.class, int.class, boolean.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "createSocket", + args = {java.lang.String.class, int.class} + ), + @TestTargetNew( + level = TestLevel.NOT_FEASIBLE, + method = "createSocket", + args = {java.lang.String.class, int.class, java.net.InetAddress.class, int.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "createSocket", + args = {java.net.InetAddress.class, int.class, java.net.InetAddress.class, int.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "SSLCertificateSocketFactory", + args = {int.class} + ) + }) + @BrokenTest("flaky") + public void testCreateSocket() throws Exception { + new SSLCertificateSocketFactory(100); + int port = 443; + String host = "www.fortify.net"; + InetAddress inetAddress = null; + inetAddress = InetAddress.getLocalHost(); + try { + mFactory.createSocket(inetAddress, port); + fail("should throw exception!"); + } catch (IOException e) { + // expected + } + + try { + InetAddress inetAddress1 = InetAddress.getLocalHost(); + InetAddress inetAddress2 = InetAddress.getLocalHost(); + mFactory.createSocket(inetAddress1, port, inetAddress2, port); + fail("should throw exception!"); + } catch (IOException e) { + // expected + } + + try { + Socket socket = new Socket(); + mFactory.createSocket(socket, host, port, true); + fail("should throw exception!"); + } catch (IOException e) { + // expected + } + Socket socket = null; + socket = mFactory.createSocket(host, port); + assertNotNull(socket); + assertNotNull(socket.getOutputStream()); + assertNotNull(socket.getInputStream()); + + // it throw exception when calling createSocket(String, int, InetAddress, int) + // The socket level is invalid. + } + +} diff --git a/tests/cts/net/src/android/net/cts/UriTest.java b/tests/cts/net/src/android/net/cts/UriTest.java new file mode 100644 index 0000000000..067ce52372 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/UriTest.java @@ -0,0 +1,727 @@ +/* + * Copyright (C) 2008 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 dalvik.annotation.TestTargets; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import android.content.ContentUris; +import android.net.Uri; +import android.os.Parcel; +import android.test.AndroidTestCase; +import java.io.File; +import java.util.Arrays; + +@TestTargetClass(Uri.class) +public class UriTest extends AndroidTestCase { + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test write to and read frome parcel.", + method = "writeToParcel", + args = {android.os.Parcel.class, android.net.Uri.class} + ) + public void testParcelling() { + parcelAndUnparcel(Uri.parse("foo:bob%20lee")); + parcelAndUnparcel(Uri.fromParts("foo", "bob lee", "fragment")); + parcelAndUnparcel(new Uri.Builder() + .scheme("http") + .authority("crazybob.org") + .path("/rss/") + .encodedQuery("a=b") + .fragment("foo") + .build()); + } + + private void parcelAndUnparcel(Uri u) { + Parcel p = Parcel.obtain(); + Uri.writeToParcel(p, u); + p.setDataPosition(0); + assertEquals(u, Uri.CREATOR.createFromParcel(p)); + + p.setDataPosition(0); + u = u.buildUpon().build(); + Uri.writeToParcel(p, u); + p.setDataPosition(0); + assertEquals(u, Uri.CREATOR.createFromParcel(p)); + } + + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test buildUpon", + method = "buildUpon", + args = {} + ) + public void testBuildUpon() { + Uri u = Uri.parse("bob:lee").buildUpon().scheme("robert").build(); + assertEquals("robert", u.getScheme()); + assertEquals("lee", u.getEncodedSchemeSpecificPart()); + assertEquals("lee", u.getSchemeSpecificPart()); + assertNull(u.getQuery()); + assertNull(u.getPath()); + assertNull(u.getAuthority()); + assertNull(u.getHost()); + + Uri a = Uri.fromParts("foo", "bar", "tee"); + Uri b = a.buildUpon().fragment("new").build(); + assertEquals("new", b.getFragment()); + assertEquals("bar", b.getSchemeSpecificPart()); + assertEquals("foo", b.getScheme()); + a = new Uri.Builder() + .scheme("foo") + .encodedOpaquePart("bar") + .fragment("tee") + .build(); + b = a.buildUpon().fragment("new").build(); + assertEquals("new", b.getFragment()); + assertEquals("bar", b.getSchemeSpecificPart()); + assertEquals("foo", b.getScheme()); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test string uri.", + method = "getSchemeSpecificPart", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test string uri.", + method = "getEncodedSchemeSpecificPart", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test string uri.", + method = "getEncodedPath", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test string uri.", + method = "getPath", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test string uri.", + method = "getEncodedQuery", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test string uri.", + method = "getQuery", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test string uri.", + method = "getEncodedFragment", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test string uri.", + method = "getHost", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test string uri.", + method = "getPort", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test string uri.", + method = "getUserInfo", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test string uri.", + method = "getEncodedUserInfo", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test string uri.", + method = "parse", + args = {java.lang.String.class} + ) + }) + public void testStringUri() { + assertEquals("bob lee", + Uri.parse("foo:bob%20lee").getSchemeSpecificPart()); + assertEquals("bob%20lee", + Uri.parse("foo:bob%20lee").getEncodedSchemeSpecificPart()); + + assertEquals("/bob%20lee", + Uri.parse("foo:/bob%20lee").getEncodedPath()); + assertNull(Uri.parse("foo:bob%20lee").getPath()); + + assertEquals("bob%20lee", + Uri.parse("foo:?bob%20lee").getEncodedQuery()); + assertNull(Uri.parse("foo:bob%20lee").getEncodedQuery()); + assertNull(Uri.parse("foo:bar#?bob%20lee").getQuery()); + + assertEquals("bob%20lee", + Uri.parse("foo:#bob%20lee").getEncodedFragment()); + + Uri uri = Uri.parse("http://localhost:42"); + assertEquals("localhost", uri.getHost()); + assertEquals(42, uri.getPort()); + + uri = Uri.parse("http://bob@localhost:42"); + assertEquals("bob", uri.getUserInfo()); + assertEquals("localhost", uri.getHost()); + assertEquals(42, uri.getPort()); + + uri = Uri.parse("http://bob%20lee@localhost:42"); + assertEquals("bob lee", uri.getUserInfo()); + assertEquals("bob%20lee", uri.getEncodedUserInfo()); + + uri = Uri.parse("http://localhost"); + assertEquals("localhost", uri.getHost()); + assertEquals(-1, uri.getPort()); + } + + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test compareTo", + method = "compareTo", + args = {android.net.Uri.class} + ) + public void testCompareTo() { + Uri a = Uri.parse("foo:a"); + Uri b = Uri.parse("foo:b"); + Uri b2 = Uri.parse("foo:b"); + + assertTrue(a.compareTo(b) < 0); + assertTrue(b.compareTo(a) > 0); + assertEquals(0, b.compareTo(b2)); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test equals and hashCode.", + method = "equals", + args = {java.lang.Object.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test equals and hashCode.", + method = "hashCode", + args = {} + ) + }) + public void testEqualsAndHashCode() { + Uri a = Uri.parse("http://crazybob.org/test/?foo=bar#tee"); + + Uri b = new Uri.Builder() + .scheme("http") + .authority("crazybob.org") + .path("/test/") + .encodedQuery("foo=bar") + .fragment("tee") + .build(); + + // Try alternate builder methods. + Uri c = new Uri.Builder() + .scheme("http") + .encodedAuthority("crazybob.org") + .encodedPath("/test/") + .encodedQuery("foo=bar") + .encodedFragment("tee") + .build(); + + assertFalse(Uri.EMPTY.equals(null)); + assertEquals(a, b); + assertEquals(b, c); + assertEquals(c, a); + assertEquals(a.hashCode(), b.hashCode()); + assertEquals(b.hashCode(), c.hashCode()); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test encode and decode.", + method = "encode", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test encode and decode.", + method = "encode", + args = {java.lang.String.class, java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test encode and decode.", + method = "decode", + args = {java.lang.String.class} + ) + }) + public void testEncodeAndDecode() { + String encoded = Uri.encode("Bob:/", "/"); + assertEquals(-1, encoded.indexOf(':')); + assertTrue(encoded.indexOf('/') > -1); + assertDecode(null); + assertDecode(""); + assertDecode("Bob"); + assertDecode(":Bob"); + assertDecode("::Bob"); + assertDecode("Bob::Lee"); + assertDecode("Bob:Lee"); + assertDecode("Bob::"); + assertDecode("Bob:"); + assertDecode("::Bob::"); + } + + private void assertDecode(String s) { + assertEquals(s, Uri.decode(Uri.encode(s, null))); + } + + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test fromFile.", + method = "fromFile", + args = {java.io.File.class} + ) + public void testFromFile() { + File f = new File("/tmp/bob"); + Uri uri = Uri.fromFile(f); + assertEquals("file:///tmp/bob", uri.toString()); + try { + Uri.fromFile(null); + fail("testFile fail"); + } catch (NullPointerException e) {} + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test get query parameters.", + method = "getQueryParameter", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test get query parameters.", + method = "getQueryParameters", + args = {java.lang.String.class} + ) + }) + public void testQueryParameters() { + Uri uri = Uri.parse("content://user"); + assertEquals(null, uri.getQueryParameter("a")); + + uri = uri.buildUpon().appendQueryParameter("a", "b").build(); + assertEquals("b", uri.getQueryParameter("a")); + + uri = uri.buildUpon().appendQueryParameter("a", "b2").build(); + assertEquals(Arrays.asList("b", "b2"), uri.getQueryParameters("a")); + + uri = uri.buildUpon().appendQueryParameter("c", "d").build(); + assertEquals(Arrays.asList("b", "b2"), uri.getQueryParameters("a")); + assertEquals("d", uri.getQueryParameter("c")); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "", + method = "getPathSegments", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "", + method = "getLastPathSegment", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "", + method = "withAppendedPath", + args = {android.net.Uri.class, java.lang.String.class} + ) + }) + public void testPathOperations() { + Uri uri = Uri.parse("content://user/a/b"); + + assertEquals(2, uri.getPathSegments().size()); + assertEquals("a", uri.getPathSegments().get(0)); + assertEquals("b", uri.getPathSegments().get(1)); + assertEquals("b", uri.getLastPathSegment()); + + Uri first = uri; + uri = uri.buildUpon().appendPath("c").build(); + assertEquals(3, uri.getPathSegments().size()); + assertEquals("c", uri.getPathSegments().get(2)); + assertEquals("c", uri.getLastPathSegment()); + assertEquals("content://user/a/b/c", uri.toString()); + + uri = ContentUris.withAppendedId(uri, 100); + assertEquals(4, uri.getPathSegments().size()); + assertEquals("100", uri.getPathSegments().get(3)); + assertEquals("100", uri.getLastPathSegment()); + assertEquals(100, ContentUris.parseId(uri)); + assertEquals("content://user/a/b/c/100", uri.toString()); + + // Make sure the original URI is still intact. + assertEquals(2, first.getPathSegments().size()); + assertEquals("b", first.getLastPathSegment()); + + try { + first.getPathSegments().get(2); + fail("test path operations"); + } catch (IndexOutOfBoundsException e) {} + + assertEquals(null, Uri.EMPTY.getLastPathSegment()); + + Uri withC = Uri.parse("foo:/a/b/").buildUpon().appendPath("c").build(); + assertEquals("/a/b/c", withC.getPath()); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test opaque uri.", + method = "isAbsolute", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test opaque uri.", + method = "isOpaque", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test opaque uri.", + method = "isRelative", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test opaque uri.", + method = "getHost", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test opaque uri.", + method = "getPort", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test opaque uri.", + method = "getScheme", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test opaque uri.", + method = "getSchemeSpecificPart", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test opaque uri.", + method = "fromParts", + args = {java.lang.String.class, java.lang.String.class, java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test opaque uri.", + method = "toString", + args = {} + ) + }) + public void testOpaqueUri() { + Uri uri = Uri.parse("mailto:nobody"); + testOpaqueUri(uri); + + uri = uri.buildUpon().build(); + testOpaqueUri(uri); + + uri = Uri.fromParts("mailto", "nobody", null); + testOpaqueUri(uri); + + uri = uri.buildUpon().build(); + testOpaqueUri(uri); + + uri = new Uri.Builder() + .scheme("mailto") + .opaquePart("nobody") + .build(); + testOpaqueUri(uri); + + uri = uri.buildUpon().build(); + testOpaqueUri(uri); + } + + private void testOpaqueUri(Uri uri) { + assertEquals("mailto", uri.getScheme()); + assertEquals("nobody", uri.getSchemeSpecificPart()); + assertEquals("nobody", uri.getEncodedSchemeSpecificPart()); + + assertNull(uri.getFragment()); + assertTrue(uri.isAbsolute()); + assertTrue(uri.isOpaque()); + assertFalse(uri.isRelative()); + assertFalse(uri.isHierarchical()); + + assertNull(uri.getAuthority()); + assertNull(uri.getEncodedAuthority()); + assertNull(uri.getPath()); + assertNull(uri.getEncodedPath()); + assertNull(uri.getUserInfo()); + assertNull(uri.getEncodedUserInfo()); + assertNull(uri.getQuery()); + assertNull(uri.getEncodedQuery()); + assertNull(uri.getHost()); + assertEquals(-1, uri.getPort()); + + assertTrue(uri.getPathSegments().isEmpty()); + assertNull(uri.getLastPathSegment()); + + assertEquals("mailto:nobody", uri.toString()); + + Uri withFragment = uri.buildUpon().fragment("top").build(); + assertEquals("mailto:nobody#top", withFragment.toString()); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test hierarchical uris.", + method = "getAuthority", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test hierarchical uris.", + method = "getScheme", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test hierarchical uris.", + method = "getEncodedAuthority", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test hierarchical uris.", + method = "getPath", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test hierarchical uris.", + method = "getEncodedPath", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test hierarchical uris.", + method = "getQuery", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test hierarchical uris.", + method = "getEncodedQuery", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test hierarchical uris.", + method = "getFragment", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test hierarchical uris.", + method = "getEncodedFragment", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test hierarchical uris.", + method = "getSchemeSpecificPart", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test hierarchical uris.", + method = "isAbsolute", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test hierarchical uris.", + method = "isHierarchical", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test hierarchical uris.", + method = "isOpaque", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test hierarchical uris.", + method = "isRelative", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test hierarchical uris.", + method = "toString", + args = {} + ) + }) + public void testHierarchicalUris() { + testHierarchical("http", "google.com", "/p1/p2", "query", "fragment"); + testHierarchical("file", null, "/p1/p2", null, null); + testHierarchical("content", "contact", "/p1/p2", null, null); + testHierarchical("http", "google.com", "/p1/p2", null, "fragment"); + testHierarchical("http", "google.com", "", null, "fragment"); + testHierarchical("http", "google.com", "", "query", "fragment"); + testHierarchical("http", "google.com", "", "query", null); + testHierarchical("http", null, "/", "query", null); + } + + private static void testHierarchical(String scheme, String authority, + String path, String query, String fragment) { + StringBuilder sb = new StringBuilder(); + + if (authority != null) { + sb.append("//").append(authority); + } + if (path != null) { + sb.append(path); + } + if (query != null) { + sb.append('?').append(query); + } + + String ssp = sb.toString(); + + if (scheme != null) { + sb.insert(0, scheme + ":"); + } + if (fragment != null) { + sb.append('#').append(fragment); + } + + String uriString = sb.toString(); + + Uri uri = Uri.parse(uriString); + + // Run these twice to test caching. + compareHierarchical( + uriString, ssp, uri, scheme, authority, path, query, fragment); + compareHierarchical( + uriString, ssp, uri, scheme, authority, path, query, fragment); + + // Test rebuilt version. + uri = uri.buildUpon().build(); + + // Run these twice to test caching. + compareHierarchical( + uriString, ssp, uri, scheme, authority, path, query, fragment); + compareHierarchical( + uriString, ssp, uri, scheme, authority, path, query, fragment); + + // The decoded and encoded versions of the inputs are all the same. + // We'll test the actual encoding decoding separately. + + // Test building with encoded versions. + Uri built = new Uri.Builder() + .scheme(scheme) + .encodedAuthority(authority) + .encodedPath(path) + .encodedQuery(query) + .encodedFragment(fragment) + .build(); + + compareHierarchical( + uriString, ssp, built, scheme, authority, path, query, fragment); + compareHierarchical( + uriString, ssp, built, scheme, authority, path, query, fragment); + + // Test building with decoded versions. + built = new Uri.Builder() + .scheme(scheme) + .authority(authority) + .path(path) + .query(query) + .fragment(fragment) + .build(); + + compareHierarchical( + uriString, ssp, built, scheme, authority, path, query, fragment); + compareHierarchical( + uriString, ssp, built, scheme, authority, path, query, fragment); + + // Rebuild. + built = built.buildUpon().build(); + + compareHierarchical( + uriString, ssp, built, scheme, authority, path, query, fragment); + compareHierarchical( + uriString, ssp, built, scheme, authority, path, query, fragment); + } + + private static void compareHierarchical(String uriString, String ssp, + Uri uri, + String scheme, String authority, String path, String query, + String fragment) { + assertEquals(scheme, uri.getScheme()); + assertEquals(authority, uri.getAuthority()); + assertEquals(authority, uri.getEncodedAuthority()); + assertEquals(path, uri.getPath()); + assertEquals(path, uri.getEncodedPath()); + assertEquals(query, uri.getQuery()); + assertEquals(query, uri.getEncodedQuery()); + assertEquals(fragment, uri.getFragment()); + assertEquals(fragment, uri.getEncodedFragment()); + assertEquals(ssp, uri.getSchemeSpecificPart()); + + if (scheme != null) { + assertTrue(uri.isAbsolute()); + assertFalse(uri.isRelative()); + } else { + assertFalse(uri.isAbsolute()); + assertTrue(uri.isRelative()); + } + + assertFalse(uri.isOpaque()); + assertTrue(uri.isHierarchical()); + assertEquals(uriString, uri.toString()); + } +} diff --git a/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java b/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java new file mode 100644 index 0000000000..66bdb074b0 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2008 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 junit.framework.TestCase; +import dalvik.annotation.TestTargets; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargetClass; +import android.net.Uri.Builder; +import android.net.Uri; + +@TestTargetClass(Uri.Builder.class) +public class Uri_BuilderTest extends TestCase { + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test Builder operations.", + method = "Uri.Builder", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test Builder operations.", + method = "build", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test Builder operations.", + method = "scheme", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test Builder operations.", + method = "authority", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test Builder operations.", + method = "path", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test Builder operations.", + method = "query", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test Builder operations.", + method = "opaquePart", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test Builder operations.", + method = "fragment", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test Builder operations.", + method = "appendEncodedPath", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test Builder operations.", + method = "appendPath", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test Builder operations.", + method = "appendQueryParameter", + args = {java.lang.String.class, java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test Builder operations.", + method = "encodedAuthority", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test Builder operations.", + method = "encodedFragment", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test Builder operations.", + method = "encodedPath", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test Builder operations.", + method = "encodedQuery", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test Builder operations.", + method = "encodedOpaquePart", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test Builder operations.", + method = "toString", + args = {} + ) + }) + public void testBuilderOperations() { + Uri uri = Uri.parse("http://google.com/p1?query#fragment"); + Builder builder = uri.buildUpon(); + uri = builder.appendPath("p2").build(); + assertEquals("http", uri.getScheme()); + assertEquals("google.com", uri.getAuthority()); + assertEquals("/p1/p2", uri.getPath()); + assertEquals("query", uri.getQuery()); + assertEquals("fragment", uri.getFragment()); + assertEquals(uri.toString(), builder.toString()); + + uri = Uri.parse("mailto:nobody"); + builder = uri.buildUpon(); + uri = builder.build(); + assertEquals("mailto", uri.getScheme()); + assertEquals("nobody", uri.getSchemeSpecificPart()); + assertEquals(uri.toString(), builder.toString()); + + uri = new Uri.Builder() + .scheme("http") + .encodedAuthority("google.com") + .encodedPath("/p1") + .appendEncodedPath("p2") + .encodedQuery("query") + .appendQueryParameter("query2", null) + .encodedFragment("fragment") + .build(); + assertEquals("http", uri.getScheme()); + assertEquals("google.com", uri.getEncodedAuthority()); + assertEquals("/p1/p2", uri.getEncodedPath()); + assertEquals("query&query2=null", uri.getEncodedQuery()); + assertEquals("fragment", uri.getEncodedFragment()); + + uri = new Uri.Builder() + .scheme("mailto") + .encodedOpaquePart("nobody") + .build(); + assertEquals("mailto", uri.getScheme()); + assertEquals("nobody", uri.getEncodedSchemeSpecificPart()); + } +} diff --git a/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java b/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java new file mode 100644 index 0000000000..0dd5db1886 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java @@ -0,0 +1,419 @@ +/* + * Copyright (C) 2009 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 java.util.List; +import java.util.Set; +import android.net.UrlQuerySanitizer; +import android.net.UrlQuerySanitizer.IllegalCharacterValueSanitizer; +import android.net.UrlQuerySanitizer.ParameterValuePair; +import android.net.UrlQuerySanitizer.ValueSanitizer; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; + +@TestTargetClass(UrlQuerySanitizer.class) +public class UrlQuerySanitizerTest extends AndroidTestCase { + private static final int ALL_OK = IllegalCharacterValueSanitizer.ALL_OK; + + // URL for test. + private static final String TEST_URL = "http://example.com/?name=Joe+User&age=20&height=175"; + + // Default sanitizer's change when "+". + private static final String EXPECTED_UNDERLINE_NAME = "Joe_User"; + + // IllegalCharacterValueSanitizer sanitizer's change when "+". + private static final String EXPECTED_SPACE_NAME = "Joe User"; + private static final String EXPECTED_AGE = "20"; + private static final String EXPECTED_HEIGHT = "175"; + private static final String NAME = "name"; + private static final String AGE = "age"; + private static final String HEIGHT = "height"; + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "UrlQuerySanitizer", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "UrlQuerySanitizer", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "parseUrl", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "parseQuery", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "parseEntry", + args = {String.class, String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getValue", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "addSanitizedEntry", + args = {String.class, String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "hasParameter", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getParameterSet", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getParameterList", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "setUnregisteredParameterValueSanitizer", + args = {ValueSanitizer.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getUnregisteredParameterValueSanitizer", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getAllButNulAndAngleBracketsLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getAllButNulLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getAllButWhitespaceLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getAllIllegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getAmpAndSpaceLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getAmpLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getSpaceLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getUrlAndSpaceLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getUrlLegal", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "unescape", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "isHexDigit", + args = {char.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "decodeHexDigit", + args = {char.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "setAllowUnregisteredParamaters", + args = {boolean.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getAllowUnregisteredParamaters", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "registerParameter", + args = {String.class, ValueSanitizer.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "registerParameters", + args = {String[].class, ValueSanitizer.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getEffectiveValueSanitizer", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getValueSanitizer", + args = {String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "clear", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "setPreferFirstRepeatedParameter", + args = {boolean.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getPreferFirstRepeatedParameter", + args = {} + ) + }) + public void testUrlQuerySanitizer() { + MockUrlQuerySanitizer uqs = new MockUrlQuerySanitizer(); + assertFalse(uqs.getAllowUnregisteredParamaters()); + + final String query = "book=thinking in java&price=108"; + final String book = "book"; + final String bookName = "thinking in java"; + final String price = "price"; + final String bookPrice = "108"; + final String notExistPar = "notExistParameter"; + uqs.registerParameters(new String[]{book, price}, UrlQuerySanitizer.getSpaceLegal()); + uqs.parseQuery(query); + assertTrue(uqs.hasParameter(book)); + assertTrue(uqs.hasParameter(price)); + assertFalse(uqs.hasParameter(notExistPar)); + assertEquals(bookName, uqs.getValue(book)); + assertEquals(bookPrice, uqs.getValue(price)); + assertNull(uqs.getValue(notExistPar)); + uqs.clear(); + assertFalse(uqs.hasParameter(book)); + assertFalse(uqs.hasParameter(price)); + + uqs.parseEntry(book, bookName); + assertTrue(uqs.hasParameter(book)); + assertEquals(bookName, uqs.getValue(book)); + uqs.parseEntry(price, bookPrice); + assertTrue(uqs.hasParameter(price)); + assertEquals(bookPrice, uqs.getValue(price)); + assertFalse(uqs.hasParameter(notExistPar)); + assertNull(uqs.getValue(notExistPar)); + + uqs = new MockUrlQuerySanitizer(TEST_URL); + assertTrue(uqs.getAllowUnregisteredParamaters()); + + assertTrue(uqs.hasParameter(NAME)); + assertTrue(uqs.hasParameter(AGE)); + assertTrue(uqs.hasParameter(HEIGHT)); + assertFalse(uqs.hasParameter(notExistPar)); + + assertEquals(EXPECTED_UNDERLINE_NAME, uqs.getValue(NAME)); + assertEquals(EXPECTED_AGE, uqs.getValue(AGE)); + assertEquals(EXPECTED_HEIGHT, uqs.getValue(HEIGHT)); + assertNull(uqs.getValue(notExistPar)); + + final int ContainerLen = 3; + Set urlSet = uqs.getParameterSet(); + assertEquals(ContainerLen, urlSet.size()); + assertTrue(urlSet.contains(NAME)); + assertTrue(urlSet.contains(AGE)); + assertTrue(urlSet.contains(HEIGHT)); + assertFalse(urlSet.contains(notExistPar)); + + List urlList = uqs.getParameterList(); + assertEquals(ContainerLen, urlList.size()); + ParameterValuePair pvp = urlList.get(0); + assertEquals(NAME, pvp.mParameter); + assertEquals(EXPECTED_UNDERLINE_NAME, pvp.mValue); + pvp = urlList.get(1); + assertEquals(AGE, pvp.mParameter); + assertEquals(EXPECTED_AGE, pvp.mValue); + pvp = urlList.get(2); + assertEquals(HEIGHT, pvp.mParameter); + assertEquals(EXPECTED_HEIGHT, pvp.mValue); + + assertFalse(uqs.getPreferFirstRepeatedParameter()); + uqs.addSanitizedEntry(HEIGHT, EXPECTED_HEIGHT + 1); + assertEquals(ContainerLen, urlSet.size()); + assertEquals(ContainerLen + 1, urlList.size()); + assertEquals(EXPECTED_HEIGHT + 1, uqs.getValue(HEIGHT)); + + uqs.setPreferFirstRepeatedParameter(true); + assertTrue(uqs.getPreferFirstRepeatedParameter()); + uqs.addSanitizedEntry(HEIGHT, EXPECTED_HEIGHT); + assertEquals(ContainerLen, urlSet.size()); + assertEquals(ContainerLen + 2, urlList.size()); + assertEquals(EXPECTED_HEIGHT + 1, uqs.getValue(HEIGHT)); + + uqs.registerParameter(NAME, null); + assertNull(uqs.getValueSanitizer(NAME)); + assertNotNull(uqs.getEffectiveValueSanitizer(NAME)); + + uqs.setAllowUnregisteredParamaters(false); + assertFalse(uqs.getAllowUnregisteredParamaters()); + uqs.registerParameter(NAME, null); + assertNull(uqs.getEffectiveValueSanitizer(NAME)); + + ValueSanitizer vs = new IllegalCharacterValueSanitizer(ALL_OK); + uqs.registerParameter(NAME, vs); + uqs.parseUrl(TEST_URL); + assertEquals(EXPECTED_SPACE_NAME, uqs.getValue(NAME)); + assertNotSame(EXPECTED_AGE, uqs.getValue(AGE)); + + String[] register = {NAME, AGE}; + uqs.registerParameters(register, vs); + uqs.parseUrl(TEST_URL); + assertEquals(EXPECTED_SPACE_NAME, uqs.getValue(NAME)); + assertEquals(EXPECTED_AGE, uqs.getValue(AGE)); + assertNotSame(EXPECTED_HEIGHT, uqs.getValue(HEIGHT)); + + uqs.setUnregisteredParameterValueSanitizer(vs); + assertEquals(vs, uqs.getUnregisteredParameterValueSanitizer()); + + vs = UrlQuerySanitizer.getAllIllegal(); + assertEquals("Joe_User", vs.sanitize("Joe\0User")); + vs = UrlQuerySanitizer.getAllButNulLegal(); + assertEquals("Joe User", vs.sanitize("Joe\0User")); + vs = UrlQuerySanitizer.getAllButWhitespaceLegal(); + assertEquals("Joe_User", vs.sanitize("Joe User")); + vs = UrlQuerySanitizer.getAmpAndSpaceLegal(); + assertEquals("Joe User&", vs.sanitize("Joe User&")); + vs = UrlQuerySanitizer.getAmpLegal(); + assertEquals("Joe_User&", vs.sanitize("Joe User&")); + vs = UrlQuerySanitizer.getSpaceLegal(); + assertEquals("Joe User ", vs.sanitize("Joe User&")); + vs = UrlQuerySanitizer.getUrlAndSpaceLegal(); + assertEquals("Joe User&Smith%B5'\'", vs.sanitize("Joe User&Smith%B5'\'")); + vs = UrlQuerySanitizer.getUrlLegal(); + assertEquals("Joe_User&Smith%B5'\'", vs.sanitize("Joe User&Smith%B5'\'")); + + String escape = "Joe"; + assertEquals(escape, uqs.unescape(escape)); + String expectedPlus = "Joe User"; + String expectedPercentSignHex = "title=" + Character.toString((char)181); + String initialPlus = "Joe+User"; + String initialPercentSign = "title=%B5"; + assertEquals(expectedPlus, uqs.unescape(initialPlus)); + assertEquals(expectedPercentSignHex, uqs.unescape(initialPercentSign)); + + assertTrue(uqs.decodeHexDigit('0') >= 0); + assertTrue(uqs.decodeHexDigit('b') >= 0); + assertTrue(uqs.decodeHexDigit('F') >= 0); + assertTrue(uqs.decodeHexDigit('$') < 0); + + assertTrue(uqs.isHexDigit('0')); + assertTrue(uqs.isHexDigit('b')); + assertTrue(uqs.isHexDigit('F')); + assertFalse(uqs.isHexDigit('$')); + + uqs.clear(); + assertEquals(0, urlSet.size()); + assertEquals(0, urlList.size()); + + uqs.setPreferFirstRepeatedParameter(true); + assertTrue(uqs.getPreferFirstRepeatedParameter()); + uqs.setPreferFirstRepeatedParameter(false); + assertFalse(uqs.getPreferFirstRepeatedParameter()); + + UrlQuerySanitizer uq = new UrlQuerySanitizer(); + uq.setPreferFirstRepeatedParameter(true); + final String PARA_ANSWER = "answer"; + uq.registerParameter(PARA_ANSWER, new MockValueSanitizer()); + uq.parseUrl("http://www.google.com/question?answer=13&answer=42"); + assertEquals("13", uq.getValue(PARA_ANSWER)); + + uq.setPreferFirstRepeatedParameter(false); + uq.parseQuery("http://www.google.com/question?answer=13&answer=42"); + assertEquals("42", uq.getValue(PARA_ANSWER)); + + } + + private static class MockValueSanitizer implements ValueSanitizer{ + + public String sanitize(String value) { + return value; + } + } + + class MockUrlQuerySanitizer extends UrlQuerySanitizer { + public MockUrlQuerySanitizer() { + super(); + } + + public MockUrlQuerySanitizer(String url) { + super(url); + } + + @Override + protected void addSanitizedEntry(String parameter, String value) { + super.addSanitizedEntry(parameter, value); + } + + @Override + protected void clear() { + super.clear(); + } + + @Override + protected int decodeHexDigit(char c) { + return super.decodeHexDigit(c); + } + + @Override + protected boolean isHexDigit(char c) { + return super.isHexDigit(c); + } + + @Override + protected void parseEntry(String parameter, String value) { + super.parseEntry(parameter, value); + } + } +} diff --git a/tests/cts/net/src/android/net/cts/UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java b/tests/cts/net/src/android/net/cts/UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java new file mode 100644 index 0000000000..f85a5347e0 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2009 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.net.UrlQuerySanitizer; +import android.net.UrlQuerySanitizer.IllegalCharacterValueSanitizer; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; + +@TestTargetClass(UrlQuerySanitizer.IllegalCharacterValueSanitizer.class) +public class UrlQuerySanitizer_IllegalCharacterValueSanitizerTest extends AndroidTestCase { + static final int SPACE_OK = IllegalCharacterValueSanitizer.SPACE_OK; + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test constructor(s) of {@link IllegalCharacterValueSanitizer}", + method = "IllegalCharacterValueSanitizer", + args = {int.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test method: sanitize", + method = "sanitize", + args = {String.class} + ) + }) + public void testSanitize() { + IllegalCharacterValueSanitizer sanitizer = new IllegalCharacterValueSanitizer(SPACE_OK); + assertEquals("Joe User", sanitizer.sanitize("Joe getCriticalExtensionOIDs() { + return null; + } + + public byte[] getExtensionValue(String oid) { + return null; + } + + public Set getNonCriticalExtensionOIDs() { + return null; + } + + public boolean hasUnsupportedCriticalExtension() { + return false; + } + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test saveState and restoreState(SslCertificate certificate).", + method = "saveState", + args = {android.net.http.SslCertificate.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test saveState and restoreState(SslCertificate certificate).", + method = "restoreState", + args = {android.os.Bundle.class} + ) + }) + public void testState() { + // set the expected value + + Date date1 = new Date(System.currentTimeMillis() - 1000); + Date date2 = new Date(System.currentTimeMillis()); + SslCertificate ssl = new SslCertificate("c=129", "e=weji", DateFormat.getInstance().format( + date1), DateFormat.getInstance().format(date2)); + Bundle saved = SslCertificate.saveState(ssl); + assertTrue(saved.size() == 4); + + assertNotNull(saved.getString("issued-to")); + assertNotNull(saved.getString("issued-by")); + assertNotNull(saved.getString("valid-not-before")); + assertNotNull(saved.getString("valid-not-after")); + assertNull(SslCertificate.saveState(null)); + + SslCertificate restored = SslCertificate.restoreState(saved); + assertEquals(ssl.getValidNotAfter(), restored.getValidNotAfter()); + assertEquals(ssl.getValidNotBefore(), restored.getValidNotBefore()); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test getIssuedTo().", + method = "getIssuedTo", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test getIssuedTo().", + method = "getIssuedBy", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test getIssuedTo().", + method = "getValidNotAfter", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test getIssuedTo().", + method = "getValidNotBefore", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test getIssuedTo().", + method = "toString", + args = {} + ) + }) + public void testSslCertificate() { + + final String TO = "c=ccc,o=testOName,ou=testUName,cn=testCName"; + final String BY = "e=aeei,c=adb,o=testOName,ou=testUName,cn=testCName"; + // new the SslCertificate instance + Date date1 = new Date(System.currentTimeMillis() - 1000); + Date date2 = new Date(System.currentTimeMillis()); + SslCertificate ssl = new SslCertificate(TO, BY, DateFormat.getInstance().format( + date1), DateFormat.getInstance().format(date2)); + DName issuedTo = ssl.getIssuedTo(); + DName issuedBy = ssl.getIssuedBy(); + + assertEquals("testCName", issuedTo.getCName()); + assertEquals(TO, issuedTo.getDName()); + assertEquals("testOName", issuedTo.getOName()); + assertEquals("testUName", issuedTo.getUName()); + + assertEquals("testCName", issuedBy.getCName()); + assertEquals(BY, issuedBy.getDName()); + assertEquals("testOName", issuedBy.getOName()); + assertEquals("testUName", issuedBy.getUName()); + + assertEquals(DateFormat.getInstance().format(date1), ssl.getValidNotBefore()); + assertEquals(DateFormat.getInstance().format(date2), ssl.getValidNotAfter()); + final String EXPECTED = "Issued to: c=ccc,o=testOName,ou=testUName,cn=testCName;\n" + + "Issued by: e=aeei,c=adb,o=testOName,ou=testUName,cn=testCName;\n"; + assertEquals(EXPECTED, ssl.toString()); + } + +} diff --git a/tests/cts/net/src/android/net/http/cts/SslCertificate_DNameTest.java b/tests/cts/net/src/android/net/http/cts/SslCertificate_DNameTest.java new file mode 100644 index 0000000000..848bf7b95a --- /dev/null +++ b/tests/cts/net/src/android/net/http/cts/SslCertificate_DNameTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2008 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.http.cts; + +import java.text.DateFormat; +import java.util.Date; + +import junit.framework.TestCase; +import dalvik.annotation.TestTargets; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargetClass; +import android.net.http.SslCertificate; +import android.net.http.SslCertificate.DName; + +@TestTargetClass(DName.class) +public class SslCertificate_DNameTest extends TestCase { + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test DName.", + method = "SslCertificate.DName", + args = {java.lang.String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test DName.", + method = "getCName", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test DName.", + method = "getDName", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test DName.", + method = "getOName", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + notes = "Test DName.", + method = "getUName", + args = {} + ) + }) + public void testDName() { + final String TO = "c=ccc,o=testOName,ou=testUName,cn=testCName"; + final String BY = "e=aeei,c=adb,o=testOName,ou=testUName,cn=testCName"; + // new the SslCertificate instance + Date date1 = new Date(System.currentTimeMillis() - 1000); + Date date2 = new Date(System.currentTimeMillis()); + SslCertificate ssl = new SslCertificate(TO, BY, DateFormat.getInstance().format( + date1), DateFormat.getInstance().format(date2)); + DName issuedTo = ssl.getIssuedTo(); + + assertNotNull(issuedTo); + + assertEquals("testCName", issuedTo.getCName()); + assertEquals(TO, issuedTo.getDName()); + assertEquals("testOName", issuedTo.getOName()); + assertEquals("testUName", issuedTo.getUName()); + } + +} diff --git a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java new file mode 100644 index 0000000000..0ab71c70e4 --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2008 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.wifi.cts; + +import java.util.List; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.wifi.ScanResult; +import android.net.wifi.WifiManager; +import android.net.wifi.WifiManager.WifiLock; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; + +@TestTargetClass(ScanResult.class) +public class ScanResultTest extends AndroidTestCase { + private static class MySync { + int expectedState = STATE_NULL; + } + + private WifiManager mWifiManager; + private WifiLock mWifiLock; + private static MySync mMySync; + + private static final int STATE_NULL = 0; + private static final int STATE_WIFI_CHANGING = 1; + private static final int STATE_WIFI_CHANGED = 2; + + private static final String TAG = "WifiInfoTest"; + private static final int TIMEOUT_MSEC = 6000; + private static final int WAIT_MSEC = 60; + private static final int DURATION = 10000; + private IntentFilter mIntentFilter; + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) { + synchronized (mMySync) { + mMySync.expectedState = STATE_WIFI_CHANGED; + mMySync.notify(); + } + } + } + }; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mMySync = new MySync(); + mIntentFilter = new IntentFilter(); + mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); + mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); + mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.ACTION_PICK_WIFI_NETWORK); + + mContext.registerReceiver(mReceiver, mIntentFilter); + mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); + assertNotNull(mWifiManager); + mWifiLock = mWifiManager.createWifiLock(TAG); + mWifiLock.acquire(); + if (!mWifiManager.isWifiEnabled()) + setWifiEnabled(true); + Thread.sleep(DURATION); + assertTrue(mWifiManager.isWifiEnabled()); + mMySync.expectedState = STATE_NULL; + } + + @Override + protected void tearDown() throws Exception { + mWifiLock.release(); + mContext.unregisterReceiver(mReceiver); + if (!mWifiManager.isWifiEnabled()) + setWifiEnabled(true); + Thread.sleep(DURATION); + super.tearDown(); + } + + private void setWifiEnabled(boolean enable) throws Exception { + synchronized (mMySync) { + mMySync.expectedState = STATE_WIFI_CHANGING; + assertTrue(mWifiManager.setWifiEnabled(enable)); + long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; + while (System.currentTimeMillis() < timeout + && mMySync.expectedState == STATE_WIFI_CHANGING) + mMySync.wait(WAIT_MSEC); + } + } + + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "toString", + args = {} + ) + public void testScanResultProperties() { + List scanResults = mWifiManager.getScanResults(); + // this test case should in Wifi environment + for (int i = 0; i < scanResults.size(); i++) { + ScanResult mScanResult = scanResults.get(i); + assertNotNull(mScanResult.toString()); + } + } + +} diff --git a/tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java b/tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java new file mode 100644 index 0000000000..4e03f5e9ce --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2008 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.wifi.cts; + +import android.net.wifi.SupplicantState; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; + +@TestTargetClass(SupplicantState.class) +public class SupplicantStateTest extends AndroidTestCase { + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "isValidState", + args = {android.net.wifi.SupplicantState.class} + ) + }) + public void testIsValidState() { + assertTrue(SupplicantState.isValidState(SupplicantState.DISCONNECTED)); + assertTrue(SupplicantState.isValidState(SupplicantState.INACTIVE)); + assertTrue(SupplicantState.isValidState(SupplicantState.SCANNING)); + assertTrue(SupplicantState.isValidState(SupplicantState.ASSOCIATING)); + assertTrue(SupplicantState.isValidState(SupplicantState.ASSOCIATED)); + assertTrue(SupplicantState.isValidState(SupplicantState.FOUR_WAY_HANDSHAKE)); + assertTrue(SupplicantState.isValidState(SupplicantState.GROUP_HANDSHAKE)); + assertTrue(SupplicantState.isValidState(SupplicantState.COMPLETED)); + assertTrue(SupplicantState.isValidState(SupplicantState.DORMANT)); + assertFalse(SupplicantState.isValidState(SupplicantState.UNINITIALIZED)); + assertFalse(SupplicantState.isValidState(SupplicantState.INVALID)); + } + +} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java new file mode 100644 index 0000000000..3018907092 --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2008 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.wifi.cts; + +import java.util.List; + +import android.content.Context; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiManager; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; + +@TestTargetClass(WifiConfiguration.class) +public class WifiConfigurationTest extends AndroidTestCase { + private WifiManager mWifiManager; + @Override + protected void setUp() throws Exception { + super.setUp(); + mWifiManager = (WifiManager) mContext + .getSystemService(Context.WIFI_SERVICE); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "WifiConfiguration", + args = {} + ), + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "toString", + args = {} + ) + }) + public void testWifiConfiguration() { + List wifiConfigurations = mWifiManager.getConfiguredNetworks(); + for (int i = 0; i < wifiConfigurations.size(); i++) { + WifiConfiguration wifiConfiguration = wifiConfigurations.get(i); + assertNotNull(wifiConfiguration); + assertNotNull(wifiConfiguration.toString()); + } + } +} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java new file mode 100644 index 0000000000..42243c890d --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2008 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.wifi.cts; + +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; +import dalvik.annotation.ToBeFixed; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.wifi.SupplicantState; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; +import android.net.wifi.WifiManager.WifiLock; +import android.test.AndroidTestCase; + +@TestTargetClass(WifiInfo.class) +public class WifiInfoTest extends AndroidTestCase { + private static class MySync { + int expectedState = STATE_NULL; + } + + private WifiManager mWifiManager; + private WifiLock mWifiLock; + private static MySync mMySync; + + private static final int STATE_NULL = 0; + private static final int STATE_WIFI_CHANGING = 1; + private static final int STATE_WIFI_CHANGED = 2; + + private static final String TAG = "WifiInfoTest"; + private static final int TIMEOUT_MSEC = 6000; + private static final int WAIT_MSEC = 60; + private static final int DURATION = 10000; + private IntentFilter mIntentFilter; + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) { + synchronized (mMySync) { + mMySync.expectedState = STATE_WIFI_CHANGED; + mMySync.notify(); + } + } + } + }; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mMySync = new MySync(); + mIntentFilter = new IntentFilter(); + mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); + mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); + mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.ACTION_PICK_WIFI_NETWORK); + + mContext.registerReceiver(mReceiver, mIntentFilter); + mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); + assertNotNull(mWifiManager); + mWifiLock = mWifiManager.createWifiLock(TAG); + mWifiLock.acquire(); + if (!mWifiManager.isWifiEnabled()) + setWifiEnabled(true); + Thread.sleep(DURATION); + assertTrue(mWifiManager.isWifiEnabled()); + mMySync.expectedState = STATE_NULL; + } + + @Override + protected void tearDown() throws Exception { + mWifiLock.release(); + mContext.unregisterReceiver(mReceiver); + if (!mWifiManager.isWifiEnabled()) + setWifiEnabled(true); + Thread.sleep(DURATION); + super.tearDown(); + } + + private void setWifiEnabled(boolean enable) throws Exception { + synchronized (mMySync) { + mMySync.expectedState = STATE_WIFI_CHANGING; + assertTrue(mWifiManager.setWifiEnabled(enable)); + long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; + while (System.currentTimeMillis() < timeout + && mMySync.expectedState == STATE_WIFI_CHANGING) + mMySync.wait(WAIT_MSEC); + } + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getMacAddress", + args = {} + ), + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getIpAddress", + args = {} + ), + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getDetailedStateOf", + args = {android.net.wifi.SupplicantState.class} + ), + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getNetworkId", + args = {} + ), + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getSSID", + args = {} + ), + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getBSSID", + args = {} + ), + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getSupplicantState", + args = {} + ), + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getLinkSpeed", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "toString", + args = {} + ), + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getRssi", + args = {} + ), + @TestTargetNew( + level = TestLevel.PARTIAL, + method = "getHiddenSSID", + args = {} + ) + }) + @ToBeFixed(bug="1871573", explanation="android.net.wifi.WifiInfo#getNetworkId() return -1 when" + + " there is wifi connection") + public void testWifiInfoProperties() throws Exception { + // this test case should in Wifi environment + WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); + + assertNotNull(wifiInfo); + assertNotNull(wifiInfo.toString()); + SupplicantState.isValidState(wifiInfo.getSupplicantState()); + WifiInfo.getDetailedStateOf(SupplicantState.DISCONNECTED); + wifiInfo.getSSID(); + wifiInfo.getBSSID(); + wifiInfo.getIpAddress(); + wifiInfo.getLinkSpeed(); + wifiInfo.getRssi(); + wifiInfo.getHiddenSSID(); + wifiInfo.getMacAddress(); + setWifiEnabled(false); + Thread.sleep(DURATION); + wifiInfo = mWifiManager.getConnectionInfo(); + assertEquals(-1, wifiInfo.getNetworkId()); + } + +} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java new file mode 100644 index 0000000000..132ca9247d --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -0,0 +1,427 @@ +/* + * Copyright (C) 2009 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.wifi.cts; + +import java.util.List; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.wifi.ScanResult; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiManager; +import android.net.wifi.WifiConfiguration.Status; +import android.net.wifi.WifiManager.WifiLock; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; + +@TestTargetClass(WifiManager.class) +public class WifiManagerTest extends AndroidTestCase { + private static class MySync { + int expectedState = STATE_NULL; + } + + private WifiManager mWifiManager; + private WifiLock mWifiLock; + private static MySync mMySync; + private List mScanResult = null; + + // Please refer to WifiManager + private static final int MIN_RSSI = -100; + private static final int MAX_RSSI = -55; + + private static final int STATE_NULL = 0; + private static final int STATE_WIFI_CHANGING = 1; + private static final int STATE_WIFI_CHANGED = 2; + private static final int STATE_SCANING = 3; + private static final int STATE_SCAN_RESULTS_AVAILABLE = 4; + + private static final String TAG = "WifiManagerTest"; + private static final String SSID1 = "\"WifiManagerTest\""; + private static final String SSID2 = "\"WifiManagerTestModified\""; + private static final int TIMEOUT_MSEC = 6000; + private static final int WAIT_MSEC = 60; + private static final int DURATION = 10000; + private IntentFilter mIntentFilter; + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { + synchronized (mMySync) { + if (mWifiManager.getScanResults() != null) { + mScanResult = mWifiManager.getScanResults(); + mMySync.expectedState = STATE_SCAN_RESULTS_AVAILABLE; + mScanResult = mWifiManager.getScanResults(); + mMySync.notify(); + } + } + } else if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) { + synchronized (mMySync) { + mMySync.expectedState = STATE_WIFI_CHANGED; + mMySync.notify(); + } + } + } + }; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mMySync = new MySync(); + mIntentFilter = new IntentFilter(); + mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); + mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); + mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION); + mIntentFilter.addAction(WifiManager.ACTION_PICK_WIFI_NETWORK); + + mContext.registerReceiver(mReceiver, mIntentFilter); + mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); + assertNotNull(mWifiManager); + mWifiLock = mWifiManager.createWifiLock(TAG); + mWifiLock.acquire(); + if (!mWifiManager.isWifiEnabled()) + setWifiEnabled(true); + Thread.sleep(DURATION); + assertTrue(mWifiManager.isWifiEnabled()); + mMySync.expectedState = STATE_NULL; + } + + @Override + protected void tearDown() throws Exception { + mWifiLock.release(); + mContext.unregisterReceiver(mReceiver); + if (!mWifiManager.isWifiEnabled()) + setWifiEnabled(true); + Thread.sleep(DURATION); + super.tearDown(); + } + + private void setWifiEnabled(boolean enable) throws Exception { + synchronized (mMySync) { + mMySync.expectedState = STATE_WIFI_CHANGING; + assertTrue(mWifiManager.setWifiEnabled(enable)); + long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; + while (System.currentTimeMillis() < timeout + && mMySync.expectedState == STATE_WIFI_CHANGING) + mMySync.wait(WAIT_MSEC); + } + } + + private void startScan() throws Exception { + synchronized (mMySync) { + mMySync.expectedState = STATE_SCANING; + assertTrue(mWifiManager.startScan()); + long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; + while (System.currentTimeMillis() < timeout && mMySync.expectedState == STATE_SCANING) + mMySync.wait(WAIT_MSEC); + } + } + + private boolean existSSID(String ssid) { + for (final WifiConfiguration w : mWifiManager.getConfiguredNetworks()) { + if (w.SSID.equals(ssid)) + return true; + } + return false; + } + + private int findConfiguredNetworks(String SSID, List networks) { + for (final WifiConfiguration w : networks) { + if (w.SSID.equals(SSID)) + return networks.indexOf(w); + } + return -1; + } + + private void assertDisableOthers(WifiConfiguration wifiConfiguration, boolean disableOthers) { + for (WifiConfiguration w : mWifiManager.getConfiguredNetworks()) { + if ((!w.SSID.equals(wifiConfiguration.SSID)) && w.status != Status.CURRENT) { + if (disableOthers) + assertEquals(Status.DISABLED, w.status); + } + } + } + + /** + * test point of wifiManager actions: + * 1.reconnect + * 2.reassociate + * 3.disconnect + * 4.pingSupplicant + * 5.satrtScan + */ + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "isWifiEnabled", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "setWifiEnabled", + args = {boolean.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "startScan", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getScanResults", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "pingSupplicant", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "reassociate", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "reconnect", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "disconnect", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "createWifiLock", + args = {int.class, String.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "createWifiLock", + args = {String.class} + ) + }) + public void testWifiManagerActions() throws Exception { + assertTrue(mWifiManager.reconnect()); + assertTrue(mWifiManager.reassociate()); + assertTrue(mWifiManager.disconnect()); + assertTrue(mWifiManager.pingSupplicant()); + startScan(); + setWifiEnabled(false); + Thread.sleep(DURATION); + assertFalse(mWifiManager.pingSupplicant()); + final String TAG = "Test"; + assertNotNull(mWifiManager.createWifiLock(TAG)); + assertNotNull(mWifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, TAG)); + } + + /** + * test point of wifiManager properties: + * 1.enable properties + * 2.DhcpInfo properties + * 3.wifi state + * 4.ConnectionInfo + */ + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "isWifiEnabled", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getWifiState", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "setWifiEnabled", + args = {boolean.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getConnectionInfo", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getDhcpInfo", + args = {} + ) + }) + public void testWifiManagerProperties() throws Exception { + setWifiEnabled(true); + assertTrue(mWifiManager.isWifiEnabled()); + assertNotNull(mWifiManager.getDhcpInfo()); + assertEquals(WifiManager.WIFI_STATE_ENABLED, mWifiManager.getWifiState()); + mWifiManager.getConnectionInfo(); + setWifiEnabled(false); + assertFalse(mWifiManager.isWifiEnabled()); + } + + /** + * test point of wifiManager NetWork: + * 1.add NetWork + * 2.update NetWork + * 3.remove NetWork + * 4.enable NetWork + * 5.disable NetWork + * 6.configured Networks + * 7.save configure; + */ + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "isWifiEnabled", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "setWifiEnabled", + args = {boolean.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getConfiguredNetworks", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "addNetwork", + args = {android.net.wifi.WifiConfiguration.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "updateNetwork", + args = {android.net.wifi.WifiConfiguration.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "removeNetwork", + args = {int.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "enableNetwork", + args = {int.class, boolean.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "disableNetwork", + args = {int.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "saveConfiguration", + args = {} + ) + }) + public void testWifiManagerNetWork() throws Exception { + WifiConfiguration wifiConfiguration; + // add a WifiConfig + final int notExist = -1; + List wifiConfiguredNetworks = mWifiManager.getConfiguredNetworks(); + int pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); + if (notExist != pos) { + wifiConfiguration = wifiConfiguredNetworks.get(pos); + mWifiManager.removeNetwork(wifiConfiguration.networkId); + } + pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); + assertEquals(notExist, pos); + final int size = wifiConfiguredNetworks.size(); + + wifiConfiguration = new WifiConfiguration(); + wifiConfiguration.SSID = SSID1; + int netId = mWifiManager.addNetwork(wifiConfiguration); + assertTrue(existSSID(SSID1)); + + wifiConfiguredNetworks = mWifiManager.getConfiguredNetworks(); + assertEquals(size + 1, wifiConfiguredNetworks.size()); + pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); + assertTrue(notExist != pos); + + // Enable & disable network + boolean disableOthers = false; + assertTrue(mWifiManager.enableNetwork(netId, disableOthers)); + wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); + assertDisableOthers(wifiConfiguration, disableOthers); + assertEquals(Status.ENABLED, wifiConfiguration.status); + disableOthers = true; + assertTrue(mWifiManager.enableNetwork(netId, disableOthers)); + wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); + assertDisableOthers(wifiConfiguration, disableOthers); + + assertTrue(mWifiManager.disableNetwork(netId)); + wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); + assertEquals(Status.DISABLED, wifiConfiguration.status); + + // Update a WifiConfig + wifiConfiguration = wifiConfiguredNetworks.get(pos); + wifiConfiguration.SSID = SSID2; + netId = mWifiManager.updateNetwork(wifiConfiguration); + assertFalse(existSSID(SSID1)); + assertTrue(existSSID(SSID2)); + + // Remove a WifiConfig + assertTrue(mWifiManager.removeNetwork(netId)); + assertFalse(mWifiManager.removeNetwork(notExist)); + assertFalse(existSSID(SSID1)); + assertFalse(existSSID(SSID2)); + + assertTrue(mWifiManager.saveConfiguration()); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "compareSignalLevel", + args = {int.class, int.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "calculateSignalLevel", + args = {int.class, int.class} + ) + }) + public void testSignal() { + final int numLevels = 9; + int expectLevel = 0; + assertEquals(expectLevel, WifiManager.calculateSignalLevel(MIN_RSSI, numLevels)); + assertEquals(numLevels - 1, WifiManager.calculateSignalLevel(MAX_RSSI, numLevels)); + expectLevel = 4; + assertEquals(expectLevel, WifiManager.calculateSignalLevel((MIN_RSSI + MAX_RSSI) / 2, + numLevels)); + int rssiA = 4; + int rssiB = 5; + assertTrue(WifiManager.compareSignalLevel(rssiA, rssiB) < 0); + rssiB = 4; + assertTrue(WifiManager.compareSignalLevel(rssiA, rssiB) == 0); + rssiA = 5; + rssiB = 4; + assertTrue(WifiManager.compareSignalLevel(rssiA, rssiB) > 0); + } +} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java new file mode 100644 index 0000000000..53150c9650 --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2008 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.wifi.cts; + +import android.content.Context; +import android.net.wifi.WifiManager; +import android.net.wifi.WifiManager.WifiLock; +import android.test.AndroidTestCase; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; + +@TestTargetClass(WifiManager.WifiLock.class) +public class WifiManager_WifiLockTest extends AndroidTestCase { + + private static final String WIFI_TAG = "WifiManager_WifiLockTest"; + + @TestTargets({ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "acquire", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "finalize", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "isHeld", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "release", + args = {} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "setReferenceCounted", + args = {boolean.class} + ), + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "toString", + args = {} + ) + }) + public void testWifiLock() { + WifiManager wm = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); + WifiLock wl = wm.createWifiLock(WIFI_TAG); + + wl.setReferenceCounted(true); + assertFalse(wl.isHeld()); + wl.acquire(); + assertTrue(wl.isHeld()); + wl.release(); + assertFalse(wl.isHeld()); + wl.acquire(); + wl.acquire(); + assertTrue(wl.isHeld()); + wl.release(); + assertTrue(wl.isHeld()); + wl.release(); + assertFalse(wl.isHeld()); + assertNotNull(wl.toString()); + try { + wl.release(); + fail("should throw out exception because release is called" + +" a greater number of times than acquire"); + } catch (RuntimeException e) { + // expected + } + + wl = wm.createWifiLock(WIFI_TAG); + wl.setReferenceCounted(false); + assertFalse(wl.isHeld()); + wl.acquire(); + assertTrue(wl.isHeld()); + wl.release(); + assertFalse(wl.isHeld()); + wl.acquire(); + wl.acquire(); + assertTrue(wl.isHeld()); + wl.release(); + assertFalse(wl.isHeld()); + assertNotNull(wl.toString()); + // should be ignored + wl.release(); + } +} From cd7a8fa37379f557cec738963f2d20db9c2b85c4 Mon Sep 17 00:00:00 2001 From: Brian Carlstrom Date: Tue, 2 Mar 2010 10:01:45 -0800 Subject: [PATCH 0040/1109] SslCertificate should provide Date interface While working on out openssl code, I found a Y2k bug that the dates from invalidate certificates could be shown as 1909 instead of 2009. The reason was because SslCertificate/BrowserActivity passed the values around as Strings even though the started as Dates (from X509Certificate) and were converted backed to Dates before presentation by BrowserActivity's reformatCertificateDate. SslCertificate now maintains date fields internally as Date objects without converting them to Strings. The constructor and String accessors, which are now @deprecated, now specify the format as an ISO 8601 date string which uses 4 digit years. BrowserActivity now reformatCertificateDate is now simply formatCertificateDate and no longer has to convert from String to Date and back to String to get proper Locale formatting. CTS SslCertificateTest also updated. --- .../android/net/http/cts/SslCertificateTest.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java b/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java index 91ca876fda..8bc84989ec 100644 --- a/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java +++ b/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java @@ -223,8 +223,7 @@ public class SslCertificateTest extends TestCase { Date date1 = new Date(System.currentTimeMillis() - 1000); Date date2 = new Date(System.currentTimeMillis()); - SslCertificate ssl = new SslCertificate("c=129", "e=weji", DateFormat.getInstance().format( - date1), DateFormat.getInstance().format(date2)); + SslCertificate ssl = new SslCertificate("c=129", "e=weji", date1, date2); Bundle saved = SslCertificate.saveState(ssl); assertTrue(saved.size() == 4); @@ -255,13 +254,13 @@ public class SslCertificateTest extends TestCase { @TestTargetNew( level = TestLevel.COMPLETE, notes = "Test getIssuedTo().", - method = "getValidNotAfter", + method = "getValidNotAfterDate", args = {} ), @TestTargetNew( level = TestLevel.COMPLETE, notes = "Test getIssuedTo().", - method = "getValidNotBefore", + method = "getValidNotBeforeDate", args = {} ), @TestTargetNew( @@ -278,8 +277,7 @@ public class SslCertificateTest extends TestCase { // new the SslCertificate instance Date date1 = new Date(System.currentTimeMillis() - 1000); Date date2 = new Date(System.currentTimeMillis()); - SslCertificate ssl = new SslCertificate(TO, BY, DateFormat.getInstance().format( - date1), DateFormat.getInstance().format(date2)); + SslCertificate ssl = new SslCertificate(TO, BY, date1, date2); DName issuedTo = ssl.getIssuedTo(); DName issuedBy = ssl.getIssuedBy(); @@ -293,8 +291,8 @@ public class SslCertificateTest extends TestCase { assertEquals("testOName", issuedBy.getOName()); assertEquals("testUName", issuedBy.getUName()); - assertEquals(DateFormat.getInstance().format(date1), ssl.getValidNotBefore()); - assertEquals(DateFormat.getInstance().format(date2), ssl.getValidNotAfter()); + assertEquals(date1, ssl.getValidNotBeforeDate()); + assertEquals(date2, ssl.getValidNotAfterDate()); final String EXPECTED = "Issued to: c=ccc,o=testOName,ou=testUName,cn=testCName;\n" + "Issued by: e=aeei,c=adb,o=testOName,ou=testUName,cn=testCName;\n"; assertEquals(EXPECTED, ssl.toString()); From c4b56b887f2c3b0e7565f59d06a717718202b44e Mon Sep 17 00:00:00 2001 From: Brett Chabot Date: Wed, 3 Mar 2010 19:16:18 -0800 Subject: [PATCH 0041/1109] Fix NetworkInfoTest#testAccessNetworkInfoProperties Bug 2483701 Change-Id: I98c0fc74471d9a7a9511c224d5eaa52542a8d68f --- tests/cts/net/src/android/net/cts/NetworkInfoTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java index d2de4e4be2..99e8e15169 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java @@ -32,7 +32,7 @@ public class NetworkInfoTest extends AndroidTestCase { public static final int TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE; public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI; - public static final String MOBILE_TYPE_NAME = "MOBILE"; + public static final String MOBILE_TYPE_NAME = "mobile"; public static final String WIFI_TYPE_NAME = "WIFI"; @TestTargets({ From 4706a3af1558331a5870c160c52039c77d8bf1c8 Mon Sep 17 00:00:00 2001 From: Dan Egnor Date: Thu, 8 Apr 2010 14:02:54 -0700 Subject: [PATCH 0042/1109] CTS test for android.net.TrafficStats Change-Id: I35fecea2a343fe2483d8c723b7f3a2d9916d47f2 --- .../src/android/net/cts/TrafficStatsTest.java | 219 ++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 tests/cts/net/src/android/net/cts/TrafficStatsTest.java diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java new file mode 100644 index 0000000000..ee37244792 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2010 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.os.Process; +import android.net.TrafficStats; +import android.test.AndroidTestCase; + +import dalvik.annotation.TestTargets; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargetClass; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.UnknownHostException; +import java.util.Random; + +@TestTargetClass(TrafficStats.class) +public class TrafficStatsTest extends AndroidTestCase { + @TestTargets({ + @TestTargetNew(level = TestLevel.SUFFICIENT, method = "getMobileTxPackets"), + @TestTargetNew(level = TestLevel.SUFFICIENT, method = "getMobileRxPackets"), + @TestTargetNew(level = TestLevel.SUFFICIENT, method = "getMobileTxBytes"), + @TestTargetNew(level = TestLevel.SUFFICIENT, method = "getMobileRxBytes") + }) + public void testGetMobileStats() { + // We can't assume a mobile network is even present in this test, so + // we simply assert that a valid value is returned. + + assertTrue(TrafficStats.getMobileTxPackets() == TrafficStats.UNSUPPORTED || + TrafficStats.getMobileTxPackets() >= 0); + assertTrue(TrafficStats.getMobileRxPackets() == TrafficStats.UNSUPPORTED || + TrafficStats.getMobileRxPackets() >= 0); + assertTrue(TrafficStats.getMobileTxBytes() == TrafficStats.UNSUPPORTED || + TrafficStats.getMobileTxBytes() >= 0); + assertTrue(TrafficStats.getMobileRxBytes() == TrafficStats.UNSUPPORTED || + TrafficStats.getMobileRxBytes() >= 0); + } + + @TestTargets({ + @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getTotalTxPackets"), + @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getTotalRxPackets"), + @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getTotalTxBytes"), + @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getTotalRxBytes"), + @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getUidTxBytes"), + @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getUidRxBytes") + }) + public void testTrafficStatsWithHostLookup() { + long txPacketsBefore = TrafficStats.getTotalTxPackets(); + long rxPacketsBefore = TrafficStats.getTotalRxPackets(); + long txBytesBefore = TrafficStats.getTotalTxBytes(); + long rxBytesBefore = TrafficStats.getTotalRxBytes(); + long uidTxBytesBefore = TrafficStats.getUidTxBytes(Process.myUid()); + long uidRxBytesBefore = TrafficStats.getUidRxBytes(Process.myUid()); + + // Look up random hostnames in a wildcard domain owned by Google. + // This will require a DNS request, which should generate traffic. + + int found = 0; + Random r = new Random(); + for (int i = 0; i < 10; i++) { + try { + String host = "test" + r.nextInt(100000) + ".clients.google.com"; + InetAddress[] addr = InetAddress.getAllByName(host); + if (addr.length > 0) found++; + } catch (UnknownHostException e) { + // Ignore -- our purpose is not to test network connectivity, + // and we'd rather have false positives than a flaky test. + } + } + + long txPacketsAfter = TrafficStats.getTotalTxPackets(); + long rxPacketsAfter = TrafficStats.getTotalRxPackets(); + long txBytesAfter = TrafficStats.getTotalTxBytes(); + long rxBytesAfter = TrafficStats.getTotalRxBytes(); + long uidTxBytesAfter = TrafficStats.getUidTxBytes(Process.myUid()); + long uidRxBytesAfter = TrafficStats.getUidRxBytes(Process.myUid()); + + // Make some conservative assertions about the data used: + // each successful resolution should exchange at least one packet, + // and at least 20 bytes in each direction. + + assertTrue("txp: " + txPacketsBefore + " [" + found + "] " + txPacketsAfter, + txPacketsAfter >= txPacketsBefore + found); + assertTrue("rxp: " + rxPacketsBefore + " [" + found + "] " + rxPacketsAfter, + rxPacketsAfter >= rxPacketsBefore + found); + assertTrue("txb: " + txBytesBefore + " [" + found + "] " + txBytesAfter, + txBytesAfter >= txBytesBefore + found * 20); + assertTrue("rxb: " + rxBytesBefore + " [" + found + "] " + rxBytesAfter, + rxBytesAfter >= rxBytesBefore + found * 20); + assertTrue("uidtxb: " + uidTxBytesBefore + " [" + found + "] " + uidTxBytesAfter, + uidTxBytesAfter >= uidTxBytesBefore + found * 20); + assertTrue("uidrxb: " + uidRxBytesBefore + " [" + found + "] " + uidRxBytesAfter, + uidRxBytesAfter >= uidRxBytesBefore + found * 20); + } + + @TestTargets({ + @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getMobileTxPackets"), + @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getMobileRxPackets"), + @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getMobileTxBytes"), + @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getMobileRxBytes"), + @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getTotalTxPackets"), + @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getTotalRxPackets"), + @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getTotalTxBytes"), + @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getTotalRxBytes"), + @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getUidTxBytes"), + @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getUidRxBytes") + }) + public void testTrafficStatsForLocalhost() throws IOException { + long mobileTxPacketsBefore = TrafficStats.getTotalTxPackets(); + long mobileRxPacketsBefore = TrafficStats.getTotalRxPackets(); + long mobileTxBytesBefore = TrafficStats.getTotalTxBytes(); + long mobileRxBytesBefore = TrafficStats.getTotalRxBytes(); + long totalTxPacketsBefore = TrafficStats.getTotalTxPackets(); + long totalRxPacketsBefore = TrafficStats.getTotalRxPackets(); + long totalTxBytesBefore = TrafficStats.getTotalTxBytes(); + long totalRxBytesBefore = TrafficStats.getTotalRxBytes(); + long uidTxBytesBefore = TrafficStats.getUidTxBytes(Process.myUid()); + long uidRxBytesBefore = TrafficStats.getUidRxBytes(Process.myUid()); + + // Transfer 1MB of data across an explicitly localhost socket. + + final ServerSocket server = new ServerSocket(0); + new Thread("TrafficStatsTest.testTrafficStatsForLocalhost") { + @Override + public void run() { + try { + Socket socket = new Socket("localhost", server.getLocalPort()); + OutputStream out = socket.getOutputStream(); + byte[] buf = new byte[1024]; + for (int i = 0; i < 1024; i++) out.write(buf); + out.close(); + socket.close(); + } catch (IOException e) { + } + } + }.start(); + + try { + Socket socket = server.accept(); + InputStream in = socket.getInputStream(); + byte[] buf = new byte[1024]; + int read = 0; + while (read < 1048576) { + int n = in.read(buf); + assertTrue("Unexpected EOF", n > 0); + read += n; + } + } finally { + server.close(); + } + + long mobileTxPacketsAfter = TrafficStats.getTotalTxPackets(); + long mobileRxPacketsAfter = TrafficStats.getTotalRxPackets(); + long mobileTxBytesAfter = TrafficStats.getTotalTxBytes(); + long mobileRxBytesAfter = TrafficStats.getTotalRxBytes(); + long totalTxPacketsAfter = TrafficStats.getTotalTxPackets(); + long totalRxPacketsAfter = TrafficStats.getTotalRxPackets(); + long totalTxBytesAfter = TrafficStats.getTotalTxBytes(); + long totalRxBytesAfter = TrafficStats.getTotalRxBytes(); + long uidTxBytesAfter = TrafficStats.getUidTxBytes(Process.myUid()); + long uidRxBytesAfter = TrafficStats.getUidRxBytes(Process.myUid()); + + // Localhost traffic should *not* count against mobile or total stats. + // There might be some other traffic, but nowhere near 1MB. + + assertTrue("mtxp: " + mobileTxPacketsBefore + " -> " + mobileTxPacketsAfter, + mobileTxPacketsAfter >= mobileTxPacketsBefore && + mobileTxPacketsAfter <= mobileTxPacketsBefore + 500); + assertTrue("mrxp: " + mobileRxPacketsBefore + " -> " + mobileRxPacketsAfter, + mobileRxPacketsAfter >= mobileRxPacketsBefore && + mobileRxPacketsAfter <= mobileRxPacketsBefore + 500); + assertTrue("mtxb: " + mobileTxBytesBefore + " -> " + mobileTxBytesAfter, + mobileTxBytesAfter >= mobileTxBytesBefore && + mobileTxBytesAfter <= mobileTxBytesBefore + 200000); + assertTrue("mrxb: " + mobileRxBytesBefore + " -> " + mobileRxBytesAfter, + mobileRxBytesAfter >= mobileRxBytesBefore && + mobileRxBytesAfter <= mobileRxBytesBefore + 200000); + + assertTrue("ttxp: " + totalTxPacketsBefore + " -> " + totalTxPacketsAfter, + totalTxPacketsAfter >= totalTxPacketsBefore && + totalTxPacketsAfter <= totalTxPacketsBefore + 500); + assertTrue("trxp: " + totalRxPacketsBefore + " -> " + totalRxPacketsAfter, + totalRxPacketsAfter >= totalRxPacketsBefore && + totalRxPacketsAfter <= totalRxPacketsBefore + 500); + assertTrue("ttxb: " + totalTxBytesBefore + " -> " + totalTxBytesAfter, + totalTxBytesAfter >= totalTxBytesBefore && + totalTxBytesAfter <= totalTxBytesBefore + 200000); + assertTrue("trxb: " + totalRxBytesBefore + " -> " + totalRxBytesAfter, + totalRxBytesAfter >= totalRxBytesBefore && + totalRxBytesAfter <= totalRxBytesBefore + 200000); + + // Localhost traffic *does* count against per-UID stats. + assertTrue("uidtxb: " + uidTxBytesBefore + " -> " + uidTxBytesAfter, + uidTxBytesAfter >= uidTxBytesBefore + 1048576); + assertTrue("uidrxb: " + uidRxBytesBefore + " -> " + uidRxBytesAfter, + uidRxBytesAfter >= uidRxBytesBefore + 1048576); + } +} From 20a98ac150770c7316392a8c7ac73bec63b0e1b7 Mon Sep 17 00:00:00 2001 From: Brian Muramatsu Date: Wed, 2 Jun 2010 16:12:05 -0700 Subject: [PATCH 0043/1109] Prohibit Listening Ports on Devices Bug 2732034 Check that devices do not have any listening ports open by scanning files in the /proc/net directory. Change-Id: Ic6204667809b3a0c136e38f35fe536bc6d79dcad --- .../android/net/cts/ListeningPortsTest.java | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 tests/cts/net/src/android/net/cts/ListeningPortsTest.java diff --git a/tests/cts/net/src/android/net/cts/ListeningPortsTest.java b/tests/cts/net/src/android/net/cts/ListeningPortsTest.java new file mode 100644 index 0000000000..ff6b4e9d94 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/ListeningPortsTest.java @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2010 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 java.io.File; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; +import java.util.regex.Pattern; + +import junit.framework.TestCase; + +public class ListeningPortsTest extends TestCase { + + /** Address patterns used to check whether we're checking the right column in /proc/net. */ + private static final List ADDRESS_PATTERNS = new ArrayList(2); + + static { + ADDRESS_PATTERNS.add("[0-9A-F]{8}:[0-9A-F]{4}"); + ADDRESS_PATTERNS.add("[0-9A-F]{32}:[0-9A-F]{4}"); + } + + /** Ports that are allowed to be listening on the emulator. */ + private static final List EXCEPTION_PATTERNS = new ArrayList(6); + + static { + // IPv4 exceptions + EXCEPTION_PATTERNS.add("00000000:15B3"); // 0.0.0.0:5555 - emulator port + EXCEPTION_PATTERNS.add("0F02000A:15B3"); // 10.0.2.15:5555 - net forwarding for emulator + EXCEPTION_PATTERNS.add("[0-9A-F]{6}7F:[0-9A-F]{4}"); // IPv4 Loopback + + // IPv6 exceptions + EXCEPTION_PATTERNS.add("[0]{31}1:[0-9A-F]{4}"); // IPv6 Loopback + EXCEPTION_PATTERNS.add("[0]{16}[0]{4}[0]{4}[0-9A-F]{6}7F:[0-9A-F]{4}"); // IPv4-6 Conversion + EXCEPTION_PATTERNS.add("[0]{16}[F]{4}[0]{4}[0-9A-F]{6}7F:[0-9A-F]{4}"); // IPv4-6 Conversion + } + + public static void testNoListeningPorts() { + final boolean isTcp = true; + assertNoListeningPorts("/proc/net/tcp", isTcp); + assertNoListeningPorts("/proc/net/tcp6", isTcp); + assertNoListeningPorts("/proc/net/udp", !isTcp); + assertNoListeningPorts("/proc/net/udp6", !isTcp); + } + + private static void assertNoListeningPorts(String procFilePath, boolean isTcp) { + + /* + * Sample output of "cat /proc/net/tcp" on emulator: + * + * sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid ... + * 0: 0100007F:13AD 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 ... + * 1: 00000000:15B3 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 ... + * 2: 0F02000A:15B3 0202000A:CE8A 01 00000000:00000000 00:00000000 00000000 0 ... + * + */ + + File procFile = new File(procFilePath); + Scanner scanner = null; + try { + scanner = new Scanner(procFile); + while (scanner.hasNextLine()) { + String line = scanner.nextLine().trim(); + + // Skip column headers + if (line.startsWith("sl")) { + continue; + } + + String[] fields = line.split("\\s+"); + final int expectedNumColumns = 12; + assertTrue(procFilePath + " should have at least " + expectedNumColumns + + " columns of output " + fields, fields.length >= expectedNumColumns); + + String localAddress = fields[1]; + String state = fields[3]; + + assertTrue(procFilePath + " should have an IP address in the second column", + isAddress(localAddress)); + + if (!isException(localAddress) && isPortListening(state, isTcp)) { + fail("Found port listening on " + localAddress + " in " + procFilePath); + } + } + } catch (FileNotFoundException notFound) { + fail("Could not open file " + procFilePath + " to check for listening ports."); + } finally { + if (scanner != null) { + scanner.close(); + } + } + } + + private static boolean isAddress(String localAddress) { + return isPatternMatch(ADDRESS_PATTERNS, localAddress); + } + + private static boolean isException(String localAddress) { + return isPatternMatch(EXCEPTION_PATTERNS, localAddress); + } + + private static boolean isPatternMatch(List patterns, String input) { + for (String pattern : patterns) { + if (Pattern.matches(pattern, input)) { + return true; + } + } + return false; + } + + private static boolean isPortListening(String state, boolean isTcp) { + // 0A = TCP_LISTEN from include/net/tcp_states.h + String listeningState = isTcp ? "0A" : "07"; + return listeningState.equals(state); + } +} From 878dd15dce911a6346b767169054a7c4546149ad Mon Sep 17 00:00:00 2001 From: DongseokYi Date: Thu, 16 Sep 2010 11:44:04 +0900 Subject: [PATCH 0044/1109] Need enough time (1 sec) to read amounts of packet from /proc/stat_uid/[uid]/tcp_snd. Change-Id: I93fdd1bc383e8b944a76e211166e2c5fdb9707cd --- tests/cts/net/src/android/net/cts/TrafficStatsTest.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java index ee37244792..9d23a874da 100644 --- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java +++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java @@ -170,6 +170,12 @@ public class TrafficStatsTest extends AndroidTestCase { server.close(); } + // It's too fast to call getUidTxBytes function. + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + } + long mobileTxPacketsAfter = TrafficStats.getTotalTxPackets(); long mobileRxPacketsAfter = TrafficStats.getTotalRxPackets(); long mobileTxBytesAfter = TrafficStats.getTotalTxBytes(); From bf0563335889cb898963324192870878042b9b29 Mon Sep 17 00:00:00 2001 From: Brian Carlstrom Date: Wed, 22 Sep 2010 17:13:29 -0700 Subject: [PATCH 0045/1109] Create CTS test for SSL hostname checks Bug: 2807618 Change-Id: I05b051d779850e51eabea0880400273cdcc2f748 --- .../cts/SSLCertificateSocketFactoryTest.java | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java index 6cd5d6f10b..258ac4db1c 100644 --- a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java +++ b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java @@ -21,6 +21,7 @@ import java.net.InetAddress; import java.net.Socket; import javax.net.SocketFactory; +import javax.net.ssl.SSLPeerUnverifiedException; import android.net.SSLCertificateSocketFactory; import android.test.AndroidTestCase; @@ -141,4 +142,73 @@ public class SSLCertificateSocketFactoryTest extends AndroidTestCase { // The socket level is invalid. } + // a host and port that are expected to be available but have + // a cert with a different CN, in this case CN=mtalk.google.com + private static String TEST_CREATE_SOCKET_HOST = "mobile-gtalk.l.google.com"; + private static int TEST_CREATE_SOCKET_PORT = 5228; + + /** + * b/2807618 Make sure that hostname verifcation in cases were it + * is documented to be included by various + * SSLCertificateSocketFactory.createSocket messages. + * + * NOTE: Test will fail if external server is not available. + */ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "createSocket", + args = {String.class, int.class} + ) + public void test_createSocket_simple() throws Exception { + try { + mFactory.createSocket(TEST_CREATE_SOCKET_HOST, TEST_CREATE_SOCKET_PORT); + fail(); + } catch (SSLPeerUnverifiedException expected) { + // expected + } + } + + /** + * b/2807618 Make sure that hostname verifcation in cases were it + * is documented to be included by various + * SSLCertificateSocketFactory.createSocket messages. + * + * NOTE: Test will fail if external server is not available. + */ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "createSocket", + args = {Socket.class, String.class, int.class, boolean.class} + ) + public void test_createSocket_wrapping() throws Exception { + try { + Socket underlying = new Socket(TEST_CREATE_SOCKET_HOST, TEST_CREATE_SOCKET_PORT); + mFactory.createSocket( + underlying, TEST_CREATE_SOCKET_HOST, TEST_CREATE_SOCKET_PORT, true); + fail(); + } catch (SSLPeerUnverifiedException expected) { + // expected + } + } + + /** + * b/2807618 Make sure that hostname verifcation in cases were it + * is documented to be included by various + * SSLCertificateSocketFactory.createSocket messages. + * + * NOTE: Test will fail if external server is not available. + */ + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "createSocket", + args = {String.class, int.class, InetAddress.class, int.class} + ) + public void test_createSocket_bind() throws Exception { + try { + mFactory.createSocket(TEST_CREATE_SOCKET_HOST, TEST_CREATE_SOCKET_PORT, null, 0); + fail(); + } catch (SSLPeerUnverifiedException expected) { + // expected + } + } } From 5ff0ab314c7af98e2ab81dde3fc7d03450cc1ab9 Mon Sep 17 00:00:00 2001 From: Brian Muramatsu Date: Wed, 20 Oct 2010 15:04:28 -0700 Subject: [PATCH 0046/1109] Delete CM#testAccessNetworkPreference Test Bug 3106981 ConnectivityManager#setNetworkPreference used to be synchronous, but now it merely sends a handler message. As a result, the method won't throw any SecurityExceptions, because it will throw it in the handler instead when trying to write to System.Secure settings. The test tries to write invalid settings or the same settings value to test that it won't throw a SecurityException. Since the method won't throw the exceptions anymore and its not clear how long to wait to confirm that the settings weren't going to be changed, just delete these tests. Change-Id: I9e754bb0e026656511512b17108c42c37d84b069 --- .../net/cts/ConnectivityManagerTest.java | 61 ------------------- 1 file changed, 61 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index edcea9a24e..cfe087227c 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -97,67 +97,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { assertFalse(ConnectivityManager.isNetworkTypeValid(-1)); } - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getNetworkPreference", - args = {} - ), - @TestTargetNew( - level = TestLevel.SUFFICIENT, - method = "setNetworkPreference", - args = {int.class} - ) - }) - public void testAccessNetworkPreference() { - int initialSetting = mCm.getNetworkPreference(); - - // Changing the network preference requires android.permission.WRITE_SECURE_SETTINGS, - // which is only available to signed or system applications. - - // Setting the same preference that is already set is a no-op and does not throw - // a SecurityException. - mCm.setNetworkPreference(initialSetting); - assertEquals(initialSetting, mCm.getNetworkPreference()); - - // find a valid setting that is different from the initial setting - int validSetting = -1; - NetworkInfo[] ni = mCm.getAllNetworkInfo(); - for (NetworkInfo n : ni) { - int type = n.getType(); - if (type != initialSetting) { - validSetting = type; - break; - } - } - if (validSetting >= 0) { - try { - mCm.setNetworkPreference(validSetting); - fail("Trying to change the network preference should throw SecurityException"); - } catch (SecurityException expected) { - // expected - } - } - - // find an invalid setting - int invalidSetting = -1; - for (int i = 0; i < 10; i++) { - if (!ConnectivityManager.isNetworkTypeValid(i)) { - invalidSetting = i; - break; - } - } - if (invalidSetting >= 0) { - // illegal setting should be ignored - mCm.setNetworkPreference(invalidSetting); - assertEquals(initialSetting, mCm.getNetworkPreference()); - } - - // illegal setting should be ignored - mCm.setNetworkPreference(-1); - assertEquals(initialSetting, mCm.getNetworkPreference()); - } - @TestTargetNew( level = TestLevel.COMPLETE, notes = "Test getAllNetworkInfo().", From bfc98683699ac45dc0cc787bace8e64dc4c5909c Mon Sep 17 00:00:00 2001 From: Brett Chabot Date: Fri, 12 Nov 2010 17:20:23 -0800 Subject: [PATCH 0047/1109] Stop WifiManagerTest from disabling current network. Bug 3181376 Change-Id: I93fa28f20a36b2cc90fbe0a59bbfbac758855c3a --- .../android/net/wifi/cts/WifiManagerTest.java | 139 +++++++++++------- 1 file changed, 86 insertions(+), 53 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 132ca9247d..e2a583b6ef 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -16,7 +16,10 @@ package android.net.wifi.cts; -import java.util.List; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; import android.content.BroadcastReceiver; import android.content.Context; @@ -28,10 +31,11 @@ import android.net.wifi.WifiManager; import android.net.wifi.WifiConfiguration.Status; import android.net.wifi.WifiManager.WifiLock; import android.test.AndroidTestCase; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargets; +import android.util.Log; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; @TestTargetClass(WifiManager.class) public class WifiManagerTest extends AndroidTestCase { @@ -341,58 +345,87 @@ public class WifiManagerTest extends AndroidTestCase { ) }) public void testWifiManagerNetWork() throws Exception { - WifiConfiguration wifiConfiguration; - // add a WifiConfig - final int notExist = -1; - List wifiConfiguredNetworks = mWifiManager.getConfiguredNetworks(); - int pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); - if (notExist != pos) { + // store the list of enabled networks, so they can be re-enabled after test completes + Set enabledSsids = getEnabledNetworks(mWifiManager.getConfiguredNetworks()); + try { + WifiConfiguration wifiConfiguration; + // add a WifiConfig + final int notExist = -1; + List wifiConfiguredNetworks = mWifiManager.getConfiguredNetworks(); + int pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); + if (notExist != pos) { + wifiConfiguration = wifiConfiguredNetworks.get(pos); + mWifiManager.removeNetwork(wifiConfiguration.networkId); + } + pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); + assertEquals(notExist, pos); + final int size = wifiConfiguredNetworks.size(); + + wifiConfiguration = new WifiConfiguration(); + wifiConfiguration.SSID = SSID1; + int netId = mWifiManager.addNetwork(wifiConfiguration); + assertTrue(existSSID(SSID1)); + + wifiConfiguredNetworks = mWifiManager.getConfiguredNetworks(); + assertEquals(size + 1, wifiConfiguredNetworks.size()); + pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); + assertTrue(notExist != pos); + + // Enable & disable network + boolean disableOthers = false; + assertTrue(mWifiManager.enableNetwork(netId, disableOthers)); + wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); + assertDisableOthers(wifiConfiguration, disableOthers); + assertEquals(Status.ENABLED, wifiConfiguration.status); + disableOthers = true; + + assertTrue(mWifiManager.enableNetwork(netId, disableOthers)); + wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); + assertDisableOthers(wifiConfiguration, disableOthers); + + assertTrue(mWifiManager.disableNetwork(netId)); + wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); + assertEquals(Status.DISABLED, wifiConfiguration.status); + + // Update a WifiConfig wifiConfiguration = wifiConfiguredNetworks.get(pos); - mWifiManager.removeNetwork(wifiConfiguration.networkId); + wifiConfiguration.SSID = SSID2; + netId = mWifiManager.updateNetwork(wifiConfiguration); + assertFalse(existSSID(SSID1)); + assertTrue(existSSID(SSID2)); + + // Remove a WifiConfig + assertTrue(mWifiManager.removeNetwork(netId)); + assertFalse(mWifiManager.removeNetwork(notExist)); + assertFalse(existSSID(SSID1)); + assertFalse(existSSID(SSID2)); + + assertTrue(mWifiManager.saveConfiguration()); + } finally { + reEnableNetworks(enabledSsids, mWifiManager.getConfiguredNetworks()); + mWifiManager.saveConfiguration(); } - pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); - assertEquals(notExist, pos); - final int size = wifiConfiguredNetworks.size(); + } - wifiConfiguration = new WifiConfiguration(); - wifiConfiguration.SSID = SSID1; - int netId = mWifiManager.addNetwork(wifiConfiguration); - assertTrue(existSSID(SSID1)); + private Set getEnabledNetworks(List configuredNetworks) { + Set ssids = new HashSet(); + for (WifiConfiguration wifiConfig : configuredNetworks) { + if (Status.ENABLED == wifiConfig.status || Status.CURRENT == wifiConfig.status) { + ssids.add(wifiConfig.SSID); + Log.i(TAG, String.format("remembering enabled network %s", wifiConfig.SSID)); + } + } + return ssids; + } - wifiConfiguredNetworks = mWifiManager.getConfiguredNetworks(); - assertEquals(size + 1, wifiConfiguredNetworks.size()); - pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); - assertTrue(notExist != pos); - - // Enable & disable network - boolean disableOthers = false; - assertTrue(mWifiManager.enableNetwork(netId, disableOthers)); - wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); - assertDisableOthers(wifiConfiguration, disableOthers); - assertEquals(Status.ENABLED, wifiConfiguration.status); - disableOthers = true; - assertTrue(mWifiManager.enableNetwork(netId, disableOthers)); - wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); - assertDisableOthers(wifiConfiguration, disableOthers); - - assertTrue(mWifiManager.disableNetwork(netId)); - wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); - assertEquals(Status.DISABLED, wifiConfiguration.status); - - // Update a WifiConfig - wifiConfiguration = wifiConfiguredNetworks.get(pos); - wifiConfiguration.SSID = SSID2; - netId = mWifiManager.updateNetwork(wifiConfiguration); - assertFalse(existSSID(SSID1)); - assertTrue(existSSID(SSID2)); - - // Remove a WifiConfig - assertTrue(mWifiManager.removeNetwork(netId)); - assertFalse(mWifiManager.removeNetwork(notExist)); - assertFalse(existSSID(SSID1)); - assertFalse(existSSID(SSID2)); - - assertTrue(mWifiManager.saveConfiguration()); + private void reEnableNetworks(Set enabledSsids, + List configuredNetworks) { + for (WifiConfiguration wifiConfig : configuredNetworks) { + if (enabledSsids.contains(wifiConfig.SSID)) { + mWifiManager.enableNetwork(wifiConfig.networkId, false); + Log.i(TAG, String.format("re-enabling network %s", wifiConfig.SSID)); + } + } } @TestTargets({ From c97dbae9d4b05eb98ad1e170196ba3cef7724993 Mon Sep 17 00:00:00 2001 From: Brett Chabot Date: Fri, 12 Nov 2010 17:20:23 -0800 Subject: [PATCH 0048/1109] Stop WifiManagerTest from disabling current network. Bug 3181376 Change-Id: I7dad90ba830678357b900709359f10319070c96e --- .../android/net/wifi/cts/WifiManagerTest.java | 139 +++++++++++------- 1 file changed, 86 insertions(+), 53 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 132ca9247d..e2a583b6ef 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -16,7 +16,10 @@ package android.net.wifi.cts; -import java.util.List; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; import android.content.BroadcastReceiver; import android.content.Context; @@ -28,10 +31,11 @@ import android.net.wifi.WifiManager; import android.net.wifi.WifiConfiguration.Status; import android.net.wifi.WifiManager.WifiLock; import android.test.AndroidTestCase; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargets; +import android.util.Log; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; @TestTargetClass(WifiManager.class) public class WifiManagerTest extends AndroidTestCase { @@ -341,58 +345,87 @@ public class WifiManagerTest extends AndroidTestCase { ) }) public void testWifiManagerNetWork() throws Exception { - WifiConfiguration wifiConfiguration; - // add a WifiConfig - final int notExist = -1; - List wifiConfiguredNetworks = mWifiManager.getConfiguredNetworks(); - int pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); - if (notExist != pos) { + // store the list of enabled networks, so they can be re-enabled after test completes + Set enabledSsids = getEnabledNetworks(mWifiManager.getConfiguredNetworks()); + try { + WifiConfiguration wifiConfiguration; + // add a WifiConfig + final int notExist = -1; + List wifiConfiguredNetworks = mWifiManager.getConfiguredNetworks(); + int pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); + if (notExist != pos) { + wifiConfiguration = wifiConfiguredNetworks.get(pos); + mWifiManager.removeNetwork(wifiConfiguration.networkId); + } + pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); + assertEquals(notExist, pos); + final int size = wifiConfiguredNetworks.size(); + + wifiConfiguration = new WifiConfiguration(); + wifiConfiguration.SSID = SSID1; + int netId = mWifiManager.addNetwork(wifiConfiguration); + assertTrue(existSSID(SSID1)); + + wifiConfiguredNetworks = mWifiManager.getConfiguredNetworks(); + assertEquals(size + 1, wifiConfiguredNetworks.size()); + pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); + assertTrue(notExist != pos); + + // Enable & disable network + boolean disableOthers = false; + assertTrue(mWifiManager.enableNetwork(netId, disableOthers)); + wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); + assertDisableOthers(wifiConfiguration, disableOthers); + assertEquals(Status.ENABLED, wifiConfiguration.status); + disableOthers = true; + + assertTrue(mWifiManager.enableNetwork(netId, disableOthers)); + wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); + assertDisableOthers(wifiConfiguration, disableOthers); + + assertTrue(mWifiManager.disableNetwork(netId)); + wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); + assertEquals(Status.DISABLED, wifiConfiguration.status); + + // Update a WifiConfig wifiConfiguration = wifiConfiguredNetworks.get(pos); - mWifiManager.removeNetwork(wifiConfiguration.networkId); + wifiConfiguration.SSID = SSID2; + netId = mWifiManager.updateNetwork(wifiConfiguration); + assertFalse(existSSID(SSID1)); + assertTrue(existSSID(SSID2)); + + // Remove a WifiConfig + assertTrue(mWifiManager.removeNetwork(netId)); + assertFalse(mWifiManager.removeNetwork(notExist)); + assertFalse(existSSID(SSID1)); + assertFalse(existSSID(SSID2)); + + assertTrue(mWifiManager.saveConfiguration()); + } finally { + reEnableNetworks(enabledSsids, mWifiManager.getConfiguredNetworks()); + mWifiManager.saveConfiguration(); } - pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); - assertEquals(notExist, pos); - final int size = wifiConfiguredNetworks.size(); + } - wifiConfiguration = new WifiConfiguration(); - wifiConfiguration.SSID = SSID1; - int netId = mWifiManager.addNetwork(wifiConfiguration); - assertTrue(existSSID(SSID1)); + private Set getEnabledNetworks(List configuredNetworks) { + Set ssids = new HashSet(); + for (WifiConfiguration wifiConfig : configuredNetworks) { + if (Status.ENABLED == wifiConfig.status || Status.CURRENT == wifiConfig.status) { + ssids.add(wifiConfig.SSID); + Log.i(TAG, String.format("remembering enabled network %s", wifiConfig.SSID)); + } + } + return ssids; + } - wifiConfiguredNetworks = mWifiManager.getConfiguredNetworks(); - assertEquals(size + 1, wifiConfiguredNetworks.size()); - pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); - assertTrue(notExist != pos); - - // Enable & disable network - boolean disableOthers = false; - assertTrue(mWifiManager.enableNetwork(netId, disableOthers)); - wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); - assertDisableOthers(wifiConfiguration, disableOthers); - assertEquals(Status.ENABLED, wifiConfiguration.status); - disableOthers = true; - assertTrue(mWifiManager.enableNetwork(netId, disableOthers)); - wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); - assertDisableOthers(wifiConfiguration, disableOthers); - - assertTrue(mWifiManager.disableNetwork(netId)); - wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); - assertEquals(Status.DISABLED, wifiConfiguration.status); - - // Update a WifiConfig - wifiConfiguration = wifiConfiguredNetworks.get(pos); - wifiConfiguration.SSID = SSID2; - netId = mWifiManager.updateNetwork(wifiConfiguration); - assertFalse(existSSID(SSID1)); - assertTrue(existSSID(SSID2)); - - // Remove a WifiConfig - assertTrue(mWifiManager.removeNetwork(netId)); - assertFalse(mWifiManager.removeNetwork(notExist)); - assertFalse(existSSID(SSID1)); - assertFalse(existSSID(SSID2)); - - assertTrue(mWifiManager.saveConfiguration()); + private void reEnableNetworks(Set enabledSsids, + List configuredNetworks) { + for (WifiConfiguration wifiConfig : configuredNetworks) { + if (enabledSsids.contains(wifiConfig.SSID)) { + mWifiManager.enableNetwork(wifiConfig.networkId, false); + Log.i(TAG, String.format("re-enabling network %s", wifiConfig.SSID)); + } + } } @TestTargets({ From 9e410175ba43c445caaf67652ae0eaee9a1a188a Mon Sep 17 00:00:00 2001 From: Brett Chabot Date: Fri, 12 Nov 2010 17:20:23 -0800 Subject: [PATCH 0049/1109] Stop WifiManagerTest from disabling current network. Bug 3181376 Change-Id: Ia8d12a10f4ed0c46325e76f1dffeef93412a55e5 --- .../android/net/wifi/cts/WifiManagerTest.java | 139 +++++++++++------- 1 file changed, 86 insertions(+), 53 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 132ca9247d..e2a583b6ef 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -16,7 +16,10 @@ package android.net.wifi.cts; -import java.util.List; +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; import android.content.BroadcastReceiver; import android.content.Context; @@ -28,10 +31,11 @@ import android.net.wifi.WifiManager; import android.net.wifi.WifiConfiguration.Status; import android.net.wifi.WifiManager.WifiLock; import android.test.AndroidTestCase; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargets; +import android.util.Log; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; @TestTargetClass(WifiManager.class) public class WifiManagerTest extends AndroidTestCase { @@ -341,58 +345,87 @@ public class WifiManagerTest extends AndroidTestCase { ) }) public void testWifiManagerNetWork() throws Exception { - WifiConfiguration wifiConfiguration; - // add a WifiConfig - final int notExist = -1; - List wifiConfiguredNetworks = mWifiManager.getConfiguredNetworks(); - int pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); - if (notExist != pos) { + // store the list of enabled networks, so they can be re-enabled after test completes + Set enabledSsids = getEnabledNetworks(mWifiManager.getConfiguredNetworks()); + try { + WifiConfiguration wifiConfiguration; + // add a WifiConfig + final int notExist = -1; + List wifiConfiguredNetworks = mWifiManager.getConfiguredNetworks(); + int pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); + if (notExist != pos) { + wifiConfiguration = wifiConfiguredNetworks.get(pos); + mWifiManager.removeNetwork(wifiConfiguration.networkId); + } + pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); + assertEquals(notExist, pos); + final int size = wifiConfiguredNetworks.size(); + + wifiConfiguration = new WifiConfiguration(); + wifiConfiguration.SSID = SSID1; + int netId = mWifiManager.addNetwork(wifiConfiguration); + assertTrue(existSSID(SSID1)); + + wifiConfiguredNetworks = mWifiManager.getConfiguredNetworks(); + assertEquals(size + 1, wifiConfiguredNetworks.size()); + pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); + assertTrue(notExist != pos); + + // Enable & disable network + boolean disableOthers = false; + assertTrue(mWifiManager.enableNetwork(netId, disableOthers)); + wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); + assertDisableOthers(wifiConfiguration, disableOthers); + assertEquals(Status.ENABLED, wifiConfiguration.status); + disableOthers = true; + + assertTrue(mWifiManager.enableNetwork(netId, disableOthers)); + wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); + assertDisableOthers(wifiConfiguration, disableOthers); + + assertTrue(mWifiManager.disableNetwork(netId)); + wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); + assertEquals(Status.DISABLED, wifiConfiguration.status); + + // Update a WifiConfig wifiConfiguration = wifiConfiguredNetworks.get(pos); - mWifiManager.removeNetwork(wifiConfiguration.networkId); + wifiConfiguration.SSID = SSID2; + netId = mWifiManager.updateNetwork(wifiConfiguration); + assertFalse(existSSID(SSID1)); + assertTrue(existSSID(SSID2)); + + // Remove a WifiConfig + assertTrue(mWifiManager.removeNetwork(netId)); + assertFalse(mWifiManager.removeNetwork(notExist)); + assertFalse(existSSID(SSID1)); + assertFalse(existSSID(SSID2)); + + assertTrue(mWifiManager.saveConfiguration()); + } finally { + reEnableNetworks(enabledSsids, mWifiManager.getConfiguredNetworks()); + mWifiManager.saveConfiguration(); } - pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); - assertEquals(notExist, pos); - final int size = wifiConfiguredNetworks.size(); + } - wifiConfiguration = new WifiConfiguration(); - wifiConfiguration.SSID = SSID1; - int netId = mWifiManager.addNetwork(wifiConfiguration); - assertTrue(existSSID(SSID1)); + private Set getEnabledNetworks(List configuredNetworks) { + Set ssids = new HashSet(); + for (WifiConfiguration wifiConfig : configuredNetworks) { + if (Status.ENABLED == wifiConfig.status || Status.CURRENT == wifiConfig.status) { + ssids.add(wifiConfig.SSID); + Log.i(TAG, String.format("remembering enabled network %s", wifiConfig.SSID)); + } + } + return ssids; + } - wifiConfiguredNetworks = mWifiManager.getConfiguredNetworks(); - assertEquals(size + 1, wifiConfiguredNetworks.size()); - pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); - assertTrue(notExist != pos); - - // Enable & disable network - boolean disableOthers = false; - assertTrue(mWifiManager.enableNetwork(netId, disableOthers)); - wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); - assertDisableOthers(wifiConfiguration, disableOthers); - assertEquals(Status.ENABLED, wifiConfiguration.status); - disableOthers = true; - assertTrue(mWifiManager.enableNetwork(netId, disableOthers)); - wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); - assertDisableOthers(wifiConfiguration, disableOthers); - - assertTrue(mWifiManager.disableNetwork(netId)); - wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); - assertEquals(Status.DISABLED, wifiConfiguration.status); - - // Update a WifiConfig - wifiConfiguration = wifiConfiguredNetworks.get(pos); - wifiConfiguration.SSID = SSID2; - netId = mWifiManager.updateNetwork(wifiConfiguration); - assertFalse(existSSID(SSID1)); - assertTrue(existSSID(SSID2)); - - // Remove a WifiConfig - assertTrue(mWifiManager.removeNetwork(netId)); - assertFalse(mWifiManager.removeNetwork(notExist)); - assertFalse(existSSID(SSID1)); - assertFalse(existSSID(SSID2)); - - assertTrue(mWifiManager.saveConfiguration()); + private void reEnableNetworks(Set enabledSsids, + List configuredNetworks) { + for (WifiConfiguration wifiConfig : configuredNetworks) { + if (enabledSsids.contains(wifiConfig.SSID)) { + mWifiManager.enableNetwork(wifiConfig.networkId, false); + Log.i(TAG, String.format("re-enabling network %s", wifiConfig.SSID)); + } + } } @TestTargets({ From 5f78c57fc5a82e2f0d34668f0885654019993a2a Mon Sep 17 00:00:00 2001 From: Brian Muramatsu Date: Mon, 29 Nov 2010 12:54:45 -0800 Subject: [PATCH 0050/1109] Fix android.net.cts.ProxyTest Bug 3188260 Remove the code that was trying to write to secure settings and take off the BrokenTest annotation. Change-Id: I0759db38225a9822b25c987e66a7590c555b5e9e --- .../net/src/android/net/cts/ProxyTest.java | 36 ++----------------- 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ProxyTest.java b/tests/cts/net/src/android/net/cts/ProxyTest.java index 357935adb0..184a07c483 100644 --- a/tests/cts/net/src/android/net/cts/ProxyTest.java +++ b/tests/cts/net/src/android/net/cts/ProxyTest.java @@ -16,29 +16,17 @@ package android.net.cts; -import android.content.Context; -import android.net.Proxy; -import android.provider.Settings.Secure; -import android.test.AndroidTestCase; - -import dalvik.annotation.BrokenTest; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestTargets; +import android.net.Proxy; +import android.test.AndroidTestCase; + @TestTargetClass(Proxy.class) public class ProxyTest extends AndroidTestCase { - private Context mContext; - - @Override - protected void setUp() throws Exception { - super.setUp(); - - mContext = getContext(); - } - @TestTargetNew( level = TestLevel.COMPLETE, method = "Proxy", @@ -59,18 +47,7 @@ public class ProxyTest extends AndroidTestCase { method = "getDefaultHost", args = {} ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getPort", - args = {Context.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getHost", - args = {Context.class} - ) }) - @BrokenTest("Cannot write secure settings table") public void testAccessProperties() { final int minValidPort = 0; final int maxValidPort = 65535; @@ -80,12 +57,5 @@ public class ProxyTest extends AndroidTestCase { } else { assertTrue(defaultPort >= minValidPort && defaultPort <= maxValidPort); } - - final String host = "proxy.example.com"; - final int port = 2008; - - Secure.putString(mContext.getContentResolver(), Secure.HTTP_PROXY, host + ":" + port); - assertEquals(host, Proxy.getHost(mContext)); - assertEquals(port, Proxy.getPort(mContext)); } } From 5822cf4427886b8fbe1cfc51d4d87c5c9a6464a3 Mon Sep 17 00:00:00 2001 From: Brian Muramatsu Date: Mon, 29 Nov 2010 14:28:39 -0800 Subject: [PATCH 0051/1109] Fix Build Didn't have the right javac set in my environment... :-( Change-Id: I951a11460eafeb75c081a4a07787aaf320b48b31 --- tests/cts/net/src/android/net/cts/ProxyTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/ProxyTest.java b/tests/cts/net/src/android/net/cts/ProxyTest.java index 184a07c483..0c0586ea84 100644 --- a/tests/cts/net/src/android/net/cts/ProxyTest.java +++ b/tests/cts/net/src/android/net/cts/ProxyTest.java @@ -46,7 +46,7 @@ public class ProxyTest extends AndroidTestCase { level = TestLevel.COMPLETE, method = "getDefaultHost", args = {} - ), + ) }) public void testAccessProperties() { final int minValidPort = 0; From 26c4fe935fc14fc9661d5dccc04e0d190037f42f Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Mon, 13 Dec 2010 12:50:29 -0800 Subject: [PATCH 0052/1109] Make ListeningPortsTest less flaky. When a DNS lookup occurs, a new listening UDP socket will be created to receive the DNS response. This listening socket is only temporary, and shouldn't count as a permanent open socket. Bug: 3276283 Change-Id: I45090c0e07d9b360cc26f4bce23833db8c399507 --- .../android/net/cts/ListeningPortsTest.java | 50 ++++++++++++++++--- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ListeningPortsTest.java b/tests/cts/net/src/android/net/cts/ListeningPortsTest.java index ff6b4e9d94..0a32bd7f7f 100644 --- a/tests/cts/net/src/android/net/cts/ListeningPortsTest.java +++ b/tests/cts/net/src/android/net/cts/ListeningPortsTest.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Scanner; import java.util.regex.Pattern; +import junit.framework.AssertionFailedError; import junit.framework.TestCase; public class ListeningPortsTest extends TestCase { @@ -50,12 +51,40 @@ public class ListeningPortsTest extends TestCase { EXCEPTION_PATTERNS.add("[0]{16}[F]{4}[0]{4}[0-9A-F]{6}7F:[0-9A-F]{4}"); // IPv4-6 Conversion } - public static void testNoListeningPorts() { - final boolean isTcp = true; - assertNoListeningPorts("/proc/net/tcp", isTcp); - assertNoListeningPorts("/proc/net/tcp6", isTcp); - assertNoListeningPorts("/proc/net/udp", !isTcp); - assertNoListeningPorts("/proc/net/udp6", !isTcp); + public void testNoListeningTcpPorts() { + assertNoListeningPorts("/proc/net/tcp", true); + } + + public void testNoListeningTcp6Ports() { + assertNoListeningPorts("/proc/net/tcp6", true); + } + + public void testNoListeningUdpPorts() throws Exception { + assertNoListeningUdpPorts("/proc/net/udp"); + } + + public void testNoListeningUdp6Ports() throws Exception { + assertNoListeningUdpPorts("/proc/net/udp6"); + } + + private static final int RETRIES_MAX = 4; + + /** + * UDP tests can be flaky due to DNS lookups. Compensate. + */ + private static void assertNoListeningUdpPorts(String procFilePath) throws Exception { + for (int i = 0; i < RETRIES_MAX; i++) { + try { + assertNoListeningPorts(procFilePath, false); + return; + } catch (ListeningPortsAssertionError e) { + if (i == RETRIES_MAX - 1) { + throw e; + } + Thread.sleep(2 * 1000 * i); + } + } + throw new IllegalStateException("unreachable"); } private static void assertNoListeningPorts(String procFilePath, boolean isTcp) { @@ -94,7 +123,8 @@ public class ListeningPortsTest extends TestCase { isAddress(localAddress)); if (!isException(localAddress) && isPortListening(state, isTcp)) { - fail("Found port listening on " + localAddress + " in " + procFilePath); + throw new ListeningPortsAssertionError( + "Found port listening on " + localAddress + " in " + procFilePath); } } } catch (FileNotFoundException notFound) { @@ -128,4 +158,10 @@ public class ListeningPortsTest extends TestCase { String listeningState = isTcp ? "0A" : "07"; return listeningState.equals(state); } + + private static class ListeningPortsAssertionError extends AssertionFailedError { + private ListeningPortsAssertionError(String msg) { + super(msg); + } + } } From 553ae9a71ac044abf9df5027a41b6a0cffe4d042 Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Mon, 13 Dec 2010 14:02:45 -0800 Subject: [PATCH 0053/1109] still seeing flakyness. Increase retries. Change-Id: I988afa2922dc503bcdff455822088ad22c854d97 --- tests/cts/net/src/android/net/cts/ListeningPortsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/ListeningPortsTest.java b/tests/cts/net/src/android/net/cts/ListeningPortsTest.java index 0a32bd7f7f..b6e6efbc71 100644 --- a/tests/cts/net/src/android/net/cts/ListeningPortsTest.java +++ b/tests/cts/net/src/android/net/cts/ListeningPortsTest.java @@ -67,7 +67,7 @@ public class ListeningPortsTest extends TestCase { assertNoListeningUdpPorts("/proc/net/udp6"); } - private static final int RETRIES_MAX = 4; + private static final int RETRIES_MAX = 6; /** * UDP tests can be flaky due to DNS lookups. Compensate. From b511c888ec8d115a751bf46b24ed0b5ed24454f0 Mon Sep 17 00:00:00 2001 From: Brian Muramatsu Date: Mon, 20 Dec 2010 13:57:14 -0800 Subject: [PATCH 0054/1109] Nuke TrafficStatsTest#testTrafficStatsWithHost... Bug 3189208 Removing this test due to potential problems with GB. This will need to be brought back and investigated. Change-Id: Ifeafdf44464c652b063edfb51c5f7931624b6973 --- .../src/android/net/cts/TrafficStatsTest.java | 73 ++----------------- 1 file changed, 6 insertions(+), 67 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java index 9d23a874da..183f891637 100644 --- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java +++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java @@ -16,24 +16,20 @@ package android.net.cts; -import android.os.Process; -import android.net.TrafficStats; -import android.test.AndroidTestCase; - -import dalvik.annotation.TestTargets; import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestTargetClass; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargets; + +import android.net.TrafficStats; +import android.os.Process; +import android.test.AndroidTestCase; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.net.InetAddress; -import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; -import java.net.UnknownHostException; -import java.util.Random; @TestTargetClass(TrafficStats.class) public class TrafficStatsTest extends AndroidTestCase { @@ -57,63 +53,6 @@ public class TrafficStatsTest extends AndroidTestCase { TrafficStats.getMobileRxBytes() >= 0); } - @TestTargets({ - @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getTotalTxPackets"), - @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getTotalRxPackets"), - @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getTotalTxBytes"), - @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getTotalRxBytes"), - @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getUidTxBytes"), - @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getUidRxBytes") - }) - public void testTrafficStatsWithHostLookup() { - long txPacketsBefore = TrafficStats.getTotalTxPackets(); - long rxPacketsBefore = TrafficStats.getTotalRxPackets(); - long txBytesBefore = TrafficStats.getTotalTxBytes(); - long rxBytesBefore = TrafficStats.getTotalRxBytes(); - long uidTxBytesBefore = TrafficStats.getUidTxBytes(Process.myUid()); - long uidRxBytesBefore = TrafficStats.getUidRxBytes(Process.myUid()); - - // Look up random hostnames in a wildcard domain owned by Google. - // This will require a DNS request, which should generate traffic. - - int found = 0; - Random r = new Random(); - for (int i = 0; i < 10; i++) { - try { - String host = "test" + r.nextInt(100000) + ".clients.google.com"; - InetAddress[] addr = InetAddress.getAllByName(host); - if (addr.length > 0) found++; - } catch (UnknownHostException e) { - // Ignore -- our purpose is not to test network connectivity, - // and we'd rather have false positives than a flaky test. - } - } - - long txPacketsAfter = TrafficStats.getTotalTxPackets(); - long rxPacketsAfter = TrafficStats.getTotalRxPackets(); - long txBytesAfter = TrafficStats.getTotalTxBytes(); - long rxBytesAfter = TrafficStats.getTotalRxBytes(); - long uidTxBytesAfter = TrafficStats.getUidTxBytes(Process.myUid()); - long uidRxBytesAfter = TrafficStats.getUidRxBytes(Process.myUid()); - - // Make some conservative assertions about the data used: - // each successful resolution should exchange at least one packet, - // and at least 20 bytes in each direction. - - assertTrue("txp: " + txPacketsBefore + " [" + found + "] " + txPacketsAfter, - txPacketsAfter >= txPacketsBefore + found); - assertTrue("rxp: " + rxPacketsBefore + " [" + found + "] " + rxPacketsAfter, - rxPacketsAfter >= rxPacketsBefore + found); - assertTrue("txb: " + txBytesBefore + " [" + found + "] " + txBytesAfter, - txBytesAfter >= txBytesBefore + found * 20); - assertTrue("rxb: " + rxBytesBefore + " [" + found + "] " + rxBytesAfter, - rxBytesAfter >= rxBytesBefore + found * 20); - assertTrue("uidtxb: " + uidTxBytesBefore + " [" + found + "] " + uidTxBytesAfter, - uidTxBytesAfter >= uidTxBytesBefore + found * 20); - assertTrue("uidrxb: " + uidRxBytesBefore + " [" + found + "] " + uidRxBytesAfter, - uidRxBytesAfter >= uidRxBytesBefore + found * 20); - } - @TestTargets({ @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getMobileTxPackets"), @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getMobileRxPackets"), From d2488d6ffd7b1a789150abd8d7488764af9c085e Mon Sep 17 00:00:00 2001 From: Masanori Ogino Date: Thu, 13 Jan 2011 15:52:34 +0900 Subject: [PATCH 0055/1109] Test requestRouteToHost() except TYPE_WIFI If the device is set Wifi-ON, then testRequestRouteToHost always fails. Change-Id: Ie487773552e8f6f1d4838755cc39e23c5aa57c1d --- .../cts/net/src/android/net/cts/ConnectivityManagerTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index edcea9a24e..354428b8e9 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -204,8 +204,8 @@ public class ConnectivityManagerTest extends AndroidTestCase { NetworkInfo[] ni = mCm.getAllNetworkInfo(); for (NetworkInfo n : ni) { - // make sure network is up - if (n.isConnected()) { + // make sure network is up (except WIFI due to always fail) + if (n.isConnected() && (n.getType() != TYPE_WIFI)) { assertTrue(mCm.requestRouteToHost(n.getType(), HOST_ADDRESS)); } } From 328b217e5823e47e54b077c43bc8fab91763cb06 Mon Sep 17 00:00:00 2001 From: Madan Ankapura Date: Thu, 11 Nov 2010 18:31:24 -0800 Subject: [PATCH 0056/1109] DO NOT MERGE fix failing test testWifiInfoProperties for non-telephony devices Device can still have a valid networkId even after disconnection if it was associated with AP, getWifiState is a better check to get valid state. Change-Id: I31a8ca38f304fbf639e1f3111be4b5ed406e3b3c --- tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java index 42243c890d..d6d7d8e47c 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java @@ -20,7 +20,6 @@ import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestTargets; -import dalvik.annotation.ToBeFixed; import android.content.BroadcastReceiver; import android.content.Context; @@ -168,8 +167,6 @@ public class WifiInfoTest extends AndroidTestCase { args = {} ) }) - @ToBeFixed(bug="1871573", explanation="android.net.wifi.WifiInfo#getNetworkId() return -1 when" - + " there is wifi connection") public void testWifiInfoProperties() throws Exception { // this test case should in Wifi environment WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); @@ -187,8 +184,7 @@ public class WifiInfoTest extends AndroidTestCase { wifiInfo.getMacAddress(); setWifiEnabled(false); Thread.sleep(DURATION); - wifiInfo = mWifiManager.getConnectionInfo(); - assertEquals(-1, wifiInfo.getNetworkId()); + assertEquals(WifiManager.WIFI_STATE_DISABLED, mWifiManager.getWifiState()); } } From 3bd4323ce4d90a2051010a8f9e2880140d5b2ec4 Mon Sep 17 00:00:00 2001 From: Brian Carlstrom Date: Wed, 9 Feb 2011 16:07:14 -0800 Subject: [PATCH 0057/1109] Change SSLCertificateSocketFactoryTest.testCreateSocket host The test may be flaky because it depends on a live server. Switch to a different server that may be more reliable. Bug: 3188260 Change-Id: Ibba872489650914db8ddd9a117529556787f66ec --- .../src/android/net/cts/SSLCertificateSocketFactoryTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java index 258ac4db1c..f125550a8b 100644 --- a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java +++ b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java @@ -102,11 +102,10 @@ public class SSLCertificateSocketFactoryTest extends AndroidTestCase { args = {int.class} ) }) - @BrokenTest("flaky") public void testCreateSocket() throws Exception { new SSLCertificateSocketFactory(100); int port = 443; - String host = "www.fortify.net"; + String host = "www.google.com"; InetAddress inetAddress = null; inetAddress = InetAddress.getLocalHost(); try { From 76e1414be8d472827d510785d5529b8e5607141a Mon Sep 17 00:00:00 2001 From: Brian Muramatsu Date: Fri, 14 Jan 2011 17:38:16 -0800 Subject: [PATCH 0058/1109] Test startUsingNetworkFeature TYPE_MOBILE_HIPRI Bug 3307293 Change-Id: I03b3e11e1de20333ece772e3448937c61ca0fe91 --- .../net/cts/ConnectivityManagerTest.java | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 354428b8e9..dcb4e1d992 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -16,26 +16,43 @@ package android.net.cts; +import com.android.internal.telephony.Phone; + import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; import dalvik.annotation.TestTargetNew; import dalvik.annotation.TestTargets; import dalvik.annotation.ToBeFixed; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageManager; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; +import android.net.wifi.WifiManager; import android.test.AndroidTestCase; +import android.util.Log; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; @TestTargetClass(ConnectivityManager.class) public class ConnectivityManagerTest extends AndroidTestCase { + private static final String TAG = ConnectivityManagerTest.class.getSimpleName(); + + private static final String FEATURE_ENABLE_HIPRI = "enableHIPRI"; + public static final int TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE; public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI; private static final int HOST_ADDRESS = 0x7f000001;// represent ip 127.0.0.1 private ConnectivityManager mCm; + private WifiManager mWifiManager; + private PackageManager mPackageManager; // must include both mobile data + wifi private static final int MIN_NUM_NETWORK_TYPES = 2; @@ -43,6 +60,8 @@ public class ConnectivityManagerTest extends AndroidTestCase { protected void setUp() throws Exception { super.setUp(); mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); + mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); + mPackageManager = getContext().getPackageManager(); } @TestTargetNew( @@ -235,4 +254,91 @@ public class ConnectivityManagerTest extends AndroidTestCase { public void testTest() { mCm.getBackgroundDataSetting(); } + + /** Test that hipri can be brought up when Wifi is enabled. */ + public void testStartUsingNetworkFeature_enableHipri() throws Exception { + if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY) + || !mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) { + // This test requires a mobile data connection and WiFi. + return; + } + + boolean isWifiConnected = mWifiManager.isWifiEnabled() + && mWifiManager.getConnectionInfo().getSSID() != null; + + try { + // Make sure WiFi is connected to an access point. + if (!isWifiConnected) { + connectToWifi(); + } + + // Register a receiver that will capture the connectivity change for hipri. + ConnectivityActionReceiver receiver = + new ConnectivityActionReceiver(ConnectivityManager.TYPE_MOBILE_HIPRI); + IntentFilter filter = new IntentFilter(); + filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); + mContext.registerReceiver(receiver, filter); + + // Try to start using the hipri feature... + int result = mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, + FEATURE_ENABLE_HIPRI); + assertTrue("Couldn't start using the HIPRI feature.", result != -1); + + // Check that the ConnectivityManager reported that it connected using hipri... + assertTrue("Couldn't connect using hipri...", receiver.waitForConnection()); + + assertTrue("Couldn't requestRouteToHost using HIPRI.", + mCm.requestRouteToHost(ConnectivityManager.TYPE_MOBILE_HIPRI, HOST_ADDRESS)); + + } catch (InterruptedException e) { + fail("Broadcast receiver waiting for ConnectivityManager interrupted."); + } finally { + mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, + Phone.FEATURE_ENABLE_HIPRI); + if (!isWifiConnected) { + mWifiManager.setWifiEnabled(false); + } + } + } + + private void connectToWifi() throws InterruptedException { + ConnectivityActionReceiver receiver = + new ConnectivityActionReceiver(ConnectivityManager.TYPE_WIFI); + IntentFilter filter = new IntentFilter(); + filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); + mContext.registerReceiver(receiver, filter); + + assertTrue(mWifiManager.setWifiEnabled(true)); + assertTrue("Wifi must be configured to connect to an access point for this test.", + receiver.waitForConnection()); + + mContext.unregisterReceiver(receiver); + } + + /** Receiver that captures the last connectivity change's network type and state. */ + private class ConnectivityActionReceiver extends BroadcastReceiver { + + private final CountDownLatch mReceiveLatch = new CountDownLatch(1); + + private final int mNetworkType; + + ConnectivityActionReceiver(int networkType) { + mNetworkType = networkType; + } + + public void onReceive(Context context, Intent intent) { + NetworkInfo networkInfo = intent.getExtras() + .getParcelable(ConnectivityManager.EXTRA_NETWORK_INFO); + int networkType = networkInfo.getType(); + State networkState = networkInfo.getState(); + Log.i(TAG, "Network type: " + networkType + " state: " + networkState); + if (networkType == mNetworkType && networkInfo.getState() == State.CONNECTED) { + mReceiveLatch.countDown(); + } + } + + public boolean waitForConnection() throws InterruptedException { + return mReceiveLatch.await(10, TimeUnit.SECONDS); + } + } } From f3336d71e9928e044f8d43aa2ac07191cdcc7fc9 Mon Sep 17 00:00:00 2001 From: Brian Muramatsu Date: Mon, 28 Feb 2011 15:21:42 -0800 Subject: [PATCH 0059/1109] Remove Reference to Internal Phone Constant Use the constant defined in the test instead. Change-Id: Ia4c85a56663df0c79910395aaae534407952aaf6 --- .../cts/net/src/android/net/cts/ConnectivityManagerTest.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index dcb4e1d992..3b85e9f92e 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -16,8 +16,6 @@ package android.net.cts; -import com.android.internal.telephony.Phone; - import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; import dalvik.annotation.TestTargetNew; @@ -294,7 +292,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { fail("Broadcast receiver waiting for ConnectivityManager interrupted."); } finally { mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, - Phone.FEATURE_ENABLE_HIPRI); + FEATURE_ENABLE_HIPRI); if (!isWifiConnected) { mWifiManager.setWifiEnabled(false); } From a89c9170d2b0b20410aa96cee7a43b38035564b6 Mon Sep 17 00:00:00 2001 From: Xia Wang Date: Fri, 4 Mar 2011 22:11:29 -0800 Subject: [PATCH 0060/1109] Fix cts tests for Wi-Fi only devices. For Wi-Fi only device, startUsingNetworkFeature() returns Phone.APN_TYPE_NOT_AVAILABLE stopUsingNetworkFeature() return 1; In NetworkInfoTest: cm.getAllNetworkInfo() returns an array of NetworkInfo. But the index is not based on network type. bug#: 3513630 Change-Id: Ied0684a9fe2152dae242d779efe3dffd6c9c0609 --- .../net/cts/ConnectivityManagerTest.java | 57 +++++++------ .../src/android/net/cts/NetworkInfoTest.java | 79 +++++++++---------- 2 files changed, 72 insertions(+), 64 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 17a3ac16c8..b69bffd669 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -36,8 +36,8 @@ public class ConnectivityManagerTest extends AndroidTestCase { public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI; private static final int HOST_ADDRESS = 0x7f000001;// represent ip 127.0.0.1 private ConnectivityManager mCm; - // must include both mobile data + wifi - private static final int MIN_NUM_NETWORK_TYPES = 2; + // device could have only one interface: data, wifi. + private static final int MIN_NUM_NETWORK_TYPES = 1; @Override protected void setUp() throws Exception { @@ -51,28 +51,27 @@ public class ConnectivityManagerTest extends AndroidTestCase { args = {int.class} ) public void testGetNetworkInfo() { - - // this test assumes that there are at least two network types. assertTrue(mCm.getAllNetworkInfo().length >= MIN_NUM_NETWORK_TYPES); - NetworkInfo ni = mCm.getNetworkInfo(1); - State state = ni.getState(); - assertTrue(State.UNKNOWN.ordinal() >= state.ordinal() - && state.ordinal() >= State.CONNECTING.ordinal()); - DetailedState ds = ni.getDetailedState(); - assertTrue(DetailedState.FAILED.ordinal() >= ds.ordinal() - && ds.ordinal() >= DetailedState.IDLE.ordinal()); - - ni = mCm.getNetworkInfo(0); - state = ni.getState(); - assertTrue(State.UNKNOWN.ordinal() >= state.ordinal() - && state.ordinal() >= State.CONNECTING.ordinal()); - ds = ni.getDetailedState(); - assertTrue(DetailedState.FAILED.ordinal() >= ds.ordinal() - && ds.ordinal() >= DetailedState.IDLE.ordinal()); - + NetworkInfo ni = mCm.getNetworkInfo(TYPE_WIFI); + if (ni != null) { + State state = ni.getState(); + assertTrue(State.UNKNOWN.ordinal() >= state.ordinal() + && state.ordinal() >= State.CONNECTING.ordinal()); + DetailedState ds = ni.getDetailedState(); + assertTrue(DetailedState.FAILED.ordinal() >= ds.ordinal() + && ds.ordinal() >= DetailedState.IDLE.ordinal()); + } + ni = mCm.getNetworkInfo(TYPE_MOBILE); + if (ni != null) { + State state = ni.getState(); + assertTrue(State.UNKNOWN.ordinal() >= state.ordinal() + && state.ordinal() >= State.CONNECTING.ordinal()); + DetailedState ds = ni.getDetailedState(); + assertTrue(DetailedState.FAILED.ordinal() >= ds.ordinal() + && ds.ordinal() >= DetailedState.IDLE.ordinal()); + } ni = mCm.getNetworkInfo(-1); assertNull(ni); - } @TestTargets({ @@ -125,9 +124,21 @@ public class ConnectivityManagerTest extends AndroidTestCase { final String invalidateFeature = "invalidateFeature"; final String mmsFeature = "enableMMS"; final int failureCode = -1; + final int wifiOnlyStartFailureCode = 3; + final int wifiOnlyStopFailureCode = 1; - assertEquals(failureCode, mCm.startUsingNetworkFeature(TYPE_MOBILE, invalidateFeature)); - assertEquals(failureCode, mCm.stopUsingNetworkFeature(TYPE_MOBILE, invalidateFeature)); + NetworkInfo ni = mCm.getNetworkInfo(TYPE_MOBILE); + if (ni != null) { + assertEquals(failureCode, mCm.startUsingNetworkFeature(TYPE_MOBILE, + invalidateFeature)); + assertEquals(failureCode, mCm.stopUsingNetworkFeature(TYPE_MOBILE, + invalidateFeature)); + } else { + assertEquals(wifiOnlyStartFailureCode, mCm.startUsingNetworkFeature(TYPE_MOBILE, + invalidateFeature)); + assertEquals(wifiOnlyStopFailureCode, mCm.stopUsingNetworkFeature(TYPE_MOBILE, + invalidateFeature)); + } // Should return failure(-1) because MMS is not supported on WIFI. assertEquals(failureCode, mCm.startUsingNetworkFeature(TYPE_WIFI, mmsFeature)); diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java index 99e8e15169..b333be747e 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java @@ -120,50 +120,47 @@ public class NetworkInfoTest extends AndroidTestCase { public void testAccessNetworkInfoProperties() { ConnectivityManager cm = (ConnectivityManager) getContext().getSystemService( Context.CONNECTIVITY_SERVICE); - NetworkInfo[] ni = cm.getAllNetworkInfo(); assertTrue(ni.length >= 2); - assertFalse(ni[TYPE_MOBILE].isFailover()); - assertFalse(ni[TYPE_WIFI].isFailover()); - - // test environment:connect as TYPE_MOBILE, and connect to internet. - assertEquals(TYPE_MOBILE, ni[TYPE_MOBILE].getType()); - assertEquals(TYPE_WIFI, ni[TYPE_WIFI].getType()); - - // don't know the return value - ni[TYPE_MOBILE].getSubtype(); - ni[TYPE_WIFI].getSubtype(); - - assertEquals(MOBILE_TYPE_NAME, ni[TYPE_MOBILE].getTypeName()); - assertEquals(WIFI_TYPE_NAME, ni[TYPE_WIFI].getTypeName()); - - // don't know the return value - ni[TYPE_MOBILE].getSubtypeName(); - ni[TYPE_WIFI].getSubtypeName(); - - if(ni[TYPE_MOBILE].isConnectedOrConnecting()) { - assertTrue(ni[TYPE_MOBILE].isAvailable()); - assertTrue(ni[TYPE_MOBILE].isConnected()); - assertEquals(State.CONNECTED, ni[TYPE_MOBILE].getState()); - assertEquals(DetailedState.CONNECTED, ni[TYPE_MOBILE].getDetailedState()); - ni[TYPE_MOBILE].getReason(); - ni[TYPE_MOBILE].getExtraInfo(); + for (NetworkInfo netInfo: ni) { + switch (netInfo.getType()) { + case TYPE_MOBILE: + // don't know the return value + netInfo.getSubtype(); + assertEquals(MOBILE_TYPE_NAME, netInfo.getTypeName()); + // don't know the return value + netInfo.getSubtypeName(); + if(netInfo.isConnectedOrConnecting()) { + assertTrue(netInfo.isAvailable()); + assertTrue(netInfo.isConnected()); + assertEquals(State.CONNECTED, netInfo.getState()); + assertEquals(DetailedState.CONNECTED, netInfo.getDetailedState()); + netInfo.getReason(); + netInfo.getExtraInfo(); + } + assertFalse(netInfo.isRoaming()); + assertNotNull(netInfo.toString()); + break; + case TYPE_WIFI: + netInfo.getSubtype(); + assertEquals(WIFI_TYPE_NAME, netInfo.getTypeName()); + netInfo.getSubtypeName(); + if(netInfo.isConnectedOrConnecting()) { + assertTrue(netInfo.isAvailable()); + assertTrue(netInfo.isConnected()); + assertEquals(State.CONNECTED, netInfo.getState()); + assertEquals(DetailedState.CONNECTED, netInfo.getDetailedState()); + netInfo.getReason(); + netInfo.getExtraInfo(); + } + assertFalse(netInfo.isRoaming()); + assertNotNull(netInfo.toString()); + break; + // TODO: Add BLUETOOTH_TETHER testing + default: + break; + } } - - if(ni[TYPE_WIFI].isConnectedOrConnecting()) { - assertTrue(ni[TYPE_WIFI].isAvailable()); - assertTrue(ni[TYPE_WIFI].isConnected()); - assertEquals(State.CONNECTED, ni[TYPE_WIFI].getState()); - assertEquals(DetailedState.CONNECTED, ni[TYPE_WIFI].getDetailedState()); - ni[TYPE_WIFI].getReason(); - ni[TYPE_WIFI].getExtraInfo(); - } - - assertFalse(ni[TYPE_MOBILE].isRoaming()); - assertFalse(ni[TYPE_WIFI].isRoaming()); - - assertNotNull(ni[TYPE_MOBILE].toString()); - assertNotNull(ni[TYPE_WIFI].toString()); } } From f108edaa630a5d808328fe892cba7ebbefb26ce0 Mon Sep 17 00:00:00 2001 From: Irfan Sheriff Date: Wed, 6 Apr 2011 10:21:51 -0700 Subject: [PATCH 0061/1109] Fix WifiInfoTest Do not listen to supplicant state change for wifi disable action, instead depend on wifi state changed action Bug: 4242273 Change-Id: Ie53ff42d5e51bbc9f28d93a435fa3315611d342e --- tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java index 3b1a6c1ab3..44189cd13a 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java @@ -54,7 +54,7 @@ public class WifiInfoTest extends AndroidTestCase { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); - if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) { + if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { synchronized (mMySync) { mMySync.expectedState = STATE_WIFI_CHANGED; mMySync.notify(); @@ -68,14 +68,7 @@ public class WifiInfoTest extends AndroidTestCase { super.setUp(); mMySync = new MySync(); mIntentFilter = new IntentFilter(); - mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); - mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); - mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.ACTION_PICK_WIFI_NETWORK); mContext.registerReceiver(mReceiver, mIntentFilter); mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); From 5c990cd7145803b20368097d3f4514e23177a3c8 Mon Sep 17 00:00:00 2001 From: Irfan Sheriff Date: Wed, 6 Apr 2011 10:21:51 -0700 Subject: [PATCH 0062/1109] Fix WifiInfoTest Do not listen to supplicant state change for wifi disable action, instead depend on wifi state changed action Bug: 4242273 Change-Id: Ie53ff42d5e51bbc9f28d93a435fa3315611d342e --- tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java index 3b1a6c1ab3..44189cd13a 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java @@ -54,7 +54,7 @@ public class WifiInfoTest extends AndroidTestCase { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); - if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) { + if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { synchronized (mMySync) { mMySync.expectedState = STATE_WIFI_CHANGED; mMySync.notify(); @@ -68,14 +68,7 @@ public class WifiInfoTest extends AndroidTestCase { super.setUp(); mMySync = new MySync(); mIntentFilter = new IntentFilter(); - mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); - mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); - mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.ACTION_PICK_WIFI_NETWORK); mContext.registerReceiver(mReceiver, mIntentFilter); mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); From 4a88b709cc18156f25055de26025857bef9f5e2f Mon Sep 17 00:00:00 2001 From: Xia Wang Date: Fri, 4 Mar 2011 22:11:29 -0800 Subject: [PATCH 0063/1109] Backport from HC to Fix NetworkInfoTest Bug 4322307 Fixed some other assertions that didn't check for either CONNECTING or CONNECTED. Cleaned up some code and removed some extraneous checks. Original description: "Fix cts tests for Wi-Fi only devices. For Wi-Fi only device, startUsingNetworkFeature() returns Phone.APN_TYPE_NOT_AVAILABLE stopUsingNetworkFeature() return 1; In NetworkInfoTest: cm.getAllNetworkInfo() returns an array of NetworkInfo. But the index is not based on network type." Change-Id: I0b5e3d0cfe5fac18bca0a5ca2ce4cc73bc4dfa16 --- .../net/cts/ConnectivityManagerTest.java | 58 ++++--- .../src/android/net/cts/NetworkInfoTest.java | 156 ++++-------------- 2 files changed, 65 insertions(+), 149 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 12cc21e053..96a935b549 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -51,8 +51,9 @@ public class ConnectivityManagerTest extends AndroidTestCase { private ConnectivityManager mCm; private WifiManager mWifiManager; private PackageManager mPackageManager; - // must include both mobile data + wifi - private static final int MIN_NUM_NETWORK_TYPES = 2; + + // device could have only one interface: data, wifi. + private static final int MIN_NUM_NETWORK_TYPES = 1; @Override protected void setUp() throws Exception { @@ -68,28 +69,27 @@ public class ConnectivityManagerTest extends AndroidTestCase { args = {int.class} ) public void testGetNetworkInfo() { - - // this test assumes that there are at least two network types. assertTrue(mCm.getAllNetworkInfo().length >= MIN_NUM_NETWORK_TYPES); - NetworkInfo ni = mCm.getNetworkInfo(1); - State state = ni.getState(); - assertTrue(State.UNKNOWN.ordinal() >= state.ordinal() - && state.ordinal() >= State.CONNECTING.ordinal()); - DetailedState ds = ni.getDetailedState(); - assertTrue(DetailedState.FAILED.ordinal() >= ds.ordinal() - && ds.ordinal() >= DetailedState.IDLE.ordinal()); - - ni = mCm.getNetworkInfo(0); - state = ni.getState(); - assertTrue(State.UNKNOWN.ordinal() >= state.ordinal() - && state.ordinal() >= State.CONNECTING.ordinal()); - ds = ni.getDetailedState(); - assertTrue(DetailedState.FAILED.ordinal() >= ds.ordinal() - && ds.ordinal() >= DetailedState.IDLE.ordinal()); - + NetworkInfo ni = mCm.getNetworkInfo(TYPE_WIFI); + if (ni != null) { + State state = ni.getState(); + assertTrue(State.UNKNOWN.ordinal() >= state.ordinal() + && state.ordinal() >= State.CONNECTING.ordinal()); + DetailedState ds = ni.getDetailedState(); + assertTrue(DetailedState.FAILED.ordinal() >= ds.ordinal() + && ds.ordinal() >= DetailedState.IDLE.ordinal()); + } + ni = mCm.getNetworkInfo(TYPE_MOBILE); + if (ni != null) { + State state = ni.getState(); + assertTrue(State.UNKNOWN.ordinal() >= state.ordinal() + && state.ordinal() >= State.CONNECTING.ordinal()); + DetailedState ds = ni.getDetailedState(); + assertTrue(DetailedState.FAILED.ordinal() >= ds.ordinal() + && ds.ordinal() >= DetailedState.IDLE.ordinal()); + } ni = mCm.getNetworkInfo(-1); assertNull(ni); - } @TestTargets({ @@ -142,9 +142,21 @@ public class ConnectivityManagerTest extends AndroidTestCase { final String invalidateFeature = "invalidateFeature"; final String mmsFeature = "enableMMS"; final int failureCode = -1; + final int wifiOnlyStartFailureCode = 3; + final int wifiOnlyStopFailureCode = 1; - assertEquals(failureCode, mCm.startUsingNetworkFeature(TYPE_MOBILE, invalidateFeature)); - assertEquals(failureCode, mCm.stopUsingNetworkFeature(TYPE_MOBILE, invalidateFeature)); + NetworkInfo ni = mCm.getNetworkInfo(TYPE_MOBILE); + if (ni != null) { + assertEquals(failureCode, mCm.startUsingNetworkFeature(TYPE_MOBILE, + invalidateFeature)); + assertEquals(failureCode, mCm.stopUsingNetworkFeature(TYPE_MOBILE, + invalidateFeature)); + } else { + assertEquals(wifiOnlyStartFailureCode, mCm.startUsingNetworkFeature(TYPE_MOBILE, + invalidateFeature)); + assertEquals(wifiOnlyStopFailureCode, mCm.stopUsingNetworkFeature(TYPE_MOBILE, + invalidateFeature)); + } // Should return failure(-1) because MMS is not supported on WIFI. assertEquals(failureCode, mCm.startUsingNetworkFeature(TYPE_WIFI, mmsFeature)); diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java index 99e8e15169..6800c43b0a 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java @@ -16,16 +16,14 @@ package android.net.cts; +import dalvik.annotation.TestTargetClass; + import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; import android.test.AndroidTestCase; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargets; @TestTargetClass(NetworkInfo.class) public class NetworkInfoTest extends AndroidTestCase { @@ -35,135 +33,41 @@ public class NetworkInfoTest extends AndroidTestCase { public static final String MOBILE_TYPE_NAME = "mobile"; public static final String WIFI_TYPE_NAME = "WIFI"; - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "isConnectedOrConnecting", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "setFailover", - args = {boolean.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "isFailover", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "isRoaming", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getType", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getSubtype", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getTypeName", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getSubtypeName", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "setIsAvailable", - args = {boolean.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "isAvailable", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "isConnected", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getDetailedState", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getState", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getReason", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getExtraInfo", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "toString", - args = {} - ) - }) public void testAccessNetworkInfoProperties() { ConnectivityManager cm = (ConnectivityManager) getContext().getSystemService( Context.CONNECTIVITY_SERVICE); - NetworkInfo[] ni = cm.getAllNetworkInfo(); - assertTrue(ni.length >= 2); + assertTrue(ni.length >= 1); - assertFalse(ni[TYPE_MOBILE].isFailover()); - assertFalse(ni[TYPE_WIFI].isFailover()); - - // test environment:connect as TYPE_MOBILE, and connect to internet. - assertEquals(TYPE_MOBILE, ni[TYPE_MOBILE].getType()); - assertEquals(TYPE_WIFI, ni[TYPE_WIFI].getType()); - - // don't know the return value - ni[TYPE_MOBILE].getSubtype(); - ni[TYPE_WIFI].getSubtype(); - - assertEquals(MOBILE_TYPE_NAME, ni[TYPE_MOBILE].getTypeName()); - assertEquals(WIFI_TYPE_NAME, ni[TYPE_WIFI].getTypeName()); - - // don't know the return value - ni[TYPE_MOBILE].getSubtypeName(); - ni[TYPE_WIFI].getSubtypeName(); - - if(ni[TYPE_MOBILE].isConnectedOrConnecting()) { - assertTrue(ni[TYPE_MOBILE].isAvailable()); - assertTrue(ni[TYPE_MOBILE].isConnected()); - assertEquals(State.CONNECTED, ni[TYPE_MOBILE].getState()); - assertEquals(DetailedState.CONNECTED, ni[TYPE_MOBILE].getDetailedState()); - ni[TYPE_MOBILE].getReason(); - ni[TYPE_MOBILE].getExtraInfo(); + for (NetworkInfo netInfo: ni) { + switch (netInfo.getType()) { + case TYPE_MOBILE: + assertNetworkInfo(netInfo, MOBILE_TYPE_NAME); + break; + case TYPE_WIFI: + assertNetworkInfo(netInfo, WIFI_TYPE_NAME); + break; + // TODO: Add BLUETOOTH_TETHER testing + default: + break; + } } + } - if(ni[TYPE_WIFI].isConnectedOrConnecting()) { - assertTrue(ni[TYPE_WIFI].isAvailable()); - assertTrue(ni[TYPE_WIFI].isConnected()); - assertEquals(State.CONNECTED, ni[TYPE_WIFI].getState()); - assertEquals(DetailedState.CONNECTED, ni[TYPE_WIFI].getDetailedState()); - ni[TYPE_WIFI].getReason(); - ni[TYPE_WIFI].getExtraInfo(); + private void assertNetworkInfo(NetworkInfo netInfo, String expectedTypeName) { + assertEquals(expectedTypeName, netInfo.getTypeName()); + if(netInfo.isConnectedOrConnecting()) { + assertTrue(netInfo.isAvailable()); + if (State.CONNECTED == netInfo.getState()) { + assertTrue(netInfo.isConnected()); + } + assertTrue(State.CONNECTING == netInfo.getState() + || State.CONNECTED == netInfo.getState()); + assertTrue(DetailedState.SCANNING == netInfo.getDetailedState() + || DetailedState.CONNECTING == netInfo.getDetailedState() + || DetailedState.AUTHENTICATING == netInfo.getDetailedState() + || DetailedState.CONNECTED == netInfo.getDetailedState()); } - - assertFalse(ni[TYPE_MOBILE].isRoaming()); - assertFalse(ni[TYPE_WIFI].isRoaming()); - - assertNotNull(ni[TYPE_MOBILE].toString()); - assertNotNull(ni[TYPE_WIFI].toString()); + assertNotNull(netInfo.toString()); } } From cf5f6fa087810445801f5da1223ed0c9b1e4bea3 Mon Sep 17 00:00:00 2001 From: Xia Wang Date: Fri, 4 Mar 2011 22:11:29 -0800 Subject: [PATCH 0064/1109] Backport from HC to Fix NetworkInfoTest Bug 4322307 Fixed some other assertions that didn't check for either CONNECTING or CONNECTED. Cleaned up some code and removed some extraneous checks. Original description: "Fix cts tests for Wi-Fi only devices. For Wi-Fi only device, startUsingNetworkFeature() returns Phone.APN_TYPE_NOT_AVAILABLE stopUsingNetworkFeature() return 1; In NetworkInfoTest: cm.getAllNetworkInfo() returns an array of NetworkInfo. But the index is not based on network type." Change-Id: I0b5e3d0cfe5fac18bca0a5ca2ce4cc73bc4dfa16 --- .../net/cts/ConnectivityManagerTest.java | 58 ++++--- .../src/android/net/cts/NetworkInfoTest.java | 156 ++++-------------- 2 files changed, 65 insertions(+), 149 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 12cc21e053..96a935b549 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -51,8 +51,9 @@ public class ConnectivityManagerTest extends AndroidTestCase { private ConnectivityManager mCm; private WifiManager mWifiManager; private PackageManager mPackageManager; - // must include both mobile data + wifi - private static final int MIN_NUM_NETWORK_TYPES = 2; + + // device could have only one interface: data, wifi. + private static final int MIN_NUM_NETWORK_TYPES = 1; @Override protected void setUp() throws Exception { @@ -68,28 +69,27 @@ public class ConnectivityManagerTest extends AndroidTestCase { args = {int.class} ) public void testGetNetworkInfo() { - - // this test assumes that there are at least two network types. assertTrue(mCm.getAllNetworkInfo().length >= MIN_NUM_NETWORK_TYPES); - NetworkInfo ni = mCm.getNetworkInfo(1); - State state = ni.getState(); - assertTrue(State.UNKNOWN.ordinal() >= state.ordinal() - && state.ordinal() >= State.CONNECTING.ordinal()); - DetailedState ds = ni.getDetailedState(); - assertTrue(DetailedState.FAILED.ordinal() >= ds.ordinal() - && ds.ordinal() >= DetailedState.IDLE.ordinal()); - - ni = mCm.getNetworkInfo(0); - state = ni.getState(); - assertTrue(State.UNKNOWN.ordinal() >= state.ordinal() - && state.ordinal() >= State.CONNECTING.ordinal()); - ds = ni.getDetailedState(); - assertTrue(DetailedState.FAILED.ordinal() >= ds.ordinal() - && ds.ordinal() >= DetailedState.IDLE.ordinal()); - + NetworkInfo ni = mCm.getNetworkInfo(TYPE_WIFI); + if (ni != null) { + State state = ni.getState(); + assertTrue(State.UNKNOWN.ordinal() >= state.ordinal() + && state.ordinal() >= State.CONNECTING.ordinal()); + DetailedState ds = ni.getDetailedState(); + assertTrue(DetailedState.FAILED.ordinal() >= ds.ordinal() + && ds.ordinal() >= DetailedState.IDLE.ordinal()); + } + ni = mCm.getNetworkInfo(TYPE_MOBILE); + if (ni != null) { + State state = ni.getState(); + assertTrue(State.UNKNOWN.ordinal() >= state.ordinal() + && state.ordinal() >= State.CONNECTING.ordinal()); + DetailedState ds = ni.getDetailedState(); + assertTrue(DetailedState.FAILED.ordinal() >= ds.ordinal() + && ds.ordinal() >= DetailedState.IDLE.ordinal()); + } ni = mCm.getNetworkInfo(-1); assertNull(ni); - } @TestTargets({ @@ -142,9 +142,21 @@ public class ConnectivityManagerTest extends AndroidTestCase { final String invalidateFeature = "invalidateFeature"; final String mmsFeature = "enableMMS"; final int failureCode = -1; + final int wifiOnlyStartFailureCode = 3; + final int wifiOnlyStopFailureCode = 1; - assertEquals(failureCode, mCm.startUsingNetworkFeature(TYPE_MOBILE, invalidateFeature)); - assertEquals(failureCode, mCm.stopUsingNetworkFeature(TYPE_MOBILE, invalidateFeature)); + NetworkInfo ni = mCm.getNetworkInfo(TYPE_MOBILE); + if (ni != null) { + assertEquals(failureCode, mCm.startUsingNetworkFeature(TYPE_MOBILE, + invalidateFeature)); + assertEquals(failureCode, mCm.stopUsingNetworkFeature(TYPE_MOBILE, + invalidateFeature)); + } else { + assertEquals(wifiOnlyStartFailureCode, mCm.startUsingNetworkFeature(TYPE_MOBILE, + invalidateFeature)); + assertEquals(wifiOnlyStopFailureCode, mCm.stopUsingNetworkFeature(TYPE_MOBILE, + invalidateFeature)); + } // Should return failure(-1) because MMS is not supported on WIFI. assertEquals(failureCode, mCm.startUsingNetworkFeature(TYPE_WIFI, mmsFeature)); diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java index 99e8e15169..6800c43b0a 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java @@ -16,16 +16,14 @@ package android.net.cts; +import dalvik.annotation.TestTargetClass; + import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; import android.test.AndroidTestCase; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargets; @TestTargetClass(NetworkInfo.class) public class NetworkInfoTest extends AndroidTestCase { @@ -35,135 +33,41 @@ public class NetworkInfoTest extends AndroidTestCase { public static final String MOBILE_TYPE_NAME = "mobile"; public static final String WIFI_TYPE_NAME = "WIFI"; - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "isConnectedOrConnecting", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "setFailover", - args = {boolean.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "isFailover", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "isRoaming", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getType", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getSubtype", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getTypeName", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getSubtypeName", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "setIsAvailable", - args = {boolean.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "isAvailable", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "isConnected", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getDetailedState", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getState", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getReason", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getExtraInfo", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "toString", - args = {} - ) - }) public void testAccessNetworkInfoProperties() { ConnectivityManager cm = (ConnectivityManager) getContext().getSystemService( Context.CONNECTIVITY_SERVICE); - NetworkInfo[] ni = cm.getAllNetworkInfo(); - assertTrue(ni.length >= 2); + assertTrue(ni.length >= 1); - assertFalse(ni[TYPE_MOBILE].isFailover()); - assertFalse(ni[TYPE_WIFI].isFailover()); - - // test environment:connect as TYPE_MOBILE, and connect to internet. - assertEquals(TYPE_MOBILE, ni[TYPE_MOBILE].getType()); - assertEquals(TYPE_WIFI, ni[TYPE_WIFI].getType()); - - // don't know the return value - ni[TYPE_MOBILE].getSubtype(); - ni[TYPE_WIFI].getSubtype(); - - assertEquals(MOBILE_TYPE_NAME, ni[TYPE_MOBILE].getTypeName()); - assertEquals(WIFI_TYPE_NAME, ni[TYPE_WIFI].getTypeName()); - - // don't know the return value - ni[TYPE_MOBILE].getSubtypeName(); - ni[TYPE_WIFI].getSubtypeName(); - - if(ni[TYPE_MOBILE].isConnectedOrConnecting()) { - assertTrue(ni[TYPE_MOBILE].isAvailable()); - assertTrue(ni[TYPE_MOBILE].isConnected()); - assertEquals(State.CONNECTED, ni[TYPE_MOBILE].getState()); - assertEquals(DetailedState.CONNECTED, ni[TYPE_MOBILE].getDetailedState()); - ni[TYPE_MOBILE].getReason(); - ni[TYPE_MOBILE].getExtraInfo(); + for (NetworkInfo netInfo: ni) { + switch (netInfo.getType()) { + case TYPE_MOBILE: + assertNetworkInfo(netInfo, MOBILE_TYPE_NAME); + break; + case TYPE_WIFI: + assertNetworkInfo(netInfo, WIFI_TYPE_NAME); + break; + // TODO: Add BLUETOOTH_TETHER testing + default: + break; + } } + } - if(ni[TYPE_WIFI].isConnectedOrConnecting()) { - assertTrue(ni[TYPE_WIFI].isAvailable()); - assertTrue(ni[TYPE_WIFI].isConnected()); - assertEquals(State.CONNECTED, ni[TYPE_WIFI].getState()); - assertEquals(DetailedState.CONNECTED, ni[TYPE_WIFI].getDetailedState()); - ni[TYPE_WIFI].getReason(); - ni[TYPE_WIFI].getExtraInfo(); + private void assertNetworkInfo(NetworkInfo netInfo, String expectedTypeName) { + assertEquals(expectedTypeName, netInfo.getTypeName()); + if(netInfo.isConnectedOrConnecting()) { + assertTrue(netInfo.isAvailable()); + if (State.CONNECTED == netInfo.getState()) { + assertTrue(netInfo.isConnected()); + } + assertTrue(State.CONNECTING == netInfo.getState() + || State.CONNECTED == netInfo.getState()); + assertTrue(DetailedState.SCANNING == netInfo.getDetailedState() + || DetailedState.CONNECTING == netInfo.getDetailedState() + || DetailedState.AUTHENTICATING == netInfo.getDetailedState() + || DetailedState.CONNECTED == netInfo.getDetailedState()); } - - assertFalse(ni[TYPE_MOBILE].isRoaming()); - assertFalse(ni[TYPE_WIFI].isRoaming()); - - assertNotNull(ni[TYPE_MOBILE].toString()); - assertNotNull(ni[TYPE_WIFI].toString()); + assertNotNull(netInfo.toString()); } } From 36b66397630f26068591341982edd8931f01a978 Mon Sep 17 00:00:00 2001 From: Brian Muramatsu Date: Tue, 7 Jun 2011 13:53:47 -0700 Subject: [PATCH 0065/1109] Fix for NetworkInfo_DetailedStateTest Update the test to support a new enum value. Once the SignatureTest is fixed to check enums there shouldn't be any need for these enum checking tests. Change-Id: I85d75e86453c37a35f8be9e15d99dd47c690f6ea --- .../android/net/cts/NetworkInfo_DetailedStateTest.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java index 196e102dee..7261b167de 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java @@ -16,12 +16,13 @@ package android.net.cts; -import android.net.NetworkInfo.DetailedState; -import android.test.AndroidTestCase; import dalvik.annotation.TestLevel; import dalvik.annotation.TestTargetClass; import dalvik.annotation.TestTargetNew; +import android.net.NetworkInfo.DetailedState; +import android.test.AndroidTestCase; + @TestTargetClass(DetailedState.class) public class NetworkInfo_DetailedStateTest extends AndroidTestCase { @@ -52,7 +53,7 @@ public class NetworkInfo_DetailedStateTest extends AndroidTestCase { ) public void testValues() { DetailedState[] expected = DetailedState.values(); - assertEquals(10, expected.length); + assertEquals(11, expected.length); assertEquals(DetailedState.IDLE, expected[0]); assertEquals(DetailedState.SCANNING, expected[1]); assertEquals(DetailedState.CONNECTING, expected[2]); @@ -63,6 +64,7 @@ public class NetworkInfo_DetailedStateTest extends AndroidTestCase { assertEquals(DetailedState.DISCONNECTING, expected[7]); assertEquals(DetailedState.DISCONNECTED, expected[8]); assertEquals(DetailedState.FAILED, expected[9]); + assertEquals(DetailedState.FAILED, expected[10]); } } From 1ae190ce775f2a8669296acb066e6e06e6607831 Mon Sep 17 00:00:00 2001 From: Brian Muramatsu Date: Wed, 22 Jun 2011 15:35:43 -0700 Subject: [PATCH 0066/1109] Fix NetworkInfo_DetailedStateTest Again Change-Id: I07d6a0ee21039859991a9594cd8b4e11ac4eecb6 --- .../net/src/android/net/cts/NetworkInfo_DetailedStateTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java index 7261b167de..6b9b985122 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java @@ -64,7 +64,7 @@ public class NetworkInfo_DetailedStateTest extends AndroidTestCase { assertEquals(DetailedState.DISCONNECTING, expected[7]); assertEquals(DetailedState.DISCONNECTED, expected[8]); assertEquals(DetailedState.FAILED, expected[9]); - assertEquals(DetailedState.FAILED, expected[10]); + assertEquals(DetailedState.BLOCKED, expected[10]); } } From a18b717579a33c3751990d5e98318333b08a057b Mon Sep 17 00:00:00 2001 From: Brian Muramatsu Date: Tue, 21 Jun 2011 14:32:38 -0700 Subject: [PATCH 0067/1109] Test for Apache HttpClient Bug 4554251 This test launches multiple downloads at once to check that the device can open up multiple sockets without OOMing. One test tries to use wifi if available and the other tries to use mobile by disconnecting wifi. The CtsTestServer was modified to handle responses in separate threads to test concurrent downloads. Change-Id: Ifa1a11f409c69c1ae3ce621bf0542e0be56b50e0 --- .../net/http/cts/ApacheHttpClientTest.java | 210 ++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 tests/cts/net/src/android/net/http/cts/ApacheHttpClientTest.java diff --git a/tests/cts/net/src/android/net/http/cts/ApacheHttpClientTest.java b/tests/cts/net/src/android/net/http/cts/ApacheHttpClientTest.java new file mode 100644 index 0000000000..e4846fdec2 --- /dev/null +++ b/tests/cts/net/src/android/net/http/cts/ApacheHttpClientTest.java @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2011 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.http.cts; + +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.DefaultHttpClient; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.net.NetworkInfo.State; +import android.net.Uri; +import android.net.wifi.WifiManager; +import android.test.AndroidTestCase; +import android.util.Log; +import android.webkit.cts.CtsTestServer; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +public class ApacheHttpClientTest extends AndroidTestCase { + + private static final String TAG = ApacheHttpClientTest.class.getSimpleName(); + + private static final int NUM_DOWNLOADS = 20; + + private static final int SMALL_DOWNLOAD_SIZE = 100 * 1024; + + private CtsTestServer mWebServer; + + private WifiManager mWifiManager; + + private ConnectivityManager mConnectivityManager; + + private boolean mHasTelephony; + + private boolean mHasWifi; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mWebServer = new CtsTestServer(mContext); + mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); + mConnectivityManager = (ConnectivityManager) + mContext.getSystemService(Context.CONNECTIVITY_SERVICE); + + PackageManager packageManager = mContext.getPackageManager(); + mHasTelephony = packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY); + mHasWifi = packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + mWebServer.shutdown(); + } + + public void testExecute_withMobile() throws Exception { + if (mHasTelephony) { + disconnectWifiToConnectToMobile(); + } + + downloadMultipleFiles(); + + if (mHasWifi) { + connectToWifi(); + } + } + + public void testExecute_withWifi() throws Exception { + if (mHasWifi) { + if (!mWifiManager.isWifiEnabled()) { + connectToWifi(); + } + downloadMultipleFiles(); + } + } + + private void downloadMultipleFiles() throws ClientProtocolException, IOException { + List responses = new ArrayList(); + for (int i = 0; i < NUM_DOWNLOADS; i++) { + HttpClient httpClient = new DefaultHttpClient(); + HttpGet request = new HttpGet(getSmallDownloadUrl(i).toString()); + HttpResponse response = httpClient.execute(request); + responses.add(response); + } + + for (int i = 0; i < NUM_DOWNLOADS; i++) { + assertDownloadResponse("Download " + i, SMALL_DOWNLOAD_SIZE, responses.get(i)); + } + } + + private Uri getSmallDownloadUrl(int index) { + return Uri.parse(mWebServer.getTestDownloadUrl("cts-small-download-" + index, + SMALL_DOWNLOAD_SIZE)); + } + + private void assertDownloadResponse(String message, int expectedNumBytes, HttpResponse response) + throws IllegalStateException, IOException { + byte[] buffer = new byte[4096]; + assertEquals(200, response.getStatusLine().getStatusCode()); + + InputStream stream = response.getEntity().getContent(); + int numBytes = 0; + while (true) { + int bytesRead = stream.read(buffer); + if (bytesRead < 0) { + break; + } else { + numBytes += bytesRead; + } + } + assertEquals(message, SMALL_DOWNLOAD_SIZE, numBytes); + } + + private void connectToWifi() throws InterruptedException { + if (!mWifiManager.isWifiEnabled()) { + ConnectivityActionReceiver receiver = + new ConnectivityActionReceiver(ConnectivityManager.TYPE_WIFI, State.CONNECTED); + IntentFilter filter = new IntentFilter(); + filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); + mContext.registerReceiver(receiver, filter); + + assertTrue(mWifiManager.setWifiEnabled(true)); + assertTrue("Wifi must be configured to connect to an access point for this test.", + receiver.waitForStateChange()); + + mContext.unregisterReceiver(receiver); + } + } + + private void disconnectWifiToConnectToMobile() throws InterruptedException { + if (mHasWifi && mWifiManager.isWifiEnabled()) { + ConnectivityActionReceiver connectMobileReceiver = + new ConnectivityActionReceiver(ConnectivityManager.TYPE_MOBILE, + State.CONNECTED); + ConnectivityActionReceiver disconnectWifiReceiver = + new ConnectivityActionReceiver(ConnectivityManager.TYPE_WIFI, + State.DISCONNECTED); + IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); + mContext.registerReceiver(connectMobileReceiver, filter); + mContext.registerReceiver(disconnectWifiReceiver, filter); + + assertTrue(mWifiManager.setWifiEnabled(false)); + assertTrue(disconnectWifiReceiver.waitForStateChange()); + assertTrue(connectMobileReceiver.waitForStateChange()); + + mContext.unregisterReceiver(connectMobileReceiver); + mContext.unregisterReceiver(disconnectWifiReceiver); + } + } + + /** Receiver that captures the last connectivity change's network type and state. */ + private class ConnectivityActionReceiver extends BroadcastReceiver { + + private final CountDownLatch mReceiveLatch = new CountDownLatch(1); + + private final int mNetworkType; + + private final State mExpectedState; + + ConnectivityActionReceiver(int networkType, State expectedState) { + mNetworkType = networkType; + mExpectedState = expectedState; + } + + public void onReceive(Context context, Intent intent) { + NetworkInfo networkInfo = intent.getExtras() + .getParcelable(ConnectivityManager.EXTRA_NETWORK_INFO); + int networkType = networkInfo.getType(); + State networkState = networkInfo.getState(); + Log.i(TAG, "Network type: " + networkType + " State: " + networkInfo.getState()); + if (networkType == mNetworkType && networkInfo.getState() == mExpectedState) { + mReceiveLatch.countDown(); + } + } + + public boolean waitForStateChange() throws InterruptedException { + return hasExpectedState() || mReceiveLatch.await(30, TimeUnit.SECONDS); + } + + private boolean hasExpectedState() { + return mExpectedState == mConnectivityManager.getNetworkInfo(mNetworkType).getState(); + } + } +} From 68f66bffff2299aab6103b8fb01854988430c147 Mon Sep 17 00:00:00 2001 From: Brian Muramatsu Date: Wed, 17 Aug 2011 14:16:48 -0700 Subject: [PATCH 0068/1109] Fix for ConnectivityManagerTest Bug 5178134 Some network types can throw SecurityExceptions and depend on the build configuration. Don't fail the test if those throw exceptions. Change-Id: I5365f85280a348ef1777d05ce50b2dff17a1312f --- .../android/net/cts/ConnectivityManagerTest.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 3751b3cff0..2db0acbaae 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -35,6 +35,8 @@ import android.net.wifi.WifiManager; import android.test.AndroidTestCase; import android.util.Log; +import java.util.HashSet; +import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -170,12 +172,20 @@ public class ConnectivityManagerTest extends AndroidTestCase { args = {int.class, int.class} ) public void testRequestRouteToHost() { + Set exceptionFreeTypes = new HashSet(); + exceptionFreeTypes.add(ConnectivityManager.TYPE_BLUETOOTH); + exceptionFreeTypes.add(ConnectivityManager.TYPE_ETHERNET); + exceptionFreeTypes.add(ConnectivityManager.TYPE_MOBILE); + exceptionFreeTypes.add(ConnectivityManager.TYPE_MOBILE_DUN); + exceptionFreeTypes.add(ConnectivityManager.TYPE_MOBILE_HIPRI); + exceptionFreeTypes.add(ConnectivityManager.TYPE_MOBILE_MMS); + exceptionFreeTypes.add(ConnectivityManager.TYPE_MOBILE_SUPL); NetworkInfo[] ni = mCm.getAllNetworkInfo(); for (NetworkInfo n : ni) { - // make sure network is up (except WIFI due to always fail) - if (n.isConnected() && (n.getType() != TYPE_WIFI)) { - assertTrue(mCm.requestRouteToHost(n.getType(), HOST_ADDRESS)); + if (n.isConnected() && exceptionFreeTypes.contains(n.getType())) { + assertTrue("Network type: " + n.getType(), mCm.requestRouteToHost(n.getType(), + HOST_ADDRESS)); } } From 8670b1c23f1c074ce430213efc69f573410eabd3 Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Wed, 5 Oct 2011 10:43:01 -0700 Subject: [PATCH 0069/1109] ListeningPortsTest: Make error message more useful. - Add UID of listener to error message. - Convert hex port number to decimal for easier reading by humans. Change-Id: I0b8edcf14ebd0c039b936055a265f4706558f9fe --- tests/cts/net/src/android/net/cts/ListeningPortsTest.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/ListeningPortsTest.java b/tests/cts/net/src/android/net/cts/ListeningPortsTest.java index b6e6efbc71..5c1ba7cab8 100644 --- a/tests/cts/net/src/android/net/cts/ListeningPortsTest.java +++ b/tests/cts/net/src/android/net/cts/ListeningPortsTest.java @@ -118,13 +118,18 @@ public class ListeningPortsTest extends TestCase { String localAddress = fields[1]; String state = fields[3]; + String uid = fields[7]; assertTrue(procFilePath + " should have an IP address in the second column", isAddress(localAddress)); + String localIp = localAddress.split(":")[0]; + int localPort = Integer.parseInt(localAddress.split(":")[1], 16); + if (!isException(localAddress) && isPortListening(state, isTcp)) { throw new ListeningPortsAssertionError( - "Found port listening on " + localAddress + " in " + procFilePath); + "Found port listening on addr=" + localIp + ", port=" + + localPort + ", UID=" + uid + " in " + procFilePath); } } } catch (FileNotFoundException notFound) { From 19ad949076faee6697994776ecfbb8c037d8221b Mon Sep 17 00:00:00 2001 From: Steve Block Date: Wed, 5 Oct 2011 19:32:45 +0100 Subject: [PATCH 0070/1109] Add tests for SslError Bug: 5416594 Change-Id: Iebbc9d02088ea986246a8c7e9d4f9b2b84dd8116 --- .../android/net/http/cts/SslErrorTest.java | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100755 tests/cts/net/src/android/net/http/cts/SslErrorTest.java diff --git a/tests/cts/net/src/android/net/http/cts/SslErrorTest.java b/tests/cts/net/src/android/net/http/cts/SslErrorTest.java new file mode 100755 index 0000000000..d186f0e4b3 --- /dev/null +++ b/tests/cts/net/src/android/net/http/cts/SslErrorTest.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2011 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.http.cts; + +import android.net.http.SslCertificate; +import android.net.http.SslError; + +import dalvik.annotation.TestLevel; +import dalvik.annotation.TestTargetNew; +import dalvik.annotation.TestTargetClass; + +import java.util.Date; + +import junit.framework.TestCase; + +@TestTargetClass(SslError.class) +public class SslErrorTest extends TestCase { + private SslCertificate mCertificate; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mCertificate = new SslCertificate("foo", "bar", new Date(42), new Date(43)); + } + + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "hasError", + args = {int.class} + ) + public void testHasError() { + SslError error = new SslError(SslError.SSL_EXPIRED, mCertificate); + assertTrue(error.hasError(SslError.SSL_EXPIRED)); + assertFalse(error.hasError(SslError.SSL_UNTRUSTED)); + } + + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "addError", + args = {int.class} + ) + public void testAddError() { + SslError error = new SslError(SslError.SSL_EXPIRED, mCertificate); + assertFalse(error.hasError(SslError.SSL_UNTRUSTED)); + error.addError(SslError.SSL_UNTRUSTED); + assertTrue(error.hasError(SslError.SSL_UNTRUSTED)); + } + + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "addError", + args = {int.class} + ) + public void testAddErrorIgnoresInvalidValues() { + SslError error = new SslError(SslError.SSL_EXPIRED, mCertificate); + error.addError(42); + assertFalse(error.hasError(42)); + } + + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "SslError", + args = {int.class, SslCertificate.class} + ) + public void testConstructorIgnoresInvalidValues() { + SslError error = new SslError(42, mCertificate); + assertFalse(error.hasError(42)); + } + + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getPrimaryError", + args = {} + ) + public void testGetPrimaryError() { + SslError error = new SslError(SslError.SSL_EXPIRED, mCertificate); + error.addError(SslError.SSL_UNTRUSTED); + assertEquals(error.getPrimaryError(), SslError.SSL_UNTRUSTED); + } + + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getPrimaryError", + args = {} + ) + public void testGetPrimaryErrorWithEmptySet() { + SslError error = new SslError(42, mCertificate); + assertEquals(error.getPrimaryError(), -1); + } + + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getUrl", + args = {} + ) + public void testGetUrl() { + SslError error = new SslError(SslError.SSL_EXPIRED, mCertificate, "foo"); + assertEquals(error.getUrl(), "foo"); + } + + @TestTargetNew( + level = TestLevel.COMPLETE, + method = "getUrl", + args = {} + ) + public void testGetUrlWithDeprecatedConstructor() { + SslError error = new SslError(SslError.SSL_EXPIRED, mCertificate); + assertEquals(error.getUrl(), ""); + } +} From 0c292bb1176fb40a157b3166db35d5402726f3c6 Mon Sep 17 00:00:00 2001 From: android-htc-contribute Date: Wed, 5 Oct 2011 11:09:36 +0800 Subject: [PATCH 0071/1109] =?UTF-8?q?Data=20call=20establish=20time=20is?= =?UTF-8?q?=20related=20to=20network=20condition=20which=20can=E2=80=99t?= =?UTF-8?q?=20be=20controlled=20by=20the=20device.=20Extend=20the=20time?= =?UTF-8?q?=20limitation=20to=2030=20seconds=20to=20cover=20most=20of=20th?= =?UTF-8?q?e=20cases.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I522f7eb23baa9a652fb3fd633d200cd6307180c8 --- tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 96a935b549..77191cbd67 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -287,7 +287,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { } public boolean waitForConnection() throws InterruptedException { - return mReceiveLatch.await(10, TimeUnit.SECONDS); + return mReceiveLatch.await(30, TimeUnit.SECONDS); } } } From 531debc2802064e0e242fc873a711787d6dcd762 Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Tue, 25 Oct 2011 10:16:06 -0700 Subject: [PATCH 0072/1109] fix IPv6 loopback pattern In /proc/net/udp6 and /proc/net/tcp6, the addresses stored in that file are in network byte order. As a result, the IPv6 loopback address, ::1, is stored as 00000000000000000000000001000000 NOT 00000000000000000000000000000001 Bug: 5473686 Change-Id: I73098d52c981c48d82423c8ce99b6b20d11a5568 --- tests/cts/net/src/android/net/cts/ListeningPortsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/ListeningPortsTest.java b/tests/cts/net/src/android/net/cts/ListeningPortsTest.java index 5c1ba7cab8..bcec0fe89e 100644 --- a/tests/cts/net/src/android/net/cts/ListeningPortsTest.java +++ b/tests/cts/net/src/android/net/cts/ListeningPortsTest.java @@ -46,7 +46,7 @@ public class ListeningPortsTest extends TestCase { EXCEPTION_PATTERNS.add("[0-9A-F]{6}7F:[0-9A-F]{4}"); // IPv4 Loopback // IPv6 exceptions - EXCEPTION_PATTERNS.add("[0]{31}1:[0-9A-F]{4}"); // IPv6 Loopback + EXCEPTION_PATTERNS.add("[0]{25}1[0]{6}:[0-9A-F]{4}"); // IPv6 Loopback EXCEPTION_PATTERNS.add("[0]{16}[0]{4}[0]{4}[0-9A-F]{6}7F:[0-9A-F]{4}"); // IPv4-6 Conversion EXCEPTION_PATTERNS.add("[0]{16}[F]{4}[0]{4}[0-9A-F]{6}7F:[0-9A-F]{4}"); // IPv4-6 Conversion } From 3dc050e0eb93003721cfedca704f89908d07a24a Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Tue, 25 Oct 2011 10:16:06 -0700 Subject: [PATCH 0073/1109] fix IPv6 loopback pattern In /proc/net/udp6 and /proc/net/tcp6, the addresses stored in that file are in network byte order. As a result, the IPv6 loopback address, ::1, is stored as 00000000000000000000000001000000 NOT 00000000000000000000000000000001 Bug: 5473686 Change-Id: I73098d52c981c48d82423c8ce99b6b20d11a5568 --- tests/cts/net/src/android/net/cts/ListeningPortsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/ListeningPortsTest.java b/tests/cts/net/src/android/net/cts/ListeningPortsTest.java index 5c1ba7cab8..bcec0fe89e 100644 --- a/tests/cts/net/src/android/net/cts/ListeningPortsTest.java +++ b/tests/cts/net/src/android/net/cts/ListeningPortsTest.java @@ -46,7 +46,7 @@ public class ListeningPortsTest extends TestCase { EXCEPTION_PATTERNS.add("[0-9A-F]{6}7F:[0-9A-F]{4}"); // IPv4 Loopback // IPv6 exceptions - EXCEPTION_PATTERNS.add("[0]{31}1:[0-9A-F]{4}"); // IPv6 Loopback + EXCEPTION_PATTERNS.add("[0]{25}1[0]{6}:[0-9A-F]{4}"); // IPv6 Loopback EXCEPTION_PATTERNS.add("[0]{16}[0]{4}[0]{4}[0-9A-F]{6}7F:[0-9A-F]{4}"); // IPv4-6 Conversion EXCEPTION_PATTERNS.add("[0]{16}[F]{4}[0]{4}[0-9A-F]{6}7F:[0-9A-F]{4}"); // IPv4-6 Conversion } From 52cc91ff4585faed0d1bc0c6783d5b3a9268da5e Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Tue, 25 Oct 2011 10:16:06 -0700 Subject: [PATCH 0074/1109] fix IPv6 loopback pattern In /proc/net/udp6 and /proc/net/tcp6, the addresses stored in that file are in network byte order. As a result, the IPv6 loopback address, ::1, is stored as 00000000000000000000000001000000 NOT 00000000000000000000000000000001 Bug: 5473686 Change-Id: I73098d52c981c48d82423c8ce99b6b20d11a5568 --- tests/cts/net/src/android/net/cts/ListeningPortsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/ListeningPortsTest.java b/tests/cts/net/src/android/net/cts/ListeningPortsTest.java index 5c1ba7cab8..bcec0fe89e 100644 --- a/tests/cts/net/src/android/net/cts/ListeningPortsTest.java +++ b/tests/cts/net/src/android/net/cts/ListeningPortsTest.java @@ -46,7 +46,7 @@ public class ListeningPortsTest extends TestCase { EXCEPTION_PATTERNS.add("[0-9A-F]{6}7F:[0-9A-F]{4}"); // IPv4 Loopback // IPv6 exceptions - EXCEPTION_PATTERNS.add("[0]{31}1:[0-9A-F]{4}"); // IPv6 Loopback + EXCEPTION_PATTERNS.add("[0]{25}1[0]{6}:[0-9A-F]{4}"); // IPv6 Loopback EXCEPTION_PATTERNS.add("[0]{16}[0]{4}[0]{4}[0-9A-F]{6}7F:[0-9A-F]{4}"); // IPv4-6 Conversion EXCEPTION_PATTERNS.add("[0]{16}[F]{4}[0]{4}[0-9A-F]{6}7F:[0-9A-F]{4}"); // IPv4-6 Conversion } From fff8fb1b9f869c94dfbc14012caa13dbd7743309 Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Tue, 1 Nov 2011 16:53:21 -0700 Subject: [PATCH 0075/1109] Move file, change loopback handling, docs. Move the ListeningPortsTest from android.net.cts to android.security.cts, to better indicate that this is a security related test. Start triggering test failures when a process is bound to the loopback interface. In those cases, it's always better to use a UNIX domain socket instead of a locally bound IP socket. UNIX domain sockets can be protected with unix filesystem permissions, or getsockopt(SO_PEERCRED) can be used to indicate who is on the other end of the socket. Drastically fix the documentation to explain why this test is present. Modify the IP addresses and port numbers to be more human readable. Change-Id: Id83aadd1455279a1a2d3fb4fb1915af558355aca --- .../android/net/cts/ListeningPortsTest.java | 172 ------------------ 1 file changed, 172 deletions(-) delete mode 100644 tests/cts/net/src/android/net/cts/ListeningPortsTest.java diff --git a/tests/cts/net/src/android/net/cts/ListeningPortsTest.java b/tests/cts/net/src/android/net/cts/ListeningPortsTest.java deleted file mode 100644 index bcec0fe89e..0000000000 --- a/tests/cts/net/src/android/net/cts/ListeningPortsTest.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2010 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 java.io.File; -import java.io.FileNotFoundException; -import java.util.ArrayList; -import java.util.List; -import java.util.Scanner; -import java.util.regex.Pattern; - -import junit.framework.AssertionFailedError; -import junit.framework.TestCase; - -public class ListeningPortsTest extends TestCase { - - /** Address patterns used to check whether we're checking the right column in /proc/net. */ - private static final List ADDRESS_PATTERNS = new ArrayList(2); - - static { - ADDRESS_PATTERNS.add("[0-9A-F]{8}:[0-9A-F]{4}"); - ADDRESS_PATTERNS.add("[0-9A-F]{32}:[0-9A-F]{4}"); - } - - /** Ports that are allowed to be listening on the emulator. */ - private static final List EXCEPTION_PATTERNS = new ArrayList(6); - - static { - // IPv4 exceptions - EXCEPTION_PATTERNS.add("00000000:15B3"); // 0.0.0.0:5555 - emulator port - EXCEPTION_PATTERNS.add("0F02000A:15B3"); // 10.0.2.15:5555 - net forwarding for emulator - EXCEPTION_PATTERNS.add("[0-9A-F]{6}7F:[0-9A-F]{4}"); // IPv4 Loopback - - // IPv6 exceptions - EXCEPTION_PATTERNS.add("[0]{25}1[0]{6}:[0-9A-F]{4}"); // IPv6 Loopback - EXCEPTION_PATTERNS.add("[0]{16}[0]{4}[0]{4}[0-9A-F]{6}7F:[0-9A-F]{4}"); // IPv4-6 Conversion - EXCEPTION_PATTERNS.add("[0]{16}[F]{4}[0]{4}[0-9A-F]{6}7F:[0-9A-F]{4}"); // IPv4-6 Conversion - } - - public void testNoListeningTcpPorts() { - assertNoListeningPorts("/proc/net/tcp", true); - } - - public void testNoListeningTcp6Ports() { - assertNoListeningPorts("/proc/net/tcp6", true); - } - - public void testNoListeningUdpPorts() throws Exception { - assertNoListeningUdpPorts("/proc/net/udp"); - } - - public void testNoListeningUdp6Ports() throws Exception { - assertNoListeningUdpPorts("/proc/net/udp6"); - } - - private static final int RETRIES_MAX = 6; - - /** - * UDP tests can be flaky due to DNS lookups. Compensate. - */ - private static void assertNoListeningUdpPorts(String procFilePath) throws Exception { - for (int i = 0; i < RETRIES_MAX; i++) { - try { - assertNoListeningPorts(procFilePath, false); - return; - } catch (ListeningPortsAssertionError e) { - if (i == RETRIES_MAX - 1) { - throw e; - } - Thread.sleep(2 * 1000 * i); - } - } - throw new IllegalStateException("unreachable"); - } - - private static void assertNoListeningPorts(String procFilePath, boolean isTcp) { - - /* - * Sample output of "cat /proc/net/tcp" on emulator: - * - * sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid ... - * 0: 0100007F:13AD 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 ... - * 1: 00000000:15B3 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 ... - * 2: 0F02000A:15B3 0202000A:CE8A 01 00000000:00000000 00:00000000 00000000 0 ... - * - */ - - File procFile = new File(procFilePath); - Scanner scanner = null; - try { - scanner = new Scanner(procFile); - while (scanner.hasNextLine()) { - String line = scanner.nextLine().trim(); - - // Skip column headers - if (line.startsWith("sl")) { - continue; - } - - String[] fields = line.split("\\s+"); - final int expectedNumColumns = 12; - assertTrue(procFilePath + " should have at least " + expectedNumColumns - + " columns of output " + fields, fields.length >= expectedNumColumns); - - String localAddress = fields[1]; - String state = fields[3]; - String uid = fields[7]; - - assertTrue(procFilePath + " should have an IP address in the second column", - isAddress(localAddress)); - - String localIp = localAddress.split(":")[0]; - int localPort = Integer.parseInt(localAddress.split(":")[1], 16); - - if (!isException(localAddress) && isPortListening(state, isTcp)) { - throw new ListeningPortsAssertionError( - "Found port listening on addr=" + localIp + ", port=" - + localPort + ", UID=" + uid + " in " + procFilePath); - } - } - } catch (FileNotFoundException notFound) { - fail("Could not open file " + procFilePath + " to check for listening ports."); - } finally { - if (scanner != null) { - scanner.close(); - } - } - } - - private static boolean isAddress(String localAddress) { - return isPatternMatch(ADDRESS_PATTERNS, localAddress); - } - - private static boolean isException(String localAddress) { - return isPatternMatch(EXCEPTION_PATTERNS, localAddress); - } - - private static boolean isPatternMatch(List patterns, String input) { - for (String pattern : patterns) { - if (Pattern.matches(pattern, input)) { - return true; - } - } - return false; - } - - private static boolean isPortListening(String state, boolean isTcp) { - // 0A = TCP_LISTEN from include/net/tcp_states.h - String listeningState = isTcp ? "0A" : "07"; - return listeningState.equals(state); - } - - private static class ListeningPortsAssertionError extends AssertionFailedError { - private ListeningPortsAssertionError(String msg) { - super(msg); - } - } -} From 59be169eb952ef3322d344ab4ca00ca6544a1132 Mon Sep 17 00:00:00 2001 From: Brian Muramatsu Date: Wed, 28 Dec 2011 15:46:57 -0800 Subject: [PATCH 0076/1109] Move Test XML Generation from buildCts.py buildCts.py was the central script that generated all the test package XMLs each time CTS was built. This had a couple problems: 1. All the XML files for ~40 packages needed to be made every time CTS was made. Even if those packages were not touched at all. 2. Couldn't shard the XML generation process across the available cores on a machine. A pool was added to the python script, but it was set to a fixed number. This change moves the test XML generation into a smaller Java program called "cts-java-scanner" and the doclet it relies upon to scan the Java files into "cts-java-scanner-doclet.jar". The output of the scanner like "cts-native-scanner" for native EXEs is piped to the existing cts-xml-generator to produce the test XMLs. New CTS specific rules replace the standard BUILD_PACKAGE and BUILD_HOST_JAVA_LIBRARY. They just add extra rules for the package XML. The BUILD_CTS_PACKAGE rule also adds a rule for copying the "package.apk" to something more like "CtsFooTestCases.apk" to the test case out directory. All the apks, exes, and xmls are now thrown into a "cts-testcases" directory, before they are copied to the final CTS distribution. This change should prevent rebuilding the XMLs unnecessarily and make rebuilding CTS quicker while writing tests. There are still the libcore tests that are always rebuilt, but they can be adapted to fit into this model someday... Change-Id: I52a916aa37fd679057e2709bb0ccec694c9fca01 --- tests/cts/net/Android.mk | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index 1fd9ba0c40..1f1e38771d 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -32,5 +32,4 @@ LOCAL_INSTRUMENTATION_FOR := CtsTestStubs # uncomment when dalvik.annotation.Test* are removed or part of SDK #LOCAL_SDK_VERSION := current -include $(BUILD_PACKAGE) - +include $(BUILD_CTS_PACKAGE) From beb5a527e371dceedb16ae1bdc7378889c1897df Mon Sep 17 00:00:00 2001 From: Nick Pelly Date: Thu, 12 Jan 2012 14:40:44 -0800 Subject: [PATCH 0077/1109] CTS tests for Intent.normalize...() API's Change-Id: I5b21028dd29f5bd1565c2ca2f65636ca9aa901d0 --- tests/cts/net/src/android/net/cts/UriTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/UriTest.java b/tests/cts/net/src/android/net/cts/UriTest.java index 067ce52372..0d38f6a1d4 100644 --- a/tests/cts/net/src/android/net/cts/UriTest.java +++ b/tests/cts/net/src/android/net/cts/UriTest.java @@ -724,4 +724,12 @@ public class UriTest extends AndroidTestCase { assertTrue(uri.isHierarchical()); assertEquals(uriString, uri.toString()); } + + public void testNormalize() { + assertEquals(Uri.parse(""), Uri.parse("").normalize()); + assertEquals(Uri.parse("http://www.android.com"), + Uri.parse("http://www.android.com").normalize()); + assertEquals(Uri.parse("http://USER@WWW.ANDROID.COM:100/ABOUT?foo=blah@bar=bleh#c"), + Uri.parse("HTTP://USER@WWW.ANDROID.COM:100/ABOUT?foo=blah@bar=bleh#c").normalize()); + } } From 08acbf9245c28369206701537a9916317e1e964b Mon Sep 17 00:00:00 2001 From: Brian Muramatsu Date: Wed, 25 Jan 2012 18:28:41 -0800 Subject: [PATCH 0078/1109] Remove Test Annotations These annotations are not being parsed by any program. Also they are distracting to readers and are painful to maintain. Furthermore, they prevent us from adding the LOCAL_SDK_CURRENT clause to Makefiles which is useful to detect and stop us from using private APIs. Change-Id: Id93b3a80c73df808c342e489f1434261f288204c --- .../net/cts/ConnectivityManagerTest.java | 57 ---- .../src/android/net/cts/CredentialsTest.java | 27 -- .../net/src/android/net/cts/DhcpInfoTest.java | 16 - .../net/cts/LocalServerSocketTest.java | 40 --- .../net/cts/LocalSocketAddressTest.java | 31 -- .../cts/LocalSocketAddress_NamespaceTest.java | 16 - .../src/android/net/cts/LocalSocketTest.java | 171 ---------- .../net/src/android/net/cts/MailToTest.java | 55 --- .../src/android/net/cts/NetworkInfoTest.java | 2 - .../cts/NetworkInfo_DetailedStateTest.java | 16 - .../net/cts/NetworkInfo_StateTest.java | 16 - .../net/src/android/net/cts/ProxyTest.java | 22 -- .../cts/SSLCertificateSocketFactoryTest.java | 71 ---- .../src/android/net/cts/TrafficStatsTest.java | 23 -- .../cts/net/src/android/net/cts/UriTest.java | 319 ------------------ .../src/android/net/cts/Uri_BuilderTest.java | 109 ------ .../net/cts/UrlQuerySanitizerTest.java | 172 ---------- ...er_IllegalCharacterValueSanitizerTest.java | 19 -- ...QuerySanitizer_ParameterValuePairTest.java | 10 - .../net/http/cts/SslCertificateTest.java | 66 ---- .../http/cts/SslCertificate_DNameTest.java | 37 -- .../android/net/http/cts/SslErrorTest.java | 44 --- .../android/net/wifi/cts/ScanResultTest.java | 9 - .../net/wifi/cts/SupplicantStateTest.java | 12 - .../net/wifi/cts/WifiConfigurationTest.java | 17 - .../android/net/wifi/cts/WifiInfoTest.java | 62 ---- .../android/net/wifi/cts/WifiManagerTest.java | 143 -------- .../wifi/cts/WifiManager_WifiLockTest.java | 37 -- 28 files changed, 1619 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index cd80be2797..99d2e43182 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -16,11 +16,6 @@ package android.net.cts; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargets; -import dalvik.annotation.ToBeFixed; import android.content.BroadcastReceiver; import android.content.Context; @@ -40,7 +35,6 @@ import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -@TestTargetClass(ConnectivityManager.class) public class ConnectivityManagerTest extends AndroidTestCase { private static final String TAG = ConnectivityManagerTest.class.getSimpleName(); @@ -66,11 +60,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { mPackageManager = getContext().getPackageManager(); } - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getNetworkInfo", - args = {int.class} - ) public void testGetNetworkInfo() { assertTrue(mCm.getAllNetworkInfo().length >= MIN_NUM_NETWORK_TYPES); NetworkInfo ni = mCm.getNetworkInfo(TYPE_WIFI); @@ -95,18 +84,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { assertNull(ni); } - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "isNetworkTypeValid", - args = {int.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getAllNetworkInfo", - args = {} - ) - }) public void testIsNetworkTypeValid() { NetworkInfo[] ni = mCm.getAllNetworkInfo(); @@ -117,29 +94,11 @@ public class ConnectivityManagerTest extends AndroidTestCase { assertFalse(ConnectivityManager.isNetworkTypeValid(-1)); } - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test getAllNetworkInfo().", - method = "getAllNetworkInfo", - args = {} - ) public void testGetAllNetworkInfo() { NetworkInfo[] ni = mCm.getAllNetworkInfo(); assertTrue(ni.length >= MIN_NUM_NETWORK_TYPES); } - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "startUsingNetworkFeature", - args = {int.class, java.lang.String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "stopUsingNetworkFeature", - args = {int.class, java.lang.String.class} - ) - }) public void testStartUsingNetworkFeature() { final String invalidateFeature = "invalidateFeature"; @@ -166,11 +125,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { assertEquals(failureCode, mCm.stopUsingNetworkFeature(TYPE_WIFI, mmsFeature)); } - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "requestRouteToHost", - args = {int.class, int.class} - ) public void testRequestRouteToHost() { Set exceptionFreeTypes = new HashSet(); exceptionFreeTypes.add(ConnectivityManager.TYPE_BLUETOOTH); @@ -192,12 +146,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { assertFalse(mCm.requestRouteToHost(-1, HOST_ADDRESS)); } - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getActiveNetworkInfo", - args = {} - ) - @ToBeFixed(bug="1695243", explanation="No Javadoc") public void testGetActiveNetworkInfo() { NetworkInfo ni = mCm.getActiveNetworkInfo(); @@ -206,11 +154,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { } } - @TestTargetNew( - level = TestLevel.SUFFICIENT, - method = "getBackgroundDataSetting", - args = {} - ) public void testTest() { mCm.getBackgroundDataSetting(); } diff --git a/tests/cts/net/src/android/net/cts/CredentialsTest.java b/tests/cts/net/src/android/net/cts/CredentialsTest.java index 6cf8c2351e..91c3621eab 100644 --- a/tests/cts/net/src/android/net/cts/CredentialsTest.java +++ b/tests/cts/net/src/android/net/cts/CredentialsTest.java @@ -18,36 +18,9 @@ package android.net.cts; import android.net.Credentials; import android.test.AndroidTestCase; -import dalvik.annotation.TestTargets; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargetClass; -@TestTargetClass(android.net.Credentials.class) public class CredentialsTest extends AndroidTestCase { - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "Credentials", - args = {int.class, int.class, int.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getGid", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getPid", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getUid", - args = {} - ) - }) public void testCredentials() { // new the Credentials instance // Test with zero inputs diff --git a/tests/cts/net/src/android/net/cts/DhcpInfoTest.java b/tests/cts/net/src/android/net/cts/DhcpInfoTest.java index 97bd27a970..085fdd9132 100644 --- a/tests/cts/net/src/android/net/cts/DhcpInfoTest.java +++ b/tests/cts/net/src/android/net/cts/DhcpInfoTest.java @@ -18,29 +18,13 @@ package android.net.cts; import android.net.DhcpInfo; import android.test.AndroidTestCase; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargetNew; -@TestTargetClass(DhcpInfo.class) public class DhcpInfoTest extends AndroidTestCase { - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test DhcpInfo's constructor.", - method = "DhcpInfo", - args = {} - ) public void testConstructor() { new DhcpInfo(); } - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test toString function.", - method = "toString", - args = {} - ) public void testToString() { String expectedDefault = "ipaddr 0.0.0.0 gateway 0.0.0.0 netmask 0.0.0.0 dns1 0.0.0.0 " + "dns2 0.0.0.0 DHCP server 0.0.0.0 lease 0 seconds"; diff --git a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java index 21c7d5e299..dc7be1ff4e 100644 --- a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java @@ -22,49 +22,9 @@ import android.net.LocalServerSocket; import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.test.AndroidTestCase; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargets; -import dalvik.annotation.ToBeFixed; -@TestTargetClass(LocalServerSocket.class) public class LocalServerSocketTest extends AndroidTestCase { - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "accept", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "close", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getFileDescriptor", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getLocalSocketAddress", - args = {} - ), - @TestTargetNew( - level = TestLevel.NOT_FEASIBLE, - method = "LocalServerSocket", - args = {java.io.FileDescriptor.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "LocalServerSocket", - args = {java.lang.String.class} - ) - }) - @ToBeFixed(bug = "1520987", explanation = "Cannot find a proper FileDescriptor for " + - "android.net.LocalServerSocket constructor") public void testLocalServerSocket() throws IOException { LocalServerSocket localServerSocket = new LocalServerSocket(LocalSocketTest.mSockAddr); assertNotNull(localServerSocket.getLocalSocketAddress()); diff --git a/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java b/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java index e3141d57e5..6ef003b26f 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketAddressTest.java @@ -19,40 +19,9 @@ package android.net.cts; import android.net.LocalSocketAddress; import android.net.LocalSocketAddress.Namespace; import android.test.AndroidTestCase; -import dalvik.annotation.TestTargets; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargetClass; -@TestTargetClass(LocalSocketAddress.class) public class LocalSocketAddressTest extends AndroidTestCase { - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test LocalSocketAddress", - method = "LocalSocketAddress", - args = {java.lang.String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test LocalSocketAddress", - method = "LocalSocketAddress", - args = {java.lang.String.class, android.net.LocalSocketAddress.Namespace.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test LocalSocketAddress", - method = "getName", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test LocalSocketAddress", - method = "getNamespace", - args = {} - ) - }) public void testNewLocalSocketAddressWithDefaultNamespace() { // default namespace LocalSocketAddress localSocketAddress = new LocalSocketAddress("name"); diff --git a/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java b/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java index fc9de5b14c..97dfa435fa 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketAddress_NamespaceTest.java @@ -18,31 +18,15 @@ package android.net.cts; import android.net.LocalSocketAddress.Namespace; import android.test.AndroidTestCase; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargetNew; -@TestTargetClass(Namespace.class) public class LocalSocketAddress_NamespaceTest extends AndroidTestCase { - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test valueOf(String name).", - method = "valueOf", - args = {java.lang.String.class} - ) public void testValueOf() { assertEquals(Namespace.ABSTRACT, Namespace.valueOf("ABSTRACT")); assertEquals(Namespace.RESERVED, Namespace.valueOf("RESERVED")); assertEquals(Namespace.FILESYSTEM, Namespace.valueOf("FILESYSTEM")); } - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test values().", - method = "values", - args = {} - ) public void testValues() { Namespace[] expected = Namespace.values(); assertEquals(Namespace.ABSTRACT, expected[0]); diff --git a/tests/cts/net/src/android/net/cts/LocalSocketTest.java b/tests/cts/net/src/android/net/cts/LocalSocketTest.java index 8e3cd6714b..0a4bc0d4f2 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketTest.java @@ -25,89 +25,10 @@ import android.net.LocalServerSocket; import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.test.AndroidTestCase; -import dalvik.annotation.TestTargets; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargetClass; -@TestTargetClass(LocalSocket.class) public class LocalSocketTest extends AndroidTestCase{ public final static String mSockAddr = "com.android.net.LocalSocketTest"; - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test core functions of LocalSocket", - method = "LocalSocket", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test core functions of LocalSocket", - method = "close", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test core functions of LocalSocket", - method = "connect", - args = {android.net.LocalSocketAddress.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test core functions of LocalSocket", - method = "getAncillaryFileDescriptors", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test core functions of LocalSocket", - method = "getFileDescriptor", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test core functions of LocalSocket", - method = "getInputStream", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test core functions of LocalSocket", - method = "getOutputStream", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test core functions of LocalSocket", - method = "getPeerCredentials", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test core functions of LocalSocket", - method = "isConnected", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test core functions of LocalSocket", - method = "setFileDescriptorsForSend", - args = {java.io.FileDescriptor[].class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test core functions of LocalSocket", - method = "shutdownInput", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test core functions of LocalSocket", - method = "shutdownOutput", - args = {} - ) - }) public void testLocalConnections() throws IOException{ // create client and server socket LocalServerSocket localServerSocket = new LocalServerSocket(mSockAddr); @@ -190,98 +111,6 @@ public class LocalSocketTest extends AndroidTestCase{ } } - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test secondary functions of LocalSocket", - method = "bind", - args = {android.net.LocalSocketAddress.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test secondary functions of LocalSocket", - method = "connect", - args = {android.net.LocalSocketAddress.class, int.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test secondary functions of LocalSocket", - method = "getLocalSocketAddress", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test secondary functions of LocalSocket", - method = "getReceiveBufferSize", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test secondary functions of LocalSocket", - method = "getRemoteSocketAddress", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test secondary functions of LocalSocket", - method = "getSendBufferSize", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test secondary functions of LocalSocket", - method = "getSoTimeout", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test secondary functions of LocalSocket", - method = "isBound", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test secondary functions of LocalSocket", - method = "isClosed", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test secondary functions of LocalSocket", - method = "isInputShutdown", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test secondary functions of LocalSocket", - method = "isOutputShutdown", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test secondary functions of LocalSocket", - method = "setReceiveBufferSize", - args = {int.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test secondary functions of LocalSocket", - method = "setSendBufferSize", - args = {int.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test secondary functions of LocalSocket", - method = "setSoTimeout", - args = {int.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "test secondary functions of LocalSocket", - method = "toString", - args = {} - ) - }) public void testAccessors() throws IOException{ LocalSocket socket = new LocalSocket(); LocalSocketAddress addr = new LocalSocketAddress("secondary"); diff --git a/tests/cts/net/src/android/net/cts/MailToTest.java b/tests/cts/net/src/android/net/cts/MailToTest.java index 01ede1aea0..e454d20628 100644 --- a/tests/cts/net/src/android/net/cts/MailToTest.java +++ b/tests/cts/net/src/android/net/cts/MailToTest.java @@ -19,12 +19,7 @@ package android.net.cts; import android.net.MailTo; import android.test.AndroidTestCase; import android.util.Log; -import dalvik.annotation.TestTargets; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargetClass; -@TestTargetClass(MailTo.class) public class MailToTest extends AndroidTestCase { private static final String MAILTOURI_1 = "mailto:chris@example.com"; private static final String MAILTOURI_2 = "mailto:infobot@example.com?subject=current-issue"; @@ -42,56 +37,6 @@ public class MailToTest extends AndroidTestCase { super.setUp(); } - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test parse mailto URI.", - method = "parse", - args = {java.lang.String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test parse mailto URI.", - method = "isMailTo", - args = {java.lang.String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test parse mailto URI.", - method = "getTo", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test parse mailto URI.", - method = "getSubject", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test parse mailto URI.", - method = "getBody", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test parse mailto URI.", - method = "getCc", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test parse mailto URI.", - method = "toString", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test parse mailto URI.", - method = "getHeaders", - args = {} - ) - }) public void testParseMailToURI() { assertFalse(MailTo.isMailTo(null)); assertFalse(MailTo.isMailTo("")); diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java index 6800c43b0a..e53614b99a 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java @@ -16,7 +16,6 @@ package android.net.cts; -import dalvik.annotation.TestTargetClass; import android.content.Context; import android.net.ConnectivityManager; @@ -25,7 +24,6 @@ import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; import android.test.AndroidTestCase; -@TestTargetClass(NetworkInfo.class) public class NetworkInfoTest extends AndroidTestCase { public static final int TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE; diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java index 6b9b985122..3eeb1c5c84 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java @@ -16,22 +16,12 @@ package android.net.cts; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargetNew; import android.net.NetworkInfo.DetailedState; import android.test.AndroidTestCase; -@TestTargetClass(DetailedState.class) public class NetworkInfo_DetailedStateTest extends AndroidTestCase { - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test valueOf(String name).", - method = "valueOf", - args = {java.lang.String.class} - ) public void testValueOf() { assertEquals(DetailedState.AUTHENTICATING, DetailedState.valueOf("AUTHENTICATING")); assertEquals(DetailedState.CONNECTED, DetailedState.valueOf("CONNECTED")); @@ -45,12 +35,6 @@ public class NetworkInfo_DetailedStateTest extends AndroidTestCase { assertEquals(DetailedState.SUSPENDED, DetailedState.valueOf("SUSPENDED")); } - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test values().", - method = "values", - args = {} - ) public void testValues() { DetailedState[] expected = DetailedState.values(); assertEquals(11, expected.length); diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java index 1a51acd091..5303ef1281 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_StateTest.java @@ -18,19 +18,9 @@ package android.net.cts; import android.net.NetworkInfo.State; import android.test.AndroidTestCase; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargetNew; -@TestTargetClass(State.class) public class NetworkInfo_StateTest extends AndroidTestCase { - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test valueOf(String name).", - method = "valueOf", - args = {java.lang.String.class} - ) public void testValueOf() { assertEquals(State.CONNECTED, State.valueOf("CONNECTED")); assertEquals(State.CONNECTING, State.valueOf("CONNECTING")); @@ -40,12 +30,6 @@ public class NetworkInfo_StateTest extends AndroidTestCase { assertEquals(State.UNKNOWN, State.valueOf("UNKNOWN")); } - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test values().", - method = "values", - args = {} - ) public void testValues() { State[] expected = State.values(); assertEquals(6, expected.length); diff --git a/tests/cts/net/src/android/net/cts/ProxyTest.java b/tests/cts/net/src/android/net/cts/ProxyTest.java index 0c0586ea84..467d12f9dc 100644 --- a/tests/cts/net/src/android/net/cts/ProxyTest.java +++ b/tests/cts/net/src/android/net/cts/ProxyTest.java @@ -16,38 +16,16 @@ package android.net.cts; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargets; import android.net.Proxy; import android.test.AndroidTestCase; -@TestTargetClass(Proxy.class) public class ProxyTest extends AndroidTestCase { - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "Proxy", - args = {} - ) public void testConstructor() { new Proxy(); } - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getDefaultPort", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getDefaultHost", - args = {} - ) - }) public void testAccessProperties() { final int minValidPort = 0; final int maxValidPort = 65535; diff --git a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java index f125550a8b..70ab54d3cd 100644 --- a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java +++ b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java @@ -27,13 +27,7 @@ import android.net.SSLCertificateSocketFactory; import android.test.AndroidTestCase; import dalvik.annotation.BrokenTest; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargets; -import dalvik.annotation.ToBeFixed; -@TestTargetClass(SSLCertificateSocketFactory.class) public class SSLCertificateSocketFactoryTest extends AndroidTestCase { private SSLCertificateSocketFactory mFactory; private int mTimeout; @@ -45,24 +39,6 @@ public class SSLCertificateSocketFactoryTest extends AndroidTestCase { mFactory = (SSLCertificateSocketFactory) SSLCertificateSocketFactory.getDefault(mTimeout); } - @TestTargets({ - @TestTargetNew( - level = TestLevel.PARTIAL, - method = "getSupportedCipherSuites", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getDefault", - args = {int.class} - ), - @TestTargetNew( - level = TestLevel.PARTIAL, - method = "getDefaultCipherSuites", - args = {} - ) - }) - @ToBeFixed(bug="1695243", explanation="Android API javadocs are incomplete") public void testAccessProperties() throws Exception { mFactory.getSupportedCipherSuites(); mFactory.getDefaultCipherSuites(); @@ -70,38 +46,6 @@ public class SSLCertificateSocketFactoryTest extends AndroidTestCase { assertNotNull(sf); } - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "createSocket", - args = {java.net.InetAddress.class, int.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "createSocket", - args = {java.net.Socket.class, java.lang.String.class, int.class, boolean.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "createSocket", - args = {java.lang.String.class, int.class} - ), - @TestTargetNew( - level = TestLevel.NOT_FEASIBLE, - method = "createSocket", - args = {java.lang.String.class, int.class, java.net.InetAddress.class, int.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "createSocket", - args = {java.net.InetAddress.class, int.class, java.net.InetAddress.class, int.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "SSLCertificateSocketFactory", - args = {int.class} - ) - }) public void testCreateSocket() throws Exception { new SSLCertificateSocketFactory(100); int port = 443; @@ -153,11 +97,6 @@ public class SSLCertificateSocketFactoryTest extends AndroidTestCase { * * NOTE: Test will fail if external server is not available. */ - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "createSocket", - args = {String.class, int.class} - ) public void test_createSocket_simple() throws Exception { try { mFactory.createSocket(TEST_CREATE_SOCKET_HOST, TEST_CREATE_SOCKET_PORT); @@ -174,11 +113,6 @@ public class SSLCertificateSocketFactoryTest extends AndroidTestCase { * * NOTE: Test will fail if external server is not available. */ - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "createSocket", - args = {Socket.class, String.class, int.class, boolean.class} - ) public void test_createSocket_wrapping() throws Exception { try { Socket underlying = new Socket(TEST_CREATE_SOCKET_HOST, TEST_CREATE_SOCKET_PORT); @@ -197,11 +131,6 @@ public class SSLCertificateSocketFactoryTest extends AndroidTestCase { * * NOTE: Test will fail if external server is not available. */ - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "createSocket", - args = {String.class, int.class, InetAddress.class, int.class} - ) public void test_createSocket_bind() throws Exception { try { mFactory.createSocket(TEST_CREATE_SOCKET_HOST, TEST_CREATE_SOCKET_PORT, null, 0); diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java index 183f891637..a5bbd9886a 100644 --- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java +++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java @@ -16,10 +16,6 @@ package android.net.cts; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargets; import android.net.TrafficStats; import android.os.Process; @@ -31,14 +27,7 @@ import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; -@TestTargetClass(TrafficStats.class) public class TrafficStatsTest extends AndroidTestCase { - @TestTargets({ - @TestTargetNew(level = TestLevel.SUFFICIENT, method = "getMobileTxPackets"), - @TestTargetNew(level = TestLevel.SUFFICIENT, method = "getMobileRxPackets"), - @TestTargetNew(level = TestLevel.SUFFICIENT, method = "getMobileTxBytes"), - @TestTargetNew(level = TestLevel.SUFFICIENT, method = "getMobileRxBytes") - }) public void testGetMobileStats() { // We can't assume a mobile network is even present in this test, so // we simply assert that a valid value is returned. @@ -53,18 +42,6 @@ public class TrafficStatsTest extends AndroidTestCase { TrafficStats.getMobileRxBytes() >= 0); } - @TestTargets({ - @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getMobileTxPackets"), - @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getMobileRxPackets"), - @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getMobileTxBytes"), - @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getMobileRxBytes"), - @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getTotalTxPackets"), - @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getTotalRxPackets"), - @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getTotalTxBytes"), - @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getTotalRxBytes"), - @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getUidTxBytes"), - @TestTargetNew(level = TestLevel.PARTIAL_COMPLETE, method = "getUidRxBytes") - }) public void testTrafficStatsForLocalhost() throws IOException { long mobileTxPacketsBefore = TrafficStats.getTotalTxPackets(); long mobileRxPacketsBefore = TrafficStats.getTotalRxPackets(); diff --git a/tests/cts/net/src/android/net/cts/UriTest.java b/tests/cts/net/src/android/net/cts/UriTest.java index 0d38f6a1d4..3bf8049b0a 100644 --- a/tests/cts/net/src/android/net/cts/UriTest.java +++ b/tests/cts/net/src/android/net/cts/UriTest.java @@ -16,10 +16,6 @@ package android.net.cts; -import dalvik.annotation.TestTargets; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargetNew; import android.content.ContentUris; import android.net.Uri; import android.os.Parcel; @@ -27,14 +23,7 @@ import android.test.AndroidTestCase; import java.io.File; import java.util.Arrays; -@TestTargetClass(Uri.class) public class UriTest extends AndroidTestCase { - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test write to and read frome parcel.", - method = "writeToParcel", - args = {android.os.Parcel.class, android.net.Uri.class} - ) public void testParcelling() { parcelAndUnparcel(Uri.parse("foo:bob%20lee")); parcelAndUnparcel(Uri.fromParts("foo", "bob lee", "fragment")); @@ -60,12 +49,6 @@ public class UriTest extends AndroidTestCase { assertEquals(u, Uri.CREATOR.createFromParcel(p)); } - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test buildUpon", - method = "buildUpon", - args = {} - ) public void testBuildUpon() { Uri u = Uri.parse("bob:lee").buildUpon().scheme("robert").build(); assertEquals("robert", u.getScheme()); @@ -92,80 +75,6 @@ public class UriTest extends AndroidTestCase { assertEquals("foo", b.getScheme()); } - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test string uri.", - method = "getSchemeSpecificPart", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test string uri.", - method = "getEncodedSchemeSpecificPart", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test string uri.", - method = "getEncodedPath", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test string uri.", - method = "getPath", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test string uri.", - method = "getEncodedQuery", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test string uri.", - method = "getQuery", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test string uri.", - method = "getEncodedFragment", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test string uri.", - method = "getHost", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test string uri.", - method = "getPort", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test string uri.", - method = "getUserInfo", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test string uri.", - method = "getEncodedUserInfo", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test string uri.", - method = "parse", - args = {java.lang.String.class} - ) - }) public void testStringUri() { assertEquals("bob lee", Uri.parse("foo:bob%20lee").getSchemeSpecificPart()); @@ -202,12 +111,6 @@ public class UriTest extends AndroidTestCase { assertEquals(-1, uri.getPort()); } - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test compareTo", - method = "compareTo", - args = {android.net.Uri.class} - ) public void testCompareTo() { Uri a = Uri.parse("foo:a"); Uri b = Uri.parse("foo:b"); @@ -218,20 +121,6 @@ public class UriTest extends AndroidTestCase { assertEquals(0, b.compareTo(b2)); } - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test equals and hashCode.", - method = "equals", - args = {java.lang.Object.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test equals and hashCode.", - method = "hashCode", - args = {} - ) - }) public void testEqualsAndHashCode() { Uri a = Uri.parse("http://crazybob.org/test/?foo=bar#tee"); @@ -260,26 +149,6 @@ public class UriTest extends AndroidTestCase { assertEquals(b.hashCode(), c.hashCode()); } - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test encode and decode.", - method = "encode", - args = {java.lang.String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test encode and decode.", - method = "encode", - args = {java.lang.String.class, java.lang.String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test encode and decode.", - method = "decode", - args = {java.lang.String.class} - ) - }) public void testEncodeAndDecode() { String encoded = Uri.encode("Bob:/", "/"); assertEquals(-1, encoded.indexOf(':')); @@ -300,12 +169,6 @@ public class UriTest extends AndroidTestCase { assertEquals(s, Uri.decode(Uri.encode(s, null))); } - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test fromFile.", - method = "fromFile", - args = {java.io.File.class} - ) public void testFromFile() { File f = new File("/tmp/bob"); Uri uri = Uri.fromFile(f); @@ -316,20 +179,6 @@ public class UriTest extends AndroidTestCase { } catch (NullPointerException e) {} } - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test get query parameters.", - method = "getQueryParameter", - args = {java.lang.String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test get query parameters.", - method = "getQueryParameters", - args = {java.lang.String.class} - ) - }) public void testQueryParameters() { Uri uri = Uri.parse("content://user"); assertEquals(null, uri.getQueryParameter("a")); @@ -345,26 +194,6 @@ public class UriTest extends AndroidTestCase { assertEquals("d", uri.getQueryParameter("c")); } - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "", - method = "getPathSegments", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "", - method = "getLastPathSegment", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "", - method = "withAppendedPath", - args = {android.net.Uri.class, java.lang.String.class} - ) - }) public void testPathOperations() { Uri uri = Uri.parse("content://user/a/b"); @@ -402,62 +231,6 @@ public class UriTest extends AndroidTestCase { assertEquals("/a/b/c", withC.getPath()); } - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test opaque uri.", - method = "isAbsolute", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test opaque uri.", - method = "isOpaque", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test opaque uri.", - method = "isRelative", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test opaque uri.", - method = "getHost", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test opaque uri.", - method = "getPort", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test opaque uri.", - method = "getScheme", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test opaque uri.", - method = "getSchemeSpecificPart", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test opaque uri.", - method = "fromParts", - args = {java.lang.String.class, java.lang.String.class, java.lang.String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test opaque uri.", - method = "toString", - args = {} - ) - }) public void testOpaqueUri() { Uri uri = Uri.parse("mailto:nobody"); testOpaqueUri(uri); @@ -512,98 +285,6 @@ public class UriTest extends AndroidTestCase { assertEquals("mailto:nobody#top", withFragment.toString()); } - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test hierarchical uris.", - method = "getAuthority", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test hierarchical uris.", - method = "getScheme", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test hierarchical uris.", - method = "getEncodedAuthority", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test hierarchical uris.", - method = "getPath", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test hierarchical uris.", - method = "getEncodedPath", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test hierarchical uris.", - method = "getQuery", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test hierarchical uris.", - method = "getEncodedQuery", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test hierarchical uris.", - method = "getFragment", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test hierarchical uris.", - method = "getEncodedFragment", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test hierarchical uris.", - method = "getSchemeSpecificPart", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test hierarchical uris.", - method = "isAbsolute", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test hierarchical uris.", - method = "isHierarchical", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test hierarchical uris.", - method = "isOpaque", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test hierarchical uris.", - method = "isRelative", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test hierarchical uris.", - method = "toString", - args = {} - ) - }) public void testHierarchicalUris() { testHierarchical("http", "google.com", "/p1/p2", "query", "fragment"); testHierarchical("file", null, "/p1/p2", null, null); diff --git a/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java b/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java index 66bdb074b0..4088d822cf 100644 --- a/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java +++ b/tests/cts/net/src/android/net/cts/Uri_BuilderTest.java @@ -17,119 +17,10 @@ package android.net.cts; import junit.framework.TestCase; -import dalvik.annotation.TestTargets; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargetClass; import android.net.Uri.Builder; import android.net.Uri; -@TestTargetClass(Uri.Builder.class) public class Uri_BuilderTest extends TestCase { - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test Builder operations.", - method = "Uri.Builder", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test Builder operations.", - method = "build", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test Builder operations.", - method = "scheme", - args = {java.lang.String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test Builder operations.", - method = "authority", - args = {java.lang.String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test Builder operations.", - method = "path", - args = {java.lang.String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test Builder operations.", - method = "query", - args = {java.lang.String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test Builder operations.", - method = "opaquePart", - args = {java.lang.String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test Builder operations.", - method = "fragment", - args = {java.lang.String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test Builder operations.", - method = "appendEncodedPath", - args = {java.lang.String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test Builder operations.", - method = "appendPath", - args = {java.lang.String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test Builder operations.", - method = "appendQueryParameter", - args = {java.lang.String.class, java.lang.String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test Builder operations.", - method = "encodedAuthority", - args = {java.lang.String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test Builder operations.", - method = "encodedFragment", - args = {java.lang.String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test Builder operations.", - method = "encodedPath", - args = {java.lang.String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test Builder operations.", - method = "encodedQuery", - args = {java.lang.String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test Builder operations.", - method = "encodedOpaquePart", - args = {java.lang.String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test Builder operations.", - method = "toString", - args = {} - ) - }) public void testBuilderOperations() { Uri uri = Uri.parse("http://google.com/p1?query#fragment"); Builder builder = uri.buildUpon(); diff --git a/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java b/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java index 0dd5db1886..7076ea2990 100644 --- a/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java +++ b/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java @@ -23,12 +23,7 @@ import android.net.UrlQuerySanitizer.IllegalCharacterValueSanitizer; import android.net.UrlQuerySanitizer.ParameterValuePair; import android.net.UrlQuerySanitizer.ValueSanitizer; import android.test.AndroidTestCase; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargets; -@TestTargetClass(UrlQuerySanitizer.class) public class UrlQuerySanitizerTest extends AndroidTestCase { private static final int ALL_OK = IllegalCharacterValueSanitizer.ALL_OK; @@ -46,173 +41,6 @@ public class UrlQuerySanitizerTest extends AndroidTestCase { private static final String AGE = "age"; private static final String HEIGHT = "height"; - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "UrlQuerySanitizer", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "UrlQuerySanitizer", - args = {String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "parseUrl", - args = {String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "parseQuery", - args = {String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "parseEntry", - args = {String.class, String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getValue", - args = {String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "addSanitizedEntry", - args = {String.class, String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "hasParameter", - args = {String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getParameterSet", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getParameterList", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "setUnregisteredParameterValueSanitizer", - args = {ValueSanitizer.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getUnregisteredParameterValueSanitizer", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getAllButNulAndAngleBracketsLegal", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getAllButNulLegal", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getAllButWhitespaceLegal", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getAllIllegal", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getAmpAndSpaceLegal", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getAmpLegal", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getSpaceLegal", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getUrlAndSpaceLegal", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getUrlLegal", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "unescape", - args = {String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "isHexDigit", - args = {char.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "decodeHexDigit", - args = {char.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "setAllowUnregisteredParamaters", - args = {boolean.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getAllowUnregisteredParamaters", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "registerParameter", - args = {String.class, ValueSanitizer.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "registerParameters", - args = {String[].class, ValueSanitizer.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getEffectiveValueSanitizer", - args = {String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getValueSanitizer", - args = {String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "clear", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "setPreferFirstRepeatedParameter", - args = {boolean.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getPreferFirstRepeatedParameter", - args = {} - ) - }) public void testUrlQuerySanitizer() { MockUrlQuerySanitizer uqs = new MockUrlQuerySanitizer(); assertFalse(uqs.getAllowUnregisteredParamaters()); diff --git a/tests/cts/net/src/android/net/cts/UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java b/tests/cts/net/src/android/net/cts/UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java index f85a5347e0..f86af3114e 100644 --- a/tests/cts/net/src/android/net/cts/UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java +++ b/tests/cts/net/src/android/net/cts/UrlQuerySanitizer_IllegalCharacterValueSanitizerTest.java @@ -19,28 +19,9 @@ package android.net.cts; import android.net.UrlQuerySanitizer; import android.net.UrlQuerySanitizer.IllegalCharacterValueSanitizer; import android.test.AndroidTestCase; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargets; -@TestTargetClass(UrlQuerySanitizer.IllegalCharacterValueSanitizer.class) public class UrlQuerySanitizer_IllegalCharacterValueSanitizerTest extends AndroidTestCase { static final int SPACE_OK = IllegalCharacterValueSanitizer.SPACE_OK; - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test constructor(s) of {@link IllegalCharacterValueSanitizer}", - method = "IllegalCharacterValueSanitizer", - args = {int.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "Test method: sanitize", - method = "sanitize", - args = {String.class} - ) - }) public void testSanitize() { IllegalCharacterValueSanitizer sanitizer = new IllegalCharacterValueSanitizer(SPACE_OK); assertEquals("Joe User", sanitizer.sanitize("Joe scanResults = mWifiManager.getScanResults(); // this test case should in Wifi environment diff --git a/tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java b/tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java index 4e03f5e9ce..075138fc65 100644 --- a/tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java @@ -18,21 +18,9 @@ package android.net.wifi.cts; import android.net.wifi.SupplicantState; import android.test.AndroidTestCase; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargets; -@TestTargetClass(SupplicantState.class) public class SupplicantStateTest extends AndroidTestCase { - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "isValidState", - args = {android.net.wifi.SupplicantState.class} - ) - }) public void testIsValidState() { assertTrue(SupplicantState.isValidState(SupplicantState.DISCONNECTED)); assertTrue(SupplicantState.isValidState(SupplicantState.INACTIVE)); diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java index 3018907092..4874feb212 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java @@ -22,12 +22,7 @@ import android.content.Context; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.test.AndroidTestCase; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargets; -@TestTargetClass(WifiConfiguration.class) public class WifiConfigurationTest extends AndroidTestCase { private WifiManager mWifiManager; @Override @@ -37,18 +32,6 @@ public class WifiConfigurationTest extends AndroidTestCase { .getSystemService(Context.WIFI_SERVICE); } - @TestTargets({ - @TestTargetNew( - level = TestLevel.PARTIAL, - method = "WifiConfiguration", - args = {} - ), - @TestTargetNew( - level = TestLevel.PARTIAL, - method = "toString", - args = {} - ) - }) public void testWifiConfiguration() { List wifiConfigurations = mWifiManager.getConfiguredNetworks(); for (int i = 0; i < wifiConfigurations.size(); i++) { diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java index 44189cd13a..0bf25aa4b2 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java @@ -16,10 +16,6 @@ package android.net.wifi.cts; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargets; import android.content.BroadcastReceiver; import android.content.Context; @@ -31,7 +27,6 @@ import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.WifiLock; import android.test.AndroidTestCase; -@TestTargetClass(WifiInfo.class) public class WifiInfoTest extends AndroidTestCase { private static class MySync { int expectedState = STATE_NULL; @@ -103,63 +98,6 @@ public class WifiInfoTest extends AndroidTestCase { } } - @TestTargets({ - @TestTargetNew( - level = TestLevel.PARTIAL, - method = "getMacAddress", - args = {} - ), - @TestTargetNew( - level = TestLevel.PARTIAL, - method = "getIpAddress", - args = {} - ), - @TestTargetNew( - level = TestLevel.PARTIAL, - method = "getDetailedStateOf", - args = {android.net.wifi.SupplicantState.class} - ), - @TestTargetNew( - level = TestLevel.PARTIAL, - method = "getNetworkId", - args = {} - ), - @TestTargetNew( - level = TestLevel.PARTIAL, - method = "getSSID", - args = {} - ), - @TestTargetNew( - level = TestLevel.PARTIAL, - method = "getBSSID", - args = {} - ), - @TestTargetNew( - level = TestLevel.PARTIAL, - method = "getSupplicantState", - args = {} - ), - @TestTargetNew( - level = TestLevel.PARTIAL, - method = "getLinkSpeed", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "toString", - args = {} - ), - @TestTargetNew( - level = TestLevel.PARTIAL, - method = "getRssi", - args = {} - ), - @TestTargetNew( - level = TestLevel.PARTIAL, - method = "getHiddenSSID", - args = {} - ) - }) public void testWifiInfoProperties() throws Exception { // this test case should in Wifi environment WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index e2a583b6ef..b3fec542b7 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -16,10 +16,6 @@ package android.net.wifi.cts; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargets; import android.content.BroadcastReceiver; import android.content.Context; @@ -37,7 +33,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -@TestTargetClass(WifiManager.class) public class WifiManagerTest extends AndroidTestCase { private static class MySync { int expectedState = STATE_NULL; @@ -177,58 +172,6 @@ public class WifiManagerTest extends AndroidTestCase { * 4.pingSupplicant * 5.satrtScan */ - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "isWifiEnabled", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "setWifiEnabled", - args = {boolean.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "startScan", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getScanResults", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "pingSupplicant", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "reassociate", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "reconnect", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "disconnect", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "createWifiLock", - args = {int.class, String.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "createWifiLock", - args = {String.class} - ) - }) public void testWifiManagerActions() throws Exception { assertTrue(mWifiManager.reconnect()); assertTrue(mWifiManager.reassociate()); @@ -250,33 +193,6 @@ public class WifiManagerTest extends AndroidTestCase { * 3.wifi state * 4.ConnectionInfo */ - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "isWifiEnabled", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getWifiState", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "setWifiEnabled", - args = {boolean.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getConnectionInfo", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getDhcpInfo", - args = {} - ) - }) public void testWifiManagerProperties() throws Exception { setWifiEnabled(true); assertTrue(mWifiManager.isWifiEnabled()); @@ -297,53 +213,6 @@ public class WifiManagerTest extends AndroidTestCase { * 6.configured Networks * 7.save configure; */ - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "isWifiEnabled", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "setWifiEnabled", - args = {boolean.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "getConfiguredNetworks", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "addNetwork", - args = {android.net.wifi.WifiConfiguration.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "updateNetwork", - args = {android.net.wifi.WifiConfiguration.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "removeNetwork", - args = {int.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "enableNetwork", - args = {int.class, boolean.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "disableNetwork", - args = {int.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "saveConfiguration", - args = {} - ) - }) public void testWifiManagerNetWork() throws Exception { // store the list of enabled networks, so they can be re-enabled after test completes Set enabledSsids = getEnabledNetworks(mWifiManager.getConfiguredNetworks()); @@ -428,18 +297,6 @@ public class WifiManagerTest extends AndroidTestCase { } } - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "compareSignalLevel", - args = {int.class, int.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "calculateSignalLevel", - args = {int.class, int.class} - ) - }) public void testSignal() { final int numLevels = 9; int expectLevel = 0; diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java index 53150c9650..d48bfb87f2 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java @@ -20,48 +20,11 @@ import android.content.Context; import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.WifiLock; import android.test.AndroidTestCase; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargets; -@TestTargetClass(WifiManager.WifiLock.class) public class WifiManager_WifiLockTest extends AndroidTestCase { private static final String WIFI_TAG = "WifiManager_WifiLockTest"; - @TestTargets({ - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "acquire", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "finalize", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "isHeld", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "release", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "setReferenceCounted", - args = {boolean.class} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "toString", - args = {} - ) - }) public void testWifiLock() { WifiManager wm = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); WifiLock wl = wm.createWifiLock(WIFI_TAG); From a36a66a5422bc54af1e8205a9c8c23117515a818 Mon Sep 17 00:00:00 2001 From: Keun young Park Date: Fri, 10 Feb 2012 15:20:37 -0800 Subject: [PATCH 0079/1109] skip WiFi test if not supproted - Support info is coming from PackageManager Bug: 5547397 Change-Id: I35d0ac82fe31a436d38d0436d32c0bb194eba3a6 --- .../android/net/wifi/cts/ScanResultTest.java | 13 +++++++++ .../net/wifi/cts/SupplicantStateTest.java | 4 +++ .../net/wifi/cts/WifiConfigurationTest.java | 4 +++ .../src/android/net/wifi/cts/WifiFeature.java | 28 +++++++++++++++++++ .../android/net/wifi/cts/WifiInfoTest.java | 13 +++++++++ .../android/net/wifi/cts/WifiManagerTest.java | 25 +++++++++++++++++ .../wifi/cts/WifiManager_WifiLockTest.java | 4 +++ 7 files changed, 91 insertions(+) create mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiFeature.java diff --git a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java index 0ab71c70e4..b7202d25ec 100644 --- a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java @@ -65,6 +65,10 @@ public class ScanResultTest extends AndroidTestCase { @Override protected void setUp() throws Exception { super.setUp(); + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } mMySync = new MySync(); mIntentFilter = new IntentFilter(); mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); @@ -90,6 +94,11 @@ public class ScanResultTest extends AndroidTestCase { @Override protected void tearDown() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + super.tearDown(); + return; + } mWifiLock.release(); mContext.unregisterReceiver(mReceiver); if (!mWifiManager.isWifiEnabled()) @@ -115,6 +124,10 @@ public class ScanResultTest extends AndroidTestCase { args = {} ) public void testScanResultProperties() { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } List scanResults = mWifiManager.getScanResults(); // this test case should in Wifi environment for (int i = 0; i < scanResults.size(); i++) { diff --git a/tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java b/tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java index 4e03f5e9ce..88ecfe8a61 100644 --- a/tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java @@ -34,6 +34,10 @@ public class SupplicantStateTest extends AndroidTestCase { ) }) public void testIsValidState() { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } assertTrue(SupplicantState.isValidState(SupplicantState.DISCONNECTED)); assertTrue(SupplicantState.isValidState(SupplicantState.INACTIVE)); assertTrue(SupplicantState.isValidState(SupplicantState.SCANNING)); diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java index 3018907092..f11aa4aa26 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java @@ -50,6 +50,10 @@ public class WifiConfigurationTest extends AndroidTestCase { ) }) public void testWifiConfiguration() { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } List wifiConfigurations = mWifiManager.getConfiguredNetworks(); for (int i = 0; i < wifiConfigurations.size(); i++) { WifiConfiguration wifiConfiguration = wifiConfigurations.get(i); diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiFeature.java b/tests/cts/net/src/android/net/wifi/cts/WifiFeature.java new file mode 100644 index 0000000000..d7a83c302f --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/cts/WifiFeature.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2012 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.wifi.cts; + +import android.content.Context; +import android.content.pm.PackageManager; + +public class WifiFeature { + static boolean isWifiSupported(Context context) { + PackageManager packageManager = context.getPackageManager(); + return packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI); + } +} + diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java index 44189cd13a..2713dfdd3f 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java @@ -66,6 +66,10 @@ public class WifiInfoTest extends AndroidTestCase { @Override protected void setUp() throws Exception { super.setUp(); + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } mMySync = new MySync(); mIntentFilter = new IntentFilter(); mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); @@ -84,6 +88,11 @@ public class WifiInfoTest extends AndroidTestCase { @Override protected void tearDown() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + super.tearDown(); + return; + } mWifiLock.release(); mContext.unregisterReceiver(mReceiver); if (!mWifiManager.isWifiEnabled()) @@ -161,6 +170,10 @@ public class WifiInfoTest extends AndroidTestCase { ) }) public void testWifiInfoProperties() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } // this test case should in Wifi environment WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index e2a583b6ef..014f0eed6f 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -90,6 +90,10 @@ public class WifiManagerTest extends AndroidTestCase { @Override protected void setUp() throws Exception { super.setUp(); + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } mMySync = new MySync(); mIntentFilter = new IntentFilter(); mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); @@ -115,6 +119,11 @@ public class WifiManagerTest extends AndroidTestCase { @Override protected void tearDown() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + super.tearDown(); + return; + } mWifiLock.release(); mContext.unregisterReceiver(mReceiver); if (!mWifiManager.isWifiEnabled()) @@ -230,6 +239,10 @@ public class WifiManagerTest extends AndroidTestCase { ) }) public void testWifiManagerActions() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } assertTrue(mWifiManager.reconnect()); assertTrue(mWifiManager.reassociate()); assertTrue(mWifiManager.disconnect()); @@ -278,6 +291,10 @@ public class WifiManagerTest extends AndroidTestCase { ) }) public void testWifiManagerProperties() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } setWifiEnabled(true); assertTrue(mWifiManager.isWifiEnabled()); assertNotNull(mWifiManager.getDhcpInfo()); @@ -345,6 +362,10 @@ public class WifiManagerTest extends AndroidTestCase { ) }) public void testWifiManagerNetWork() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } // store the list of enabled networks, so they can be re-enabled after test completes Set enabledSsids = getEnabledNetworks(mWifiManager.getConfiguredNetworks()); try { @@ -441,6 +462,10 @@ public class WifiManagerTest extends AndroidTestCase { ) }) public void testSignal() { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } final int numLevels = 9; int expectLevel = 0; assertEquals(expectLevel, WifiManager.calculateSignalLevel(MIN_RSSI, numLevels)); diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java index 53150c9650..c1fc4ba712 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java @@ -63,6 +63,10 @@ public class WifiManager_WifiLockTest extends AndroidTestCase { ) }) public void testWifiLock() { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } WifiManager wm = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); WifiLock wl = wm.createWifiLock(WIFI_TAG); From 4231515a1b116eeddd1269b24459d0f56fe4be07 Mon Sep 17 00:00:00 2001 From: Chia-chi Yeh Date: Tue, 28 Feb 2012 14:05:12 -0800 Subject: [PATCH 0080/1109] Free net.cts from cts.stub. Explicitly include CtsTestServer in Android.mk to eliminate the dependency to cts.stub. This allows net.cts to instrument itself, and it also allows network-specific JNI code to be added in the same package. Change-Id: I624f87e0112619c5b97f2c3589933f666665fa8e --- tests/cts/net/Android.mk | 6 +++--- tests/cts/net/AndroidManifest.xml | 12 ++++++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index 1fd9ba0c40..bf518907f6 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -23,12 +23,12 @@ LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) LOCAL_JAVA_LIBRARIES := android.test.runner -LOCAL_SRC_FILES := $(call all-java-files-under, src) +# include CtsTestServer as a temporary hack to free net.cts from cts.stub. +LOCAL_SRC_FILES := $(call all-java-files-under, src) \ + ../../src/android/webkit/cts/CtsTestServer.java LOCAL_PACKAGE_NAME := CtsNetTestCases -LOCAL_INSTRUMENTATION_FOR := CtsTestStubs - # uncomment when dalvik.annotation.Test* are removed or part of SDK #LOCAL_SDK_VERSION := current diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index a1f632effb..4fa05654af 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -18,12 +18,20 @@ + + + + + + + + - From 66efc9c3c0db3390d2ad05a7d103ece4d796d3ab Mon Sep 17 00:00:00 2001 From: Chia-chi Yeh Date: Tue, 28 Feb 2012 17:33:10 -0800 Subject: [PATCH 0081/1109] Add CTS test for android.net.VpnService. Bug: 5910784 Change-Id: Icb3d874d4d0917f739bd2638596f28df2a7d206e --- .../src/android/net/cts/VpnServiceTest.java | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 tests/cts/net/src/android/net/cts/VpnServiceTest.java diff --git a/tests/cts/net/src/android/net/cts/VpnServiceTest.java b/tests/cts/net/src/android/net/cts/VpnServiceTest.java new file mode 100644 index 0000000000..9e35375970 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/VpnServiceTest.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2012 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.content.Intent; +import android.net.VpnService; +import android.os.ParcelFileDescriptor; +import android.test.AndroidTestCase; + +import java.io.File; +import java.net.DatagramSocket; +import java.net.Socket; + +/** + * VpnService API is built with security in mind. However, its security also + * blocks us from writing tests for positive cases. For now we only test for + * negative cases, and we will try to cover the rest in the future. + */ +public class VpnServiceTest extends AndroidTestCase { + + private static final String TAG = VpnServiceTest.class.getSimpleName(); + + private VpnService mVpnService = new VpnService(); + + public void testPrepare() throws Exception { + // Should never return null since we are not prepared. + Intent intent = VpnService.prepare(mContext); + assertNotNull(intent); + + // Should be always resolved by only one activity. + int count = mContext.getPackageManager().queryIntentActivities(intent, 0).size(); + assertEquals(count, 1); + } + + public void testEstablish() throws Exception { + ParcelFileDescriptor descriptor = null; + try { + // Should always return null since we are not prepared. + descriptor = mVpnService.new Builder().addAddress("8.8.8.8", 30).establish(); + assertNull(descriptor); + } finally { + try { + descriptor.close(); + } catch (Exception e) { + // ignore + } + } + } + + public void testProtect_DatagramSocket() throws Exception { + DatagramSocket socket = new DatagramSocket(); + try { + // Should always return false since we are not prepared. + assertFalse(mVpnService.protect(socket)); + } finally { + try { + socket.close(); + } catch (Exception e) { + // ignore + } + } + } + + public void testProtect_Socket() throws Exception { + Socket socket = new Socket(); + try { + // Should always return false since we are not prepared. + assertFalse(mVpnService.protect(socket)); + } finally { + try { + socket.close(); + } catch (Exception e) { + // ignore + } + } + } + + public void testProtect_int() throws Exception { + DatagramSocket socket = new DatagramSocket(); + ParcelFileDescriptor descriptor = ParcelFileDescriptor.fromDatagramSocket(socket); + try { + // Should always return false since we are not prepared. + assertFalse(mVpnService.protect(descriptor.getFd())); + } finally { + try { + descriptor.close(); + } catch (Exception e) { + // ignore + } + try { + socket.close(); + } catch (Exception e) { + // ignore + } + } + } + + public void testTunDevice() throws Exception { + File file = new File("/dev/tun"); + assertTrue(file.exists()); + assertFalse(file.isFile()); + assertFalse(file.isDirectory()); + assertFalse(file.canExecute()); + assertFalse(file.canRead()); + assertFalse(file.canWrite()); + } +} From 248128f2a935c56fbfa03ea9bf8ad67929d6aadd Mon Sep 17 00:00:00 2001 From: Brian Muramatsu Date: Mon, 5 Mar 2012 18:46:33 -0800 Subject: [PATCH 0082/1109] Static Libs for Popular CTS Stub Components com.android.cts.stub is growing very large. Split apart some of the popular components into separate static libraries. This should allow packages to depend on the components they need rather than all of cts.stub. Current code at the moment doesn't have to be changed, because I have CtsTestStubs depending on these new shared libraries. However, change the net package to depend on the ctstestserver static library as a proof of concept rather than including its source directly. Change-Id: I32c54eab3ddfb1d4391d6ffc347fbc9cb2fe97f9 --- tests/cts/net/Android.mk | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index c139d1c5b4..3e48cd21a2 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -24,11 +24,12 @@ LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) LOCAL_JAVA_LIBRARIES := android.test.runner # include CtsTestServer as a temporary hack to free net.cts from cts.stub. -LOCAL_SRC_FILES := $(call all-java-files-under, src) \ - ../../src/android/webkit/cts/CtsTestServer.java +LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := CtsNetTestCases +LOCAL_STATIC_JAVA_LIBRARIES := ctstestserver + # uncomment when dalvik.annotation.Test* are removed or part of SDK #LOCAL_SDK_VERSION := current From 6bda9056effc260aa7bc9cf5980358ea321831cc Mon Sep 17 00:00:00 2001 From: Chia-chi Yeh Date: Fri, 30 Mar 2012 13:35:54 -0700 Subject: [PATCH 0083/1109] Add CTS test for android.net.rtp. Bug: 5975113 Change-Id: I20ec3b172a2d6501048418f4c3da06d1b7144fd3 --- tests/cts/net/AndroidManifest.xml | 1 + .../android/net/rtp/cts/AudioCodecTest.java | 73 ++++++++ .../android/net/rtp/cts/AudioGroupTest.java | 170 ++++++++++++++++++ .../android/net/rtp/cts/AudioStreamTest.java | 94 ++++++++++ 4 files changed, 338 insertions(+) create mode 100644 tests/cts/net/src/android/net/rtp/cts/AudioCodecTest.java create mode 100644 tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java create mode 100644 tests/cts/net/src/android/net/rtp/cts/AudioStreamTest.java diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index 4fa05654af..b3556f5bec 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -23,6 +23,7 @@ + diff --git a/tests/cts/net/src/android/net/rtp/cts/AudioCodecTest.java b/tests/cts/net/src/android/net/rtp/cts/AudioCodecTest.java new file mode 100644 index 0000000000..412498c309 --- /dev/null +++ b/tests/cts/net/src/android/net/rtp/cts/AudioCodecTest.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2012 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.rtp.cts; + +import android.net.rtp.AudioCodec; +import android.test.AndroidTestCase; + +public class AudioCodecTest extends AndroidTestCase { + + private void assertEquals(AudioCodec codec, int type, String rtpmap, String fmtp) { + if (type >= 0) { + assertEquals(codec.type, type); + } else { + assertTrue(codec.type >= 96 && codec.type <= 127); + } + assertEquals(codec.rtpmap.compareToIgnoreCase(rtpmap), 0); + assertEquals(codec.fmtp, fmtp); + } + + public void testConstants() throws Exception { + assertEquals(AudioCodec.PCMU, 0, "PCMU/8000", null); + assertEquals(AudioCodec.PCMA, 8, "PCMA/8000", null); + assertEquals(AudioCodec.GSM, 3, "GSM/8000", null); + assertEquals(AudioCodec.GSM_EFR, -1, "GSM-EFR/8000", null); + assertEquals(AudioCodec.AMR, -1, "AMR/8000", null); + + assertFalse(AudioCodec.AMR.type == AudioCodec.GSM_EFR.type); + } + + public void testGetCodec() throws Exception { + // Bad types. + assertNull(AudioCodec.getCodec(128, "PCMU/8000", null)); + assertNull(AudioCodec.getCodec(-1, "PCMU/8000", null)); + assertNull(AudioCodec.getCodec(96, null, null)); + + // Fixed types. + assertEquals(AudioCodec.getCodec(0, null, null), 0, "PCMU/8000", null); + assertEquals(AudioCodec.getCodec(8, null, null), 8, "PCMA/8000", null); + assertEquals(AudioCodec.getCodec(3, null, null), 3, "GSM/8000", null); + + // Dynamic types. + assertEquals(AudioCodec.getCodec(96, "pcmu/8000", null), 96, "PCMU/8000", null); + assertEquals(AudioCodec.getCodec(97, "pcma/8000", null), 97, "PCMA/8000", null); + assertEquals(AudioCodec.getCodec(98, "gsm/8000", null), 98, "GSM/8000", null); + assertEquals(AudioCodec.getCodec(99, "gsm-efr/8000", null), 99, "GSM-EFR/8000", null); + assertEquals(AudioCodec.getCodec(100, "amr/8000", null), 100, "AMR/8000", null); + } + + public void testGetCodecs() throws Exception { + AudioCodec[] codecs = AudioCodec.getCodecs(); + assertTrue(codecs.length >= 5); + + // The types of the codecs should be different. + boolean[] types = new boolean[128]; + for (AudioCodec codec : codecs) { + assertFalse(types[codec.type]); + types[codec.type] = true; + } + } +} diff --git a/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java b/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java new file mode 100644 index 0000000000..f06d7e9b89 --- /dev/null +++ b/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2012 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.rtp.cts; + +import android.content.Context; +import android.media.AudioManager; +import android.net.rtp.AudioCodec; +import android.net.rtp.AudioGroup; +import android.net.rtp.AudioStream; +import android.net.rtp.RtpStream; +import android.test.AndroidTestCase; +import android.util.Log; + +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; + +public class AudioGroupTest extends AndroidTestCase { + + private static final String TAG = AudioGroupTest.class.getSimpleName(); + + private AudioManager mAudioManager; + + private AudioStream mStreamA; + private DatagramSocket mSocketA; + private AudioStream mStreamB; + private DatagramSocket mSocketB; + private AudioGroup mGroup; + + @Override + public void setUp() throws Exception { + mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); + mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); + + InetAddress local = InetAddress.getByName("::1"); + + mStreamA = new AudioStream(local); + mStreamA.setMode(RtpStream.MODE_NORMAL); + mStreamA.setCodec(AudioCodec.PCMU); + mSocketA = new DatagramSocket(); + mSocketA.connect(mStreamA.getLocalAddress(), mStreamA.getLocalPort()); + mStreamA.associate(mSocketA.getLocalAddress(), mSocketA.getLocalPort()); + + mStreamB = new AudioStream(local); + mStreamB.setMode(RtpStream.MODE_NORMAL); + mStreamB.setCodec(AudioCodec.PCMU); + mSocketB = new DatagramSocket(); + mSocketB.connect(mStreamB.getLocalAddress(), mStreamB.getLocalPort()); + mStreamB.associate(mSocketB.getLocalAddress(), mSocketB.getLocalPort()); + + mGroup = new AudioGroup(); + } + + @Override + public void tearDown() throws Exception { + mGroup.clear(); + mStreamA.release(); + mSocketA.close(); + mStreamB.release(); + mSocketB.close(); + mAudioManager.setMode(AudioManager.MODE_NORMAL); + } + + private void assertPacket(DatagramSocket socket, int length) throws Exception { + DatagramPacket packet = new DatagramPacket(new byte[length + 1], length + 1); + socket.setSoTimeout(3000); + socket.receive(packet); + assertEquals(packet.getLength(), length); + } + + private void drain(DatagramSocket socket) throws Exception { + DatagramPacket packet = new DatagramPacket(new byte[1], 1); + socket.setSoTimeout(1); + try { + // Drain the socket by retrieving all the packets queued on it. + // A SocketTimeoutException will be thrown when it becomes empty. + while (true) { + socket.receive(packet); + } + } catch (Exception e) { + // ignore. + } + } + + public void testTraffic() throws Exception { + mStreamA.join(mGroup); + assertPacket(mSocketA, 12 + 160); + + mStreamB.join(mGroup); + assertPacket(mSocketB, 12 + 160); + + mStreamA.join(null); + drain(mSocketA); + + drain(mSocketB); + assertPacket(mSocketB, 12 + 160); + + mStreamA.join(mGroup); + assertPacket(mSocketA, 12 + 160); + } + + public void testSetMode() throws Exception { + mGroup.setMode(AudioGroup.MODE_NORMAL); + assertEquals(mGroup.getMode(), AudioGroup.MODE_NORMAL); + + mGroup.setMode(AudioGroup.MODE_MUTED); + assertEquals(mGroup.getMode(), AudioGroup.MODE_MUTED); + + mStreamA.join(mGroup); + mStreamB.join(mGroup); + + mGroup.setMode(AudioGroup.MODE_NORMAL); + assertEquals(mGroup.getMode(), AudioGroup.MODE_NORMAL); + + mGroup.setMode(AudioGroup.MODE_MUTED); + assertEquals(mGroup.getMode(), AudioGroup.MODE_MUTED); + } + + public void testAdd() throws Exception { + mStreamA.join(mGroup); + assertEquals(mGroup.getStreams().length, 1); + + mStreamB.join(mGroup); + assertEquals(mGroup.getStreams().length, 2); + + mStreamA.join(mGroup); + assertEquals(mGroup.getStreams().length, 2); + } + + public void testRemove() throws Exception { + mStreamA.join(mGroup); + assertEquals(mGroup.getStreams().length, 1); + + mStreamA.join(null); + assertEquals(mGroup.getStreams().length, 0); + + mStreamA.join(mGroup); + assertEquals(mGroup.getStreams().length, 1); + } + + public void testClear() throws Exception { + mStreamA.join(mGroup); + mStreamB.join(mGroup); + mGroup.clear(); + + assertEquals(mGroup.getStreams().length, 0); + assertFalse(mStreamA.isBusy()); + assertFalse(mStreamB.isBusy()); + } + + public void testDoubleClear() throws Exception { + mStreamA.join(mGroup); + mStreamB.join(mGroup); + mGroup.clear(); + mGroup.clear(); + } +} diff --git a/tests/cts/net/src/android/net/rtp/cts/AudioStreamTest.java b/tests/cts/net/src/android/net/rtp/cts/AudioStreamTest.java new file mode 100644 index 0000000000..323b02215d --- /dev/null +++ b/tests/cts/net/src/android/net/rtp/cts/AudioStreamTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2012 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.rtp.cts; + +import android.net.rtp.AudioCodec; +import android.net.rtp.AudioStream; +import android.test.AndroidTestCase; + +import java.net.InetAddress; + +public class AudioStreamTest extends AndroidTestCase { + + private void testRtpStream(InetAddress address) throws Exception { + AudioStream stream = new AudioStream(address); + assertEquals(stream.getLocalAddress(), address); + assertEquals(stream.getLocalPort() % 2, 0); + + assertNull(stream.getRemoteAddress()); + assertEquals(stream.getRemotePort(), -1); + stream.associate(address, 1000); + assertEquals(stream.getRemoteAddress(), address); + assertEquals(stream.getRemotePort(), 1000); + + assertFalse(stream.isBusy()); + stream.release(); + } + + public void testV4Stream() throws Exception { + testRtpStream(InetAddress.getByName("127.0.0.1")); + } + + public void testV6Stream() throws Exception { + testRtpStream(InetAddress.getByName("::1")); + } + + public void testSetDtmfType() throws Exception { + AudioStream stream = new AudioStream(InetAddress.getByName("::1")); + + assertEquals(stream.getDtmfType(), -1); + try { + stream.setDtmfType(0); + fail("Expecting IllegalArgumentException"); + } catch (IllegalArgumentException e) { + // ignore + } + stream.setDtmfType(96); + assertEquals(stream.getDtmfType(), 96); + + stream.setCodec(AudioCodec.getCodec(97, "PCMU/8000", null)); + try { + stream.setDtmfType(97); + fail("Expecting IllegalArgumentException"); + } catch (IllegalArgumentException e) { + // ignore + } + stream.release(); + } + + public void testSetCodec() throws Exception { + AudioStream stream = new AudioStream(InetAddress.getByName("::1")); + + assertNull(stream.getCodec()); + stream.setCodec(AudioCodec.getCodec(97, "PCMU/8000", null)); + assertNotNull(stream.getCodec()); + + stream.setDtmfType(96); + try { + stream.setCodec(AudioCodec.getCodec(96, "PCMU/8000", null)); + fail("Expecting IllegalArgumentException"); + } catch (IllegalArgumentException e) { + // ignore + } + stream.release(); + } + + public void testDoubleRelease() throws Exception { + AudioStream stream = new AudioStream(InetAddress.getByName("::1")); + stream.release(); + stream.release(); + } +} From 7dde0466ab446985a579d3f8254b761339793850 Mon Sep 17 00:00:00 2001 From: Brian Muramatsu Date: Wed, 4 Apr 2012 18:22:15 -0700 Subject: [PATCH 0084/1109] Fix NetworkInfo_DetailedStateTest Bug 6292661 Test is missing a new enum value. Change-Id: I0f5983575eb7aeb87b212e44c5476025a4baf609 --- .../net/src/android/net/cts/NetworkInfo_DetailedStateTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java index 3eeb1c5c84..b8d0ea4e60 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java @@ -37,7 +37,7 @@ public class NetworkInfo_DetailedStateTest extends AndroidTestCase { public void testValues() { DetailedState[] expected = DetailedState.values(); - assertEquals(11, expected.length); + assertEquals(12, expected.length); assertEquals(DetailedState.IDLE, expected[0]); assertEquals(DetailedState.SCANNING, expected[1]); assertEquals(DetailedState.CONNECTING, expected[2]); @@ -49,6 +49,7 @@ public class NetworkInfo_DetailedStateTest extends AndroidTestCase { assertEquals(DetailedState.DISCONNECTED, expected[8]); assertEquals(DetailedState.FAILED, expected[9]); assertEquals(DetailedState.BLOCKED, expected[10]); + assertEquals(DetailedState.VERIFYING_POOR_LINK, expected[11]); } } From fb1b2d0923e40929a476b7eb546a3dd8ebb6b4ea Mon Sep 17 00:00:00 2001 From: Jesse Wilson Date: Thu, 10 May 2012 14:31:59 -0400 Subject: [PATCH 0085/1109] Track rename of Uri.normalize() to Uri.normalizeScheme(). Change-Id: I0b6c65e033bfb82503f30e5c9e55903278c4a788 --- tests/cts/net/src/android/net/cts/UriTest.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/UriTest.java b/tests/cts/net/src/android/net/cts/UriTest.java index 3bf8049b0a..ab337d0183 100644 --- a/tests/cts/net/src/android/net/cts/UriTest.java +++ b/tests/cts/net/src/android/net/cts/UriTest.java @@ -406,11 +406,12 @@ public class UriTest extends AndroidTestCase { assertEquals(uriString, uri.toString()); } - public void testNormalize() { - assertEquals(Uri.parse(""), Uri.parse("").normalize()); + public void testNormalizeScheme() { + assertEquals(Uri.parse(""), Uri.parse("").normalizeScheme()); assertEquals(Uri.parse("http://www.android.com"), - Uri.parse("http://www.android.com").normalize()); + Uri.parse("http://www.android.com").normalizeScheme()); assertEquals(Uri.parse("http://USER@WWW.ANDROID.COM:100/ABOUT?foo=blah@bar=bleh#c"), - Uri.parse("HTTP://USER@WWW.ANDROID.COM:100/ABOUT?foo=blah@bar=bleh#c").normalize()); + Uri.parse("HTTP://USER@WWW.ANDROID.COM:100/ABOUT?foo=blah@bar=bleh#c") + .normalizeScheme()); } } From 28ca76b84d2de6eaec2d2c73ab413974ce8c9ab4 Mon Sep 17 00:00:00 2001 From: Brian Muramatsu Date: Fri, 8 Jun 2012 16:45:02 -0700 Subject: [PATCH 0086/1109] Flip condition in ApacheHttpClientTest Make sure to wait first and then check the expected state rather than check the expected state first and then waiting. Bug 6293413 Change-Id: Ibcb1127b935708c51fafdc8624cb3a7eefc01bda --- .../cts/net/src/android/net/http/cts/ApacheHttpClientTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/http/cts/ApacheHttpClientTest.java b/tests/cts/net/src/android/net/http/cts/ApacheHttpClientTest.java index e4846fdec2..7d9189ff33 100644 --- a/tests/cts/net/src/android/net/http/cts/ApacheHttpClientTest.java +++ b/tests/cts/net/src/android/net/http/cts/ApacheHttpClientTest.java @@ -200,7 +200,7 @@ public class ApacheHttpClientTest extends AndroidTestCase { } public boolean waitForStateChange() throws InterruptedException { - return hasExpectedState() || mReceiveLatch.await(30, TimeUnit.SECONDS); + return mReceiveLatch.await(30, TimeUnit.SECONDS) || hasExpectedState(); } private boolean hasExpectedState() { From 562af417ed5cd2f8066b2af0d692f6426d00b7d8 Mon Sep 17 00:00:00 2001 From: bs Date: Fri, 22 Jun 2012 21:36:24 +0900 Subject: [PATCH 0087/1109] Fix CTS case testStartUsingNetworkFeature of ConnectivityManagerTest Check if type of network is supported on the devices. The device supporting TYPE_WIFI returns failureCode(-1). But, not supported device returns wifiOnlyStartFailureCode or wifiOnlyStopFailureCode. Change-Id: I070bb19f6740367c476e78b884c2a36d111ff3ee --- .../src/android/net/cts/ConnectivityManagerTest.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index cd80be2797..470458253c 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -161,9 +161,14 @@ public class ConnectivityManagerTest extends AndroidTestCase { invalidateFeature)); } - // Should return failure(-1) because MMS is not supported on WIFI. - assertEquals(failureCode, mCm.startUsingNetworkFeature(TYPE_WIFI, mmsFeature)); - assertEquals(failureCode, mCm.stopUsingNetworkFeature(TYPE_WIFI, mmsFeature)); + ni = mCm.getNetworkInfo(TYPE_WIFI); + if (ni != null) { + // Should return failure(-1) because MMS is not supported on WIFI. + assertEquals(failureCode, mCm.startUsingNetworkFeature(TYPE_WIFI, + mmsFeature)); + assertEquals(failureCode, mCm.stopUsingNetworkFeature(TYPE_WIFI, + mmsFeature)); + } } @TestTargetNew( From 237e076594b059a8631f3cc4863499ec2f967444 Mon Sep 17 00:00:00 2001 From: Brian Muramatsu Date: Tue, 26 Jun 2012 15:05:08 -0700 Subject: [PATCH 0088/1109] Fix WifiInfoTest flakiness Poll a bit longer waiting for getNetworkId and getWifiState to return the proper values. The bug reports seem to indicate that the WiFi is shutting down properly. Add a new static check method to PollingCheck that I think is simpler than the existing way of creating a new PollingCheck, overriding check, and then making sure to call run. This new variation also allows you to specify a message rather than just "unexpected timeout." Bug 6443337 Change-Id: I9f7c942f6e26b957bb717b58b1ab984acc556bf7 --- tests/cts/net/Android.mk | 2 +- .../android/net/wifi/cts/WifiInfoTest.java | 22 +++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index 3e48cd21a2..5c70ad4bb8 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -28,7 +28,7 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := CtsNetTestCases -LOCAL_STATIC_JAVA_LIBRARIES := ctstestserver +LOCAL_STATIC_JAVA_LIBRARIES := ctstestserver ctsutil # uncomment when dalvik.annotation.Test* are removed or part of SDK #LOCAL_SDK_VERSION := current diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java index df1323b255..16dc57de2b 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java @@ -21,12 +21,15 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.cts.util.PollingCheck; import android.net.wifi.SupplicantState; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.WifiLock; import android.test.AndroidTestCase; +import java.util.concurrent.Callable; + public class WifiInfoTest extends AndroidTestCase { private static class MySync { int expectedState = STATE_NULL; @@ -127,10 +130,21 @@ public class WifiInfoTest extends AndroidTestCase { wifiInfo.getHiddenSSID(); wifiInfo.getMacAddress(); setWifiEnabled(false); - Thread.sleep(DURATION); - wifiInfo = mWifiManager.getConnectionInfo(); - assertEquals(-1, wifiInfo.getNetworkId()); - assertEquals(WifiManager.WIFI_STATE_DISABLED, mWifiManager.getWifiState()); + + PollingCheck.check("getNetworkId not -1", 20000, new Callable() { + @Override + public Boolean call() throws Exception { + WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); + return wifiInfo.getNetworkId() == -1; + } + }); + + PollingCheck.check("getWifiState not disabled", 20000, new Callable() { + @Override + public Boolean call() throws Exception { + return mWifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLED; + } + }); } } From f7e73fcc352ddb0b94045a9de0e3c6dce8aadf77 Mon Sep 17 00:00:00 2001 From: Irfan Sheriff Date: Tue, 26 Jun 2012 16:54:35 -0700 Subject: [PATCH 0089/1109] Add wifi & p2p Concurrency test Change-Id: I5a35fb097b22b00366b189bad9c44a640a7d5b5a --- .../android/net/wifi/cts/ConcurrencyTest.java | 138 ++++++++++++++++++ .../src/android/net/wifi/cts/WifiFeature.java | 6 +- 2 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java diff --git a/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java b/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java new file mode 100644 index 0000000000..5accd77633 --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2012 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.wifi.cts; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.wifi.WifiManager; +import android.net.wifi.p2p.WifiP2pManager; +import static android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_STATE_DISABLED; +import static android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_STATE_ENABLED; +import android.test.AndroidTestCase; + +public class ConcurrencyTest extends AndroidTestCase { + private class MySync { + int expectedWifiState; + int expectedP2pState; + } + + private WifiManager mWifiManager; + private MySync mMySync = new MySync(); + + private static final String TAG = "WifiInfoTest"; + private static final int TIMEOUT_MSEC = 6000; + private static final int WAIT_MSEC = 60; + private static final int DURATION = 10000; + private IntentFilter mIntentFilter; + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { + synchronized (mMySync) { + mMySync.expectedWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, + WifiManager.WIFI_STATE_DISABLED); + mMySync.notify(); + } + } else if(action.equals(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION)) { + synchronized (mMySync) { + mMySync.expectedP2pState = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, + WifiP2pManager.WIFI_P2P_STATE_DISABLED); + mMySync.notify(); + } + } + } + }; + + @Override + protected void setUp() throws Exception { + super.setUp(); + if (!WifiFeature.isWifiSupported(getContext()) && + !WifiFeature.isP2pSupported(getContext())) { + // skip the test if WiFi && p2p are not supported + return; + } + mIntentFilter = new IntentFilter(); + mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); + mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); + + mContext.registerReceiver(mReceiver, mIntentFilter); + mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); + assertNotNull(mWifiManager); + if (mWifiManager.isWifiEnabled()) { + assertTrue(mWifiManager.setWifiEnabled(false)); + Thread.sleep(DURATION); + } + assertTrue(!mWifiManager.isWifiEnabled()); + mMySync.expectedWifiState = WifiManager.WIFI_STATE_DISABLED; + mMySync.expectedP2pState = WifiP2pManager.WIFI_P2P_STATE_DISABLED; + } + + @Override + protected void tearDown() throws Exception { + if (!WifiFeature.isWifiSupported(getContext()) && + !WifiFeature.isP2pSupported(getContext())) { + // skip the test if WiFi and p2p are not supported + super.tearDown(); + return; + } + mContext.unregisterReceiver(mReceiver); + + if (mWifiManager.isWifiEnabled()) { + assertTrue(mWifiManager.setWifiEnabled(false)); + Thread.sleep(DURATION); + } + super.tearDown(); + } + + private void waitForBroadcasts() { + synchronized (mMySync) { + long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; + while (System.currentTimeMillis() < timeout + && (mMySync.expectedWifiState != WifiManager.WIFI_STATE_ENABLED || + mMySync.expectedP2pState != WifiP2pManager.WIFI_P2P_STATE_ENABLED)) { + try { + mMySync.wait(WAIT_MSEC); + } catch (InterruptedException e) { } + } + } + } + + public void testConcurrency() { + // Cannot support p2p alone + if (!WifiFeature.isWifiSupported(getContext())) { + assertTrue(!WifiFeature.isP2pSupported(getContext())); + return; + } + + if (!WifiFeature.isP2pSupported(getContext())) { + // skip the test if p2p is not supported + return; + } + + // Enable wifi + assertTrue(mWifiManager.setWifiEnabled(true)); + + waitForBroadcasts(); + + assertTrue(mMySync.expectedWifiState == WifiManager.WIFI_STATE_ENABLED); + assertTrue(mMySync.expectedP2pState == WifiP2pManager.WIFI_P2P_STATE_ENABLED); + } + +} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiFeature.java b/tests/cts/net/src/android/net/wifi/cts/WifiFeature.java index d7a83c302f..63fa1dd94c 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiFeature.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiFeature.java @@ -24,5 +24,9 @@ public class WifiFeature { PackageManager packageManager = context.getPackageManager(); return packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI); } -} + static boolean isP2pSupported(Context context) { + PackageManager packageManager = context.getPackageManager(); + return packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT); + } +} From 30199405c3b15a0dc6778e7465499a7d33f7556c Mon Sep 17 00:00:00 2001 From: Keun young Park Date: Thu, 12 Jul 2012 12:56:04 -0700 Subject: [PATCH 0090/1109] change testRunner to CtsTestRunner - unlock keyguard by default Change-Id: I0452a72cfa54edfa79b485894ffd0493a71122ee --- tests/cts/net/Android.mk | 2 +- tests/cts/net/AndroidManifest.xml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index 5c70ad4bb8..b327392956 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -28,7 +28,7 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := CtsNetTestCases -LOCAL_STATIC_JAVA_LIBRARIES := ctstestserver ctsutil +LOCAL_STATIC_JAVA_LIBRARIES := ctstestserver ctsutil ctstestrunner # uncomment when dalvik.annotation.Test* are removed or part of SDK #LOCAL_SDK_VERSION := current diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index b3556f5bec..ade6728a6e 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -22,6 +22,7 @@ + @@ -31,7 +32,7 @@ - From c0e2e5715be659a19a091b37accef72939cc0dfd Mon Sep 17 00:00:00 2001 From: Irfan Sheriff Date: Mon, 23 Jul 2012 09:28:23 -0700 Subject: [PATCH 0091/1109] Fix NPE in CTS test wifiConfigurations returned by getConfiguredNetworks() can be null. It is only incidental that this test passed fine in the past. Bug: 6822950 Change-Id: I570ab6e7fd6cc5eb150914a5d7ca527ccc2f16cd --- .../android/net/wifi/cts/WifiConfigurationTest.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java index 92a55b2250..4480a24a9a 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java @@ -38,10 +38,12 @@ public class WifiConfigurationTest extends AndroidTestCase { return; } List wifiConfigurations = mWifiManager.getConfiguredNetworks(); - for (int i = 0; i < wifiConfigurations.size(); i++) { - WifiConfiguration wifiConfiguration = wifiConfigurations.get(i); - assertNotNull(wifiConfiguration); - assertNotNull(wifiConfiguration.toString()); + if (wifiConfigurations != null) { + for (int i = 0; i < wifiConfigurations.size(); i++) { + WifiConfiguration wifiConfiguration = wifiConfigurations.get(i); + assertNotNull(wifiConfiguration); + assertNotNull(wifiConfiguration.toString()); + } } } } From f16bea1f5914495b82e864a0ab92cf412ec6f9d0 Mon Sep 17 00:00:00 2001 From: Irfan Sheriff Date: Wed, 25 Jul 2012 12:10:40 -0700 Subject: [PATCH 0092/1109] Ignore case on network info name Bug: 6309231 Change-Id: I41244e25ccbf0d896edebf886c7f67ab1ded0a04 --- tests/cts/net/src/android/net/cts/NetworkInfoTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java index e53614b99a..4a7b4e7e82 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java @@ -53,7 +53,7 @@ public class NetworkInfoTest extends AndroidTestCase { } private void assertNetworkInfo(NetworkInfo netInfo, String expectedTypeName) { - assertEquals(expectedTypeName, netInfo.getTypeName()); + assertEquals(expectedTypeName.compareToIgnoreCase(netInfo.getTypeName()), 0); if(netInfo.isConnectedOrConnecting()) { assertTrue(netInfo.isAvailable()); if (State.CONNECTED == netInfo.getState()) { From e9adc27111e8f78c0281cddfd31708048326473e Mon Sep 17 00:00:00 2001 From: Irfan Sheriff Date: Mon, 13 Aug 2012 12:19:55 -0700 Subject: [PATCH 0093/1109] CTS for timestamp in ScanResult Bug: 2961159 Change-Id: I8f1fd270a71173e2bd43b590914b7315232e4fba --- .../android/net/wifi/cts/ScanResultTest.java | 74 +++++++++++++++++-- 1 file changed, 66 insertions(+), 8 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java index 26cfff83fd..c9b82eecc7 100644 --- a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java @@ -26,6 +26,7 @@ import android.net.wifi.ScanResult; import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.WifiLock; import android.test.AndroidTestCase; +import android.util.Log; public class ScanResultTest extends AndroidTestCase { private static class MySync { @@ -39,11 +40,14 @@ public class ScanResultTest extends AndroidTestCase { private static final int STATE_NULL = 0; private static final int STATE_WIFI_CHANGING = 1; private static final int STATE_WIFI_CHANGED = 2; + private static final int STATE_START_SCAN = 3; + private static final int STATE_SCAN_RESULTS_AVAILABLE = 4; private static final String TAG = "WifiInfoTest"; private static final int TIMEOUT_MSEC = 6000; private static final int WAIT_MSEC = 60; - private static final int DURATION = 10000; + private static final int ENABLE_WAIT_MSEC = 10000; + private static final int SCAN_WAIT_MSEC = 10000; private IntentFilter mIntentFilter; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override @@ -54,6 +58,11 @@ public class ScanResultTest extends AndroidTestCase { mMySync.expectedState = STATE_WIFI_CHANGED; mMySync.notify(); } + } else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { + synchronized (mMySync) { + mMySync.expectedState = STATE_SCAN_RESULTS_AVAILABLE; + mMySync.notify(); + } } } }; @@ -83,7 +92,7 @@ public class ScanResultTest extends AndroidTestCase { mWifiLock.acquire(); if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true); - Thread.sleep(DURATION); + Thread.sleep(ENABLE_WAIT_MSEC); assertTrue(mWifiManager.isWifiEnabled()); mMySync.expectedState = STATE_NULL; } @@ -99,7 +108,7 @@ public class ScanResultTest extends AndroidTestCase { mContext.unregisterReceiver(mReceiver); if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true); - Thread.sleep(DURATION); + Thread.sleep(ENABLE_WAIT_MSEC); super.tearDown(); } @@ -107,11 +116,15 @@ public class ScanResultTest extends AndroidTestCase { synchronized (mMySync) { mMySync.expectedState = STATE_WIFI_CHANGING; assertTrue(mWifiManager.setWifiEnabled(enable)); - long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; - while (System.currentTimeMillis() < timeout - && mMySync.expectedState == STATE_WIFI_CHANGING) - mMySync.wait(WAIT_MSEC); - } + waitForBroadcast(TIMEOUT_MSEC, STATE_WIFI_CHANGED); + } + } + + private void waitForBroadcast(long timeout, int expectedState) throws Exception { + long waitTime = System.currentTimeMillis() + timeout; + while (System.currentTimeMillis() < waitTime + && mMySync.expectedState != expectedState) + mMySync.wait(WAIT_MSEC); } public void testScanResultProperties() { @@ -127,4 +140,49 @@ public class ScanResultTest extends AndroidTestCase { } } + private void scanAndWait() throws Exception { + synchronized (mMySync) { + mMySync.expectedState = STATE_START_SCAN; + mWifiManager.startScan(); + waitForBroadcast(SCAN_WAIT_MSEC, STATE_SCAN_RESULTS_AVAILABLE); + } + } + + public void testScanResultTimeStamp() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + + long timestamp = 0; + String BSSID = null; + + /* Multiple scans to ensure bssid is updated */ + scanAndWait(); + scanAndWait(); + scanAndWait(); + + List scanResults = mWifiManager.getScanResults(); + for (ScanResult result : scanResults) { + BSSID = result.BSSID; + timestamp = result.timestamp; + assertTrue(timestamp != 0); + break; + } + + scanAndWait(); + scanAndWait(); + scanAndWait(); + + scanResults = mWifiManager.getScanResults(); + for (ScanResult result : scanResults) { + if (result.BSSID.equals(BSSID)) { + long timeDiff = (result.timestamp - timestamp) / 1000; + assertTrue (timeDiff > 0); + assertTrue (timeDiff < 6 * SCAN_WAIT_MSEC); + } + } + + } + } From 72010dbfcf461bdcd116d22acbfec362b6583215 Mon Sep 17 00:00:00 2001 From: Iliyan Malchev Date: Tue, 14 Aug 2012 12:24:25 -0700 Subject: [PATCH 0094/1109] Revert "CTS for timestamp in ScanResult" This accompanies: https://googleplex-android-review.googlesource.com/217002 This reverts commit e9adc27111e8f78c0281cddfd31708048326473e Change-Id: Ib37b72c59aad34fe9fd4461979c5f51af1218e37 --- .../android/net/wifi/cts/ScanResultTest.java | 74 ++----------------- 1 file changed, 8 insertions(+), 66 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java index c9b82eecc7..26cfff83fd 100644 --- a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java @@ -26,7 +26,6 @@ import android.net.wifi.ScanResult; import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.WifiLock; import android.test.AndroidTestCase; -import android.util.Log; public class ScanResultTest extends AndroidTestCase { private static class MySync { @@ -40,14 +39,11 @@ public class ScanResultTest extends AndroidTestCase { private static final int STATE_NULL = 0; private static final int STATE_WIFI_CHANGING = 1; private static final int STATE_WIFI_CHANGED = 2; - private static final int STATE_START_SCAN = 3; - private static final int STATE_SCAN_RESULTS_AVAILABLE = 4; private static final String TAG = "WifiInfoTest"; private static final int TIMEOUT_MSEC = 6000; private static final int WAIT_MSEC = 60; - private static final int ENABLE_WAIT_MSEC = 10000; - private static final int SCAN_WAIT_MSEC = 10000; + private static final int DURATION = 10000; private IntentFilter mIntentFilter; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override @@ -58,11 +54,6 @@ public class ScanResultTest extends AndroidTestCase { mMySync.expectedState = STATE_WIFI_CHANGED; mMySync.notify(); } - } else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { - synchronized (mMySync) { - mMySync.expectedState = STATE_SCAN_RESULTS_AVAILABLE; - mMySync.notify(); - } } } }; @@ -92,7 +83,7 @@ public class ScanResultTest extends AndroidTestCase { mWifiLock.acquire(); if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true); - Thread.sleep(ENABLE_WAIT_MSEC); + Thread.sleep(DURATION); assertTrue(mWifiManager.isWifiEnabled()); mMySync.expectedState = STATE_NULL; } @@ -108,7 +99,7 @@ public class ScanResultTest extends AndroidTestCase { mContext.unregisterReceiver(mReceiver); if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true); - Thread.sleep(ENABLE_WAIT_MSEC); + Thread.sleep(DURATION); super.tearDown(); } @@ -116,15 +107,11 @@ public class ScanResultTest extends AndroidTestCase { synchronized (mMySync) { mMySync.expectedState = STATE_WIFI_CHANGING; assertTrue(mWifiManager.setWifiEnabled(enable)); - waitForBroadcast(TIMEOUT_MSEC, STATE_WIFI_CHANGED); - } - } - - private void waitForBroadcast(long timeout, int expectedState) throws Exception { - long waitTime = System.currentTimeMillis() + timeout; - while (System.currentTimeMillis() < waitTime - && mMySync.expectedState != expectedState) - mMySync.wait(WAIT_MSEC); + long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; + while (System.currentTimeMillis() < timeout + && mMySync.expectedState == STATE_WIFI_CHANGING) + mMySync.wait(WAIT_MSEC); + } } public void testScanResultProperties() { @@ -140,49 +127,4 @@ public class ScanResultTest extends AndroidTestCase { } } - private void scanAndWait() throws Exception { - synchronized (mMySync) { - mMySync.expectedState = STATE_START_SCAN; - mWifiManager.startScan(); - waitForBroadcast(SCAN_WAIT_MSEC, STATE_SCAN_RESULTS_AVAILABLE); - } - } - - public void testScanResultTimeStamp() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - - long timestamp = 0; - String BSSID = null; - - /* Multiple scans to ensure bssid is updated */ - scanAndWait(); - scanAndWait(); - scanAndWait(); - - List scanResults = mWifiManager.getScanResults(); - for (ScanResult result : scanResults) { - BSSID = result.BSSID; - timestamp = result.timestamp; - assertTrue(timestamp != 0); - break; - } - - scanAndWait(); - scanAndWait(); - scanAndWait(); - - scanResults = mWifiManager.getScanResults(); - for (ScanResult result : scanResults) { - if (result.BSSID.equals(BSSID)) { - long timeDiff = (result.timestamp - timestamp) / 1000; - assertTrue (timeDiff > 0); - assertTrue (timeDiff < 6 * SCAN_WAIT_MSEC); - } - } - - } - } From 9420b3fe53c4e4e69488c8851b06932e90af6570 Mon Sep 17 00:00:00 2001 From: Iliyan Malchev Date: Tue, 14 Aug 2012 12:24:25 -0700 Subject: [PATCH 0095/1109] Revert "CTS for timestamp in ScanResult" This accompanies: https://googleplex-android-review.googlesource.com/217002 This reverts commit e9adc27111e8f78c0281cddfd31708048326473e Change-Id: Ib37b72c59aad34fe9fd4461979c5f51af1218e37 --- .../android/net/wifi/cts/ScanResultTest.java | 74 ++----------------- 1 file changed, 8 insertions(+), 66 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java index c9b82eecc7..26cfff83fd 100644 --- a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java @@ -26,7 +26,6 @@ import android.net.wifi.ScanResult; import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.WifiLock; import android.test.AndroidTestCase; -import android.util.Log; public class ScanResultTest extends AndroidTestCase { private static class MySync { @@ -40,14 +39,11 @@ public class ScanResultTest extends AndroidTestCase { private static final int STATE_NULL = 0; private static final int STATE_WIFI_CHANGING = 1; private static final int STATE_WIFI_CHANGED = 2; - private static final int STATE_START_SCAN = 3; - private static final int STATE_SCAN_RESULTS_AVAILABLE = 4; private static final String TAG = "WifiInfoTest"; private static final int TIMEOUT_MSEC = 6000; private static final int WAIT_MSEC = 60; - private static final int ENABLE_WAIT_MSEC = 10000; - private static final int SCAN_WAIT_MSEC = 10000; + private static final int DURATION = 10000; private IntentFilter mIntentFilter; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override @@ -58,11 +54,6 @@ public class ScanResultTest extends AndroidTestCase { mMySync.expectedState = STATE_WIFI_CHANGED; mMySync.notify(); } - } else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { - synchronized (mMySync) { - mMySync.expectedState = STATE_SCAN_RESULTS_AVAILABLE; - mMySync.notify(); - } } } }; @@ -92,7 +83,7 @@ public class ScanResultTest extends AndroidTestCase { mWifiLock.acquire(); if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true); - Thread.sleep(ENABLE_WAIT_MSEC); + Thread.sleep(DURATION); assertTrue(mWifiManager.isWifiEnabled()); mMySync.expectedState = STATE_NULL; } @@ -108,7 +99,7 @@ public class ScanResultTest extends AndroidTestCase { mContext.unregisterReceiver(mReceiver); if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true); - Thread.sleep(ENABLE_WAIT_MSEC); + Thread.sleep(DURATION); super.tearDown(); } @@ -116,15 +107,11 @@ public class ScanResultTest extends AndroidTestCase { synchronized (mMySync) { mMySync.expectedState = STATE_WIFI_CHANGING; assertTrue(mWifiManager.setWifiEnabled(enable)); - waitForBroadcast(TIMEOUT_MSEC, STATE_WIFI_CHANGED); - } - } - - private void waitForBroadcast(long timeout, int expectedState) throws Exception { - long waitTime = System.currentTimeMillis() + timeout; - while (System.currentTimeMillis() < waitTime - && mMySync.expectedState != expectedState) - mMySync.wait(WAIT_MSEC); + long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; + while (System.currentTimeMillis() < timeout + && mMySync.expectedState == STATE_WIFI_CHANGING) + mMySync.wait(WAIT_MSEC); + } } public void testScanResultProperties() { @@ -140,49 +127,4 @@ public class ScanResultTest extends AndroidTestCase { } } - private void scanAndWait() throws Exception { - synchronized (mMySync) { - mMySync.expectedState = STATE_START_SCAN; - mWifiManager.startScan(); - waitForBroadcast(SCAN_WAIT_MSEC, STATE_SCAN_RESULTS_AVAILABLE); - } - } - - public void testScanResultTimeStamp() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - - long timestamp = 0; - String BSSID = null; - - /* Multiple scans to ensure bssid is updated */ - scanAndWait(); - scanAndWait(); - scanAndWait(); - - List scanResults = mWifiManager.getScanResults(); - for (ScanResult result : scanResults) { - BSSID = result.BSSID; - timestamp = result.timestamp; - assertTrue(timestamp != 0); - break; - } - - scanAndWait(); - scanAndWait(); - scanAndWait(); - - scanResults = mWifiManager.getScanResults(); - for (ScanResult result : scanResults) { - if (result.BSSID.equals(BSSID)) { - long timeDiff = (result.timestamp - timestamp) / 1000; - assertTrue (timeDiff > 0); - assertTrue (timeDiff < 6 * SCAN_WAIT_MSEC); - } - } - - } - } From 72465772e01ba5d05e8f9af138e9f303e5bb2865 Mon Sep 17 00:00:00 2001 From: Yuhao Zheng Date: Tue, 14 Aug 2012 14:24:35 -0700 Subject: [PATCH 0096/1109] CTS test for WiFi watchdog. The new WiFi watchdog requires kernel/driver to export some packet loss counters. This CTS tests whether those counters are correctly exported. Change-Id: Ic764eff64ff2ef354b46f17e46eb74b14f191e4c --- .../android/net/wifi/cts/WifiManagerTest.java | 88 ++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 5fc23e7b5e..a64477d100 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -21,17 +21,22 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.net.NetworkInfo; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiManager; import android.net.wifi.WifiConfiguration.Status; +import android.net.wifi.WifiManager; +import android.net.wifi.WifiManager.TxPacketCountListener; import android.net.wifi.WifiManager.WifiLock; import android.test.AndroidTestCase; import android.util.Log; +import java.net.HttpURLConnection; +import java.net.URL; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; public class WifiManagerTest extends AndroidTestCase { private static class MySync { @@ -42,6 +47,7 @@ public class WifiManagerTest extends AndroidTestCase { private WifiLock mWifiLock; private static MySync mMySync; private List mScanResult = null; + private NetworkInfo mNetworkInfo; // Please refer to WifiManager private static final int MIN_RSSI = -100; @@ -78,6 +84,13 @@ public class WifiManagerTest extends AndroidTestCase { mMySync.expectedState = STATE_WIFI_CHANGED; mMySync.notify(); } + } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { + synchronized (mMySync) { + mNetworkInfo = + (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); + if (mNetworkInfo.getState() == NetworkInfo.State.CONNECTED) + mMySync.notify(); + } } } }; @@ -148,6 +161,18 @@ public class WifiManagerTest extends AndroidTestCase { } } + private void connectWifi() throws Exception { + synchronized (mMySync) { + if (mNetworkInfo.getState() == NetworkInfo.State.CONNECTED) return; + assertTrue(mWifiManager.reconnect()); + long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; + while (System.currentTimeMillis() < timeout + && mNetworkInfo.getState() != NetworkInfo.State.CONNECTED) + mMySync.wait(WAIT_MSEC); + assertTrue(mNetworkInfo.getState() == NetworkInfo.State.CONNECTED); + } + } + private boolean existSSID(String ssid) { for (final WifiConfiguration w : mWifiManager.getConfiguredNetworks()) { if (w.SSID.equals(ssid)) @@ -339,4 +364,65 @@ public class WifiManagerTest extends AndroidTestCase { rssiB = 4; assertTrue(WifiManager.compareSignalLevel(rssiA, rssiB) > 0); } + + private int getTxPacketCount() throws Exception { + final AtomicInteger ret = new AtomicInteger(-1); + + mWifiManager.getTxPacketCount(new TxPacketCountListener() { + @Override + public void onSuccess(int count) { + ret.set(count); + } + @Override + public void onFailure(int reason) { + ret.set(0); + } + }); + + long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; + while (ret.get() < 0 && System.currentTimeMillis() < timeout) + Thread.sleep(WAIT_MSEC); + assertTrue(ret.get() >= 0); + return ret.get(); + } + + /** + * The new WiFi watchdog requires kernel/driver to export some packet loss + * counters. This CTS tests whether those counters are correctly exported. + * To pass this CTS test, a connected WiFi link is required. + */ + public void testWifiWatchdog() throws Exception { + // Make sure WiFi is enabled + if (!mWifiManager.isWifiEnabled()) { + setWifiEnabled(true); + Thread.sleep(DURATION); + } + assertTrue(mWifiManager.isWifiEnabled()); + + // Wait for a WiFi connection + connectWifi(); + + // Read TX packet counter + int txcount1 = getTxPacketCount(); + + // Do some network operations + HttpURLConnection connection = null; + try { + URL url = new URL("http://www.google.com/"); + connection = (HttpURLConnection) url.openConnection(); + connection.setInstanceFollowRedirects(false); + connection.setConnectTimeout(TIMEOUT_MSEC); + connection.setReadTimeout(TIMEOUT_MSEC); + connection.setUseCaches(false); + connection.getInputStream(); + } catch (Exception e) { + // ignore + } finally { + if (connection != null) connection.disconnect(); + } + + // Read TX packet counter again and make sure it increases + int txcount2 = getTxPacketCount(); + assertTrue(txcount2 > txcount1); + } } From f1537c2ba42ca2a073e3eb9bca8502485bd38655 Mon Sep 17 00:00:00 2001 From: Iliyan Malchev Date: Mon, 20 Aug 2012 13:21:49 -0700 Subject: [PATCH 0097/1109] Revert "Revert "CTS for timestamp in ScanResult"" With b/6979211 fixed, we can reinstate timestamps. This reverts commit 72010dbfcf461bdcd116d22acbfec362b6583215 Change-Id: I1066567c728b233ad1d6c6af912c32ef099580e6 --- .../android/net/wifi/cts/ScanResultTest.java | 74 +++++++++++++++++-- 1 file changed, 66 insertions(+), 8 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java index 26cfff83fd..c9b82eecc7 100644 --- a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java @@ -26,6 +26,7 @@ import android.net.wifi.ScanResult; import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.WifiLock; import android.test.AndroidTestCase; +import android.util.Log; public class ScanResultTest extends AndroidTestCase { private static class MySync { @@ -39,11 +40,14 @@ public class ScanResultTest extends AndroidTestCase { private static final int STATE_NULL = 0; private static final int STATE_WIFI_CHANGING = 1; private static final int STATE_WIFI_CHANGED = 2; + private static final int STATE_START_SCAN = 3; + private static final int STATE_SCAN_RESULTS_AVAILABLE = 4; private static final String TAG = "WifiInfoTest"; private static final int TIMEOUT_MSEC = 6000; private static final int WAIT_MSEC = 60; - private static final int DURATION = 10000; + private static final int ENABLE_WAIT_MSEC = 10000; + private static final int SCAN_WAIT_MSEC = 10000; private IntentFilter mIntentFilter; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override @@ -54,6 +58,11 @@ public class ScanResultTest extends AndroidTestCase { mMySync.expectedState = STATE_WIFI_CHANGED; mMySync.notify(); } + } else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { + synchronized (mMySync) { + mMySync.expectedState = STATE_SCAN_RESULTS_AVAILABLE; + mMySync.notify(); + } } } }; @@ -83,7 +92,7 @@ public class ScanResultTest extends AndroidTestCase { mWifiLock.acquire(); if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true); - Thread.sleep(DURATION); + Thread.sleep(ENABLE_WAIT_MSEC); assertTrue(mWifiManager.isWifiEnabled()); mMySync.expectedState = STATE_NULL; } @@ -99,7 +108,7 @@ public class ScanResultTest extends AndroidTestCase { mContext.unregisterReceiver(mReceiver); if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true); - Thread.sleep(DURATION); + Thread.sleep(ENABLE_WAIT_MSEC); super.tearDown(); } @@ -107,11 +116,15 @@ public class ScanResultTest extends AndroidTestCase { synchronized (mMySync) { mMySync.expectedState = STATE_WIFI_CHANGING; assertTrue(mWifiManager.setWifiEnabled(enable)); - long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; - while (System.currentTimeMillis() < timeout - && mMySync.expectedState == STATE_WIFI_CHANGING) - mMySync.wait(WAIT_MSEC); - } + waitForBroadcast(TIMEOUT_MSEC, STATE_WIFI_CHANGED); + } + } + + private void waitForBroadcast(long timeout, int expectedState) throws Exception { + long waitTime = System.currentTimeMillis() + timeout; + while (System.currentTimeMillis() < waitTime + && mMySync.expectedState != expectedState) + mMySync.wait(WAIT_MSEC); } public void testScanResultProperties() { @@ -127,4 +140,49 @@ public class ScanResultTest extends AndroidTestCase { } } + private void scanAndWait() throws Exception { + synchronized (mMySync) { + mMySync.expectedState = STATE_START_SCAN; + mWifiManager.startScan(); + waitForBroadcast(SCAN_WAIT_MSEC, STATE_SCAN_RESULTS_AVAILABLE); + } + } + + public void testScanResultTimeStamp() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + + long timestamp = 0; + String BSSID = null; + + /* Multiple scans to ensure bssid is updated */ + scanAndWait(); + scanAndWait(); + scanAndWait(); + + List scanResults = mWifiManager.getScanResults(); + for (ScanResult result : scanResults) { + BSSID = result.BSSID; + timestamp = result.timestamp; + assertTrue(timestamp != 0); + break; + } + + scanAndWait(); + scanAndWait(); + scanAndWait(); + + scanResults = mWifiManager.getScanResults(); + for (ScanResult result : scanResults) { + if (result.BSSID.equals(BSSID)) { + long timeDiff = (result.timestamp - timestamp) / 1000; + assertTrue (timeDiff > 0); + assertTrue (timeDiff < 6 * SCAN_WAIT_MSEC); + } + } + + } + } From 3de9654925a3c916fbcd814dd64f9872a0d03619 Mon Sep 17 00:00:00 2001 From: Robert Greenwalt Date: Sun, 16 Sep 2012 17:11:04 -0700 Subject: [PATCH 0098/1109] Fix NetworkInfo CTS test. bug:7074876 Change-Id: I29cf9086fda62dda8078b42a1632f139ec65ee52 --- .../net/src/android/net/cts/NetworkInfo_DetailedStateTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java index b8d0ea4e60..590ce89579 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java @@ -37,7 +37,7 @@ public class NetworkInfo_DetailedStateTest extends AndroidTestCase { public void testValues() { DetailedState[] expected = DetailedState.values(); - assertEquals(12, expected.length); + assertEquals(13, expected.length); assertEquals(DetailedState.IDLE, expected[0]); assertEquals(DetailedState.SCANNING, expected[1]); assertEquals(DetailedState.CONNECTING, expected[2]); @@ -50,6 +50,7 @@ public class NetworkInfo_DetailedStateTest extends AndroidTestCase { assertEquals(DetailedState.FAILED, expected[9]); assertEquals(DetailedState.BLOCKED, expected[10]); assertEquals(DetailedState.VERIFYING_POOR_LINK, expected[11]); + assertEquals(DetailedState.CAPTIVE_PORTAL_CHECK, expected[12]); } } From a0a19ea8aa8ed74501a0b0e906796ae0b33b5ea8 Mon Sep 17 00:00:00 2001 From: Irfan Sheriff Date: Wed, 17 Oct 2012 15:21:23 -0700 Subject: [PATCH 0099/1109] Make packet count test more robust Ensure the packet count test does not fail due to a single attempt. Our goal is to just ensure the packet count API exists. Bug: 7001746 Change-Id: I8c6604528946166969126cd5b085024f81790a77 --- .../android/net/wifi/cts/WifiManagerTest.java | 53 +++++++++++-------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index a64477d100..74083015ce 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -399,30 +399,39 @@ public class WifiManagerTest extends AndroidTestCase { } assertTrue(mWifiManager.isWifiEnabled()); - // Wait for a WiFi connection - connectWifi(); + int i = 0; + for (; i < 15; i++) { + // Wait for a WiFi connection + connectWifi(); - // Read TX packet counter - int txcount1 = getTxPacketCount(); + // Read TX packet counter + int txcount1 = getTxPacketCount(); - // Do some network operations - HttpURLConnection connection = null; - try { - URL url = new URL("http://www.google.com/"); - connection = (HttpURLConnection) url.openConnection(); - connection.setInstanceFollowRedirects(false); - connection.setConnectTimeout(TIMEOUT_MSEC); - connection.setReadTimeout(TIMEOUT_MSEC); - connection.setUseCaches(false); - connection.getInputStream(); - } catch (Exception e) { - // ignore - } finally { - if (connection != null) connection.disconnect(); + // Do some network operations + HttpURLConnection connection = null; + try { + URL url = new URL("http://www.google.com/"); + connection = (HttpURLConnection) url.openConnection(); + connection.setInstanceFollowRedirects(false); + connection.setConnectTimeout(TIMEOUT_MSEC); + connection.setReadTimeout(TIMEOUT_MSEC); + connection.setUseCaches(false); + connection.getInputStream(); + } catch (Exception e) { + // ignore + } finally { + if (connection != null) connection.disconnect(); + } + + // Read TX packet counter again and make sure it increases + int txcount2 = getTxPacketCount(); + + if (txcount2 > txcount1) { + break; + } else { + Thread.sleep(DURATION); + } } - - // Read TX packet counter again and make sure it increases - int txcount2 = getTxPacketCount(); - assertTrue(txcount2 > txcount1); + assertTrue(i < 15); } } From 566cad494d504b60710640d931947cff6aade537 Mon Sep 17 00:00:00 2001 From: Jake Hamby Date: Fri, 26 Oct 2012 15:38:10 -0700 Subject: [PATCH 0100/1109] Fix race condition causing occasional CTS failures. WifiManagerTest was waiting for SUPPLICANT_STATE_CHANGED_ACTION after enabling or disabling WiFi. Fix the code to check if the WiFi state is already the desired state, and if not, to wait for the WIFI_STATE_CHANGED_ACTION broadcast intent. Bug: 7082455 Change-Id: Id1c2242c32311084f5587ea5403f6b227d1b8b04 --- .../android/net/wifi/cts/WifiManagerTest.java | 51 ++++++++++++------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 74083015ce..283f63b5d4 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -55,9 +55,10 @@ public class WifiManagerTest extends AndroidTestCase { private static final int STATE_NULL = 0; private static final int STATE_WIFI_CHANGING = 1; - private static final int STATE_WIFI_CHANGED = 2; - private static final int STATE_SCANING = 3; - private static final int STATE_SCAN_RESULTS_AVAILABLE = 4; + private static final int STATE_WIFI_ENABLED = 2; + private static final int STATE_WIFI_DISABLED = 3; + private static final int STATE_SCANNING = 4; + private static final int STATE_SCAN_RESULTS_AVAILABLE = 5; private static final String TAG = "WifiManagerTest"; private static final String SSID1 = "\"WifiManagerTest\""; @@ -76,20 +77,29 @@ public class WifiManagerTest extends AndroidTestCase { mScanResult = mWifiManager.getScanResults(); mMySync.expectedState = STATE_SCAN_RESULTS_AVAILABLE; mScanResult = mWifiManager.getScanResults(); - mMySync.notify(); + mMySync.notifyAll(); } } - } else if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) { + } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { + int newState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, + WifiManager.WIFI_STATE_UNKNOWN); synchronized (mMySync) { - mMySync.expectedState = STATE_WIFI_CHANGED; - mMySync.notify(); + if (newState == WifiManager.WIFI_STATE_ENABLED) { + Log.d(TAG, "*** New WiFi state is ENABLED ***"); + mMySync.expectedState = STATE_WIFI_ENABLED; + mMySync.notifyAll(); + } else if (newState == WifiManager.WIFI_STATE_DISABLED) { + Log.d(TAG, "*** New WiFi state is DISABLED ***"); + mMySync.expectedState = STATE_WIFI_DISABLED; + mMySync.notifyAll(); + } } } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { synchronized (mMySync) { mNetworkInfo = (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); if (mNetworkInfo.getState() == NetworkInfo.State.CONNECTED) - mMySync.notify(); + mMySync.notifyAll(); } } } @@ -122,7 +132,9 @@ public class WifiManagerTest extends AndroidTestCase { setWifiEnabled(true); Thread.sleep(DURATION); assertTrue(mWifiManager.isWifiEnabled()); - mMySync.expectedState = STATE_NULL; + synchronized (mMySync) { + mMySync.expectedState = STATE_NULL; + } } @Override @@ -132,31 +144,34 @@ public class WifiManagerTest extends AndroidTestCase { super.tearDown(); return; } - mWifiLock.release(); - mContext.unregisterReceiver(mReceiver); if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true); + mWifiLock.release(); + mContext.unregisterReceiver(mReceiver); Thread.sleep(DURATION); super.tearDown(); } private void setWifiEnabled(boolean enable) throws Exception { synchronized (mMySync) { - mMySync.expectedState = STATE_WIFI_CHANGING; assertTrue(mWifiManager.setWifiEnabled(enable)); - long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; - while (System.currentTimeMillis() < timeout - && mMySync.expectedState == STATE_WIFI_CHANGING) - mMySync.wait(WAIT_MSEC); + if (mWifiManager.isWifiEnabled() != enable) { + mMySync.expectedState = STATE_WIFI_CHANGING; + long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; + int expectedState = (enable ? STATE_WIFI_ENABLED : STATE_WIFI_DISABLED); + while (System.currentTimeMillis() < timeout + && mMySync.expectedState != expectedState) + mMySync.wait(WAIT_MSEC); + } } } private void startScan() throws Exception { synchronized (mMySync) { - mMySync.expectedState = STATE_SCANING; + mMySync.expectedState = STATE_SCANNING; assertTrue(mWifiManager.startScan()); long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; - while (System.currentTimeMillis() < timeout && mMySync.expectedState == STATE_SCANING) + while (System.currentTimeMillis() < timeout && mMySync.expectedState == STATE_SCANNING) mMySync.wait(WAIT_MSEC); } } From 775417bd58d53683ce3595c8805c280a97a2c8ee Mon Sep 17 00:00:00 2001 From: Wink Saville Date: Mon, 28 Jan 2013 20:00:57 -0800 Subject: [PATCH 0101/1109] Delete frameworks/base/voip use voip-common from frameworks/opt/net/voip Change-Id: Ieaba759a0f69b45c4b8839cbed1fe757cdf190c5 --- tests/cts/net/Android.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index b327392956..f69c4c3e6e 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -21,7 +21,7 @@ LOCAL_MODULE_TAGS := optional # and when built explicitly put it in the data partition LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) -LOCAL_JAVA_LIBRARIES := android.test.runner +LOCAL_JAVA_LIBRARIES := android.test.runner voip-common # include CtsTestServer as a temporary hack to free net.cts from cts.stub. LOCAL_SRC_FILES := $(call all-java-files-under, src) From 9ac09493ad1352e8193c7bfa5529f9e55e2b45df Mon Sep 17 00:00:00 2001 From: Robert Greenwalt Date: Tue, 5 Feb 2013 11:02:49 -0800 Subject: [PATCH 0102/1109] Add Dns CTS test. Checks java and native calls. Adds some performance tests, but need to look at how that should be used. Change-Id: I158164829da13302d9532275cef3482c4736168e --- tests/cts/net/Android.mk | 4 + tests/cts/net/jni/Android.mk | 30 +++ tests/cts/net/jni/NativeDnsJni.c | 166 ++++++++++++ .../cts/net/src/android/net/cts/DnsTest.java | 237 ++++++++++++++++++ 4 files changed, 437 insertions(+) create mode 100644 tests/cts/net/jni/Android.mk create mode 100644 tests/cts/net/jni/NativeDnsJni.c create mode 100644 tests/cts/net/src/android/net/cts/DnsTest.java diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index f69c4c3e6e..a6543b3a6a 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -23,6 +23,8 @@ LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) LOCAL_JAVA_LIBRARIES := android.test.runner voip-common +LOCAL_JNI_SHARED_LIBRARIES := libnativedns_jni + # include CtsTestServer as a temporary hack to free net.cts from cts.stub. LOCAL_SRC_FILES := $(call all-java-files-under, src) @@ -34,3 +36,5 @@ LOCAL_STATIC_JAVA_LIBRARIES := ctstestserver ctsutil ctstestrunner #LOCAL_SDK_VERSION := current include $(BUILD_CTS_PACKAGE) + +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tests/cts/net/jni/Android.mk b/tests/cts/net/jni/Android.mk new file mode 100644 index 0000000000..75982de3ed --- /dev/null +++ b/tests/cts/net/jni/Android.mk @@ -0,0 +1,30 @@ +# Copyright (C) 2013 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. + +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := libnativedns_jni + +# Don't include this package in any configuration by default. +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := NativeDnsJni.c + +LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) + +LOCAL_SHARED_LIBRARIES := libnativehelper liblog + +include $(BUILD_SHARED_LIBRARY) diff --git a/tests/cts/net/jni/NativeDnsJni.c b/tests/cts/net/jni/NativeDnsJni.c new file mode 100644 index 0000000000..de9bb677b5 --- /dev/null +++ b/tests/cts/net/jni/NativeDnsJni.c @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2010 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. + */ + +#include +#include +#include +#include +#include + +JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclass class) +{ + const char *node = "www.google.com"; + char *service = NULL; + struct addrinfo *answer; + + int res = getaddrinfo(node, service, NULL, &answer); + ALOGD("getaddrinfo(www.google.com) gave res=%d (%s)", res, gai_strerror(res)); + if (res != 0) return JNI_FALSE; + + // check for v4 & v6 + { + int foundv4 = 0; + int foundv6 = 0; + struct addrinfo *current = answer; + while (current != NULL) { + char buf[256]; + if (current->ai_addr->sa_family == AF_INET) { + inet_ntop(current->ai_family, &((struct sockaddr_in *)current->ai_addr)->sin_addr, + buf, sizeof(buf)); + foundv4 = 1; + ALOGD(" %s", buf); + } else if (current->ai_addr->sa_family == AF_INET6) { + inet_ntop(current->ai_family, &((struct sockaddr_in6 *)current->ai_addr)->sin6_addr, + buf, sizeof(buf)); + foundv6 = 1; + ALOGD(" %s", buf); + } + current = current->ai_next; + } + + freeaddrinfo(answer); + answer = NULL; + if (foundv4 != 1 || foundv6 != 1) { + ALOGD("getaddrinfo(www.google.com) didn't find both v4 and v6"); + return JNI_FALSE; + } + } + + node = "ipv6.google.com"; + res = getaddrinfo(node, service, NULL, &answer); + ALOGD("getaddrinfo(ipv6.google.com) gave res=%d", res); + if (res != 0) return JNI_FALSE; + + { + int foundv4 = 0; + int foundv6 = 0; + struct addrinfo *current = answer; + while (current != NULL) { + char buf[256]; + if (current->ai_addr->sa_family == AF_INET) { + inet_ntop(current->ai_family, &((struct sockaddr_in *)current->ai_addr)->sin_addr, + buf, sizeof(buf)); + ALOGD(" %s", buf); + foundv4 = 1; + } else if (current->ai_addr->sa_family == AF_INET6) { + inet_ntop(current->ai_family, &((struct sockaddr_in6 *)current->ai_addr)->sin6_addr, + buf, sizeof(buf)); + ALOGD(" %s", buf); + foundv6 = 1; + } + current = current->ai_next; + } + + freeaddrinfo(answer); + answer = NULL; + if (foundv4 == 1 || foundv6 != 1) { + ALOGD("getaddrinfo(ipv6.google.com) didn't find only v6"); + return JNI_FALSE; + } + } + + // getnameinfo + struct sockaddr_in sa4; + sa4.sin_family = AF_INET; + sa4.sin_port = 0; + inet_pton(AF_INET, "173.252.110.27", &(sa4.sin_addr)); + + struct sockaddr_in6 sa6; + sa6.sin6_family = AF_INET6; + sa6.sin6_port = 0; + sa6.sin6_flowinfo = 0; + sa6.sin6_scope_id = 0; + inet_pton(AF_INET6, "2001:4860:4001:802::1008", &(sa6.sin6_addr)); + + char buf[NI_MAXHOST]; + int flags = NI_NAMEREQD; + + res = getnameinfo((const struct sockaddr*)&sa4, sizeof(sa4), buf, sizeof(buf), NULL, 0, flags); + if (res != 0) { + ALOGD("getnameinfo(173.252.110.27 (facebook) ) gave error %d (%s)", res, gai_strerror(res)); + return JNI_FALSE; + } + if (strstr(buf, "facebook.com") == NULL) { + ALOGD("getnameinfo(173.252.110.27 (facebook) ) didn't return facebook.com: %s", buf); + return JNI_FALSE; + } + + memset(buf, sizeof(buf), 0); + res = getnameinfo((const struct sockaddr*)&sa6, sizeof(sa6), buf, sizeof(buf), + NULL, 0, flags); + if (res != 0) { + ALOGD("getnameinfo(2a03:2880:2110:df01:face:b00c::8 (facebook) ) gave error %d (%s)", + res, gai_strerror(res)); + return JNI_FALSE; + } + if (strstr(buf, "1e100.net") == NULL) { + ALOGD("getnameinfo(2a03:2880:2110:df01:face:b00c::8) didn't return facebook.com: %s", buf); + return JNI_FALSE; + } + + // gethostbyname + struct hostent *my_hostent = gethostbyname("www.mit.edu"); + if (my_hostent == NULL) { + ALOGD("gethostbyname(www.mit.edu) gave null response"); + return JNI_FALSE; + } + if ((my_hostent->h_addr_list == NULL) || (*my_hostent->h_addr_list == NULL)) { + ALOGD("gethostbyname(www.mit.edu) gave 0 addresses"); + return JNI_FALSE; + } + { + char **current = my_hostent->h_addr_list; + while (*current != NULL) { + char buf[256]; + inet_ntop(my_hostent->h_addrtype, *current, buf, sizeof(buf)); + ALOGD("gethostbyname(www.mit.edu) gave %s", buf); + current++; + } + } + + // gethostbyaddr + char addr6[16]; + inet_pton(AF_INET6, "2001:4b10:bbc::2", addr6); + my_hostent = gethostbyaddr(addr6, sizeof(addr6), AF_INET6); + if (my_hostent == NULL) { + ALOGD("gethostbyaddr(2001:4b10:bbc::2 (bbc) ) gave null response"); + return JNI_FALSE; + } + ALOGD("gethostbyaddr(2001:4b10:bbc::2 (bbc) ) gave %s for name", + my_hostent->h_name ? my_hostent->h_name : "null"); + if (my_hostent->h_name == NULL) return JNI_FALSE; + return JNI_TRUE; +} diff --git a/tests/cts/net/src/android/net/cts/DnsTest.java b/tests/cts/net/src/android/net/cts/DnsTest.java new file mode 100644 index 0000000000..cdd95aa077 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/DnsTest.java @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2013 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.os.SystemClock; +import android.test.AndroidTestCase; +import android.util.Log; + +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; + +public class DnsTest extends AndroidTestCase { + + static { + System.loadLibrary("nativedns_jni"); + } + + private static final boolean DBG = false; + private static final String TAG = "DnsTest"; + + /** + * @return true on success + */ + private static native boolean testNativeDns(); + + /** + * Verify: + * DNS works - forwards and backwards, giving ipv4 and ipv6 + * Test that DNS work on v4 and v6 networks + * Test Native dns calls (4) + * Todo: + * Cache is flushed when we change networks + * have per-network caches + * No cache when there's no network + * Perf - measure size of first and second tier caches and their effect + * Assert requires network permission + */ + public void testDnsWorks() { + InetAddress addrs[] = {}; + try { + addrs = InetAddress.getAllByName("www.google.com"); + } catch (UnknownHostException e) {} + assertTrue(addrs.length != 0); + boolean foundV4 = false, foundV6 = false; + for (InetAddress addr : addrs) { + if (addr instanceof Inet4Address) foundV4 = true; + else if (addr instanceof Inet6Address) foundV6 = true; + if (DBG) Log.e(TAG, "www.google.com gave " + addr.toString()); + } + assertTrue(foundV4); + assertTrue(foundV6); + try { + addrs = InetAddress.getAllByName("ipv6.google.com"); + } catch (UnknownHostException e) {} + assertTrue(addrs.length != 0); + foundV4 = false; + foundV6 = false; + for (InetAddress addr : addrs) { + if (addr instanceof Inet4Address) foundV4 = true; + else if (addr instanceof Inet6Address) foundV6 = true; + if (DBG) Log.e(TAG, "ipv6.google.com gave " + addr.toString()); + } + assertTrue(foundV4 == false); + assertTrue(foundV6 == true); + assertTrue(testNativeDns()); + } + + private static final String[] URLS = { "www.google.com", "ipv6.google.com", "www.yahoo.com", + "facebook.com", "youtube.com", "blogspot.com", "baidu.com", "wikipedia.org", +// live.com fails rev lookup. + "twitter.com", "qq.com", "msn.com", "yahoo.co.jp", "linkedin.com", + "taobao.com", "google.co.in", "sina.com.cn", "amazon.com", "wordpress.com", + "google.co.uk", "ebay.com", "yandex.ru", "163.com", "google.co.jp", "google.fr", + "microsoft.com", "paypal.com", "google.com.br", "flickr.com", + "mail.ru", "craigslist.org", "fc2.com", "google.it", +// "apple.com", fails rev lookup + "google.es", + "imdb.com", "google.ru", "soho.com", "bbc.co.uk", "vkontakte.ru", "ask.com", + "tumblr.com", "weibo.com", "go.com", "xvideos.com", "livejasmin.com", "cnn.com", + "youku.com", "blogspot.com", "soso.com", "google.ca", "aol.com", "tudou.com", + "xhamster.com", "megaupload.com", "ifeng.com", "zedo.com", "mediafire.com", "ameblo.jp", + "pornhub.com", "google.co.id", "godaddy.com", "adobe.com", "rakuten.co.jp", "about.com", + "espn.go.com", "4shared.com", "alibaba.com","ebay.de", "yieldmanager.com", + "wordpress.org", "livejournal.com", "google.com.tr", "google.com.mx", "renren.com", + "livedoor.com", "google.com.au", "youporn.com", "uol.com.br", "cnet.com", "conduit.com", + "google.pl", "myspace.com", "nytimes.com", "ebay.co.uk", "chinaz.com", "hao123.com", + "thepiratebay.org", "doubleclick.com", "alipay.com", "netflix.com", "cnzz.com", + "huffingtonpost.com", "twitpic.com", "weather.com", "babylon.com", "amazon.de", + "dailymotion.com", "orkut.com", "orkut.com.br", "google.com.sa", "odnoklassniki.ru", + "amazon.co.jp", "google.nl", "goo.ne.jp", "stumbleupon.com", "tube8.com", "tmall.com", + "imgur.com", "globo.com", "secureserver.net", "fileserve.com", "tianya.cn", "badoo.com", + "ehow.com", "photobucket.com", "imageshack.us", "xnxx.com", "deviantart.com", + "filestube.com", "addthis.com", "douban.com", "vimeo.com", "sogou.com", + "stackoverflow.com", "reddit.com", "dailymail.co.uk", "redtube.com", "megavideo.com", + "taringa.net", "pengyou.com", "amazon.co.uk", "fbcdn.net", "aweber.com", "spiegel.de", + "rapidshare.com", "mixi.jp", "360buy.com", "google.cn", "digg.com", "answers.com", + "bit.ly", "indiatimes.com", "skype.com", "yfrog.com", "optmd.com", "google.com.eg", + "google.com.pk", "58.com", "hotfile.com", "google.co.th", + "bankofamerica.com", "sourceforge.net", "maktoob.com", "warriorforum.com", "rediff.com", + "google.co.za", "56.com", "torrentz.eu", "clicksor.com", "avg.com", + "download.com", "ku6.com", "statcounter.com", "foxnews.com", "google.com.ar", + "nicovideo.jp", "reference.com", "liveinternet.ru", "ucoz.ru", "xinhuanet.com", + "xtendmedia.com", "naver.com", "youjizz.com", "domaintools.com", "sparkstudios.com", + "rambler.ru", "scribd.com", "kaixin001.com", "mashable.com", "adultfirendfinder.com", + "files.wordpress.com", "guardian.co.uk", "bild.de", "yelp.com", "wikimedia.org", + "chase.com", "onet.pl", "ameba.jp", "pconline.com.cn", "free.fr", "etsy.com", + "typepad.com", "youdao.com", "megaclick.com", "digitalpoint.com", "blogfa.com", + "salesforce.com", "adf.ly", "ganji.com", "wikia.com", "archive.org", "terra.com.br", + "w3schools.com", "ezinearticles.com", "wjs.com", "google.com.my", "clickbank.com", + "squidoo.com", "hulu.com", "repubblica.it", "google.be", "allegro.pl", "comcast.net", + "narod.ru", "zol.com.cn", "orange.fr", "soufun.com", "hatena.ne.jp", "google.gr", + "in.com", "techcrunch.com", "orkut.co.in", "xunlei.com", + "reuters.com", "google.com.vn", "hostgator.com", "kaskus.us", "espncricinfo.com", + "hootsuite.com", "qiyi.com", "gmx.net", "xing.com", "php.net", "soku.com", "web.de", + "libero.it", "groupon.com", "51.la", "slideshare.net", "booking.com", "seesaa.net", + "126.com", "telegraph.co.uk", "wretch.cc", "twimg.com", "rutracker.org", "angege.com", + "nba.com", "dell.com", "leboncoin.fr", "people.com", "google.com.tw", "walmart.com", + "daum.net", "2ch.net", "constantcontact.com", "nifty.com", "mywebsearch.com", + "tripadvisor.com", "google.se", "paipai.com", "google.com.ua", "ning.com", "hp.com", + "google.at", "joomla.org", "icio.us", "hudong.com", "csdn.net", "getfirebug.com", + "ups.com", "cj.com", "google.ch", "camzap.com", "wordreference.com", "tagged.com", + "wp.pl", "mozilla.com", "google.ru", "usps.com", "china.com", "themeforest.net", + "search-results.com", "tribalfusion.com", "thefreedictionary.com", "isohunt.com", + "linkwithin.com", "cam4.com", "plentyoffish.com", "wellsfargo.com", "metacafe.com", + "depositfiles.com", "freelancer.com", "opendns.com", "homeway.com", "engadget.com", + "10086.cn", "360.cn", "marca.com", "dropbox.com", "ign.com", "match.com", "google.pt", + "facemoods.com", "hardsextube.com", "google.com.ph", "lockerz.com", "istockphoto.com", + "partypoker.com", "netlog.com", "outbrain.com", "elpais.com", "fiverr.com", + "biglobe.ne.jp", "corriere.it", "love21cn.com", "yesky.com", "spankwire.com", + "ig.com.br", "imagevenue.com", "hubpages.com", "google.co.ve"}; + +// TODO - this works, but is slow and cts doesn't do anything with the result. +// Maybe require a min performance, a min cache size (detectable) and/or move +// to perf testing + private static final int LOOKUP_COUNT_GOAL = URLS.length; + public void skiptestDnsPerf() { + ArrayList results = new ArrayList(); + int failures = 0; + try { + for (int numberOfUrls = URLS.length; numberOfUrls > 0; numberOfUrls--) { + failures = 0; + int iterationLimit = LOOKUP_COUNT_GOAL / numberOfUrls; + long startTime = SystemClock.elapsedRealtimeNanos(); + for (int iteration = 0; iteration < iterationLimit; iteration++) { + for (int urlIndex = 0; urlIndex < numberOfUrls; urlIndex++) { + try { + InetAddress addr = InetAddress.getByName(URLS[urlIndex]); + } catch (UnknownHostException e) { + Log.e(TAG, "failed first lookup of " + URLS[urlIndex]); + failures++; + try { + InetAddress addr = InetAddress.getByName(URLS[urlIndex]); + } catch (UnknownHostException ee) { + failures++; + Log.e(TAG, "failed SECOND lookup of " + URLS[urlIndex]); + } + } + } + } + long endTime = SystemClock.elapsedRealtimeNanos(); + float nsPer = ((float)(endTime-startTime) / iterationLimit) / numberOfUrls/ 1000; + String thisResult = new String("getByName for " + numberOfUrls + " took " + + (endTime - startTime)/1000 + "(" + nsPer + ") with " + + failures + " failures\n"); + Log.d(TAG, thisResult); + results.add(thisResult); + } + // build up a list of addresses + ArrayList addressList = new ArrayList(); + for (String url : URLS) { + try { + InetAddress addr = InetAddress.getByName(url); + addressList.add(addr.getAddress()); + } catch (UnknownHostException e) { + Log.e(TAG, "Exception making reverseDNS list: " + e.toString()); + } + } + for (int numberOfAddrs = addressList.size(); numberOfAddrs > 0; numberOfAddrs--) { + int iterationLimit = LOOKUP_COUNT_GOAL / numberOfAddrs; + failures = 0; + long startTime = SystemClock.elapsedRealtimeNanos(); + for (int iteration = 0; iteration < iterationLimit; iteration++) { + for (int addrIndex = 0; addrIndex < numberOfAddrs; addrIndex++) { + try { + InetAddress addr = InetAddress.getByAddress(addressList.get(addrIndex)); + String hostname = addr.getHostName(); + } catch (UnknownHostException e) { + failures++; + Log.e(TAG, "Failure doing reverse DNS lookup: " + e.toString()); + try { + InetAddress addr = + InetAddress.getByAddress(addressList.get(addrIndex)); + String hostname = addr.getHostName(); + + } catch (UnknownHostException ee) { + failures++; + Log.e(TAG, "Failure doing SECOND reverse DNS lookup: " + + ee.toString()); + } + } + } + } + long endTime = SystemClock.elapsedRealtimeNanos(); + float nsPer = ((endTime-startTime) / iterationLimit) / numberOfAddrs / 1000; + String thisResult = new String("getHostName for " + numberOfAddrs + " took " + + (endTime - startTime)/1000 + "(" + nsPer + ") with " + + failures + " failures\n"); + Log.d(TAG, thisResult); + results.add(thisResult); + } + for (String result : results) Log.d(TAG, result); + + InetAddress exit = InetAddress.getByName("exitrightnow.com"); + Log.e(TAG, " exit address= "+exit.toString()); + + } catch (Exception e) { + Log.e(TAG, "bad URL in testDnsPerf: " + e.toString()); + } + } +} From fe3b3f62a45320e8492457b16953fb1c81298ab9 Mon Sep 17 00:00:00 2001 From: JP Abgrall Date: Fri, 1 Mar 2013 16:41:16 -0800 Subject: [PATCH 0103/1109] Fixup TrafficStats test wrt mobile vs total vs loopback - Use getMobileBlabla() instead of getTotalBlabla() - Have getTotalBlabla() reflect the fact that it includes loopback. - Adjust checks to take headers, acks, and packet counts into account. Change-Id: I9e1dfbbbdb9a6f932a14a2e3baee7a34469b9008 --- .../src/android/net/cts/TrafficStatsTest.java | 132 ++++++++++++------ 1 file changed, 87 insertions(+), 45 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java index a5bbd9886a..89933bfc5c 100644 --- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java +++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java @@ -42,19 +42,29 @@ public class TrafficStatsTest extends AndroidTestCase { TrafficStats.getMobileRxBytes() >= 0); } + long tcpPacketToIpBytes(long packetCount, long bytes) { + // ip header + tcp header + data. + // Tcp header is mostly 32. Syn has different tcp options -> 40. Don't care. + return packetCount * (20 + 32 + bytes); + } + public void testTrafficStatsForLocalhost() throws IOException { - long mobileTxPacketsBefore = TrafficStats.getTotalTxPackets(); - long mobileRxPacketsBefore = TrafficStats.getTotalRxPackets(); - long mobileTxBytesBefore = TrafficStats.getTotalTxBytes(); - long mobileRxBytesBefore = TrafficStats.getTotalRxBytes(); + long mobileTxPacketsBefore = TrafficStats.getMobileTxPackets(); + long mobileRxPacketsBefore = TrafficStats.getMobileRxPackets(); + long mobileTxBytesBefore = TrafficStats.getMobileTxBytes(); + long mobileRxBytesBefore = TrafficStats.getMobileRxBytes(); long totalTxPacketsBefore = TrafficStats.getTotalTxPackets(); long totalRxPacketsBefore = TrafficStats.getTotalRxPackets(); long totalTxBytesBefore = TrafficStats.getTotalTxBytes(); long totalRxBytesBefore = TrafficStats.getTotalRxBytes(); long uidTxBytesBefore = TrafficStats.getUidTxBytes(Process.myUid()); long uidRxBytesBefore = TrafficStats.getUidRxBytes(Process.myUid()); + long uidTxPacketsBefore = TrafficStats.getUidTxPackets(Process.myUid()); + long uidRxPacketsBefore = TrafficStats.getUidRxPackets(Process.myUid()); // Transfer 1MB of data across an explicitly localhost socket. + final int byteCount = 1024; + final int packetCount = 1024; final ServerSocket server = new ServerSocket(0); new Thread("TrafficStatsTest.testTrafficStatsForLocalhost") { @@ -62,9 +72,15 @@ public class TrafficStatsTest extends AndroidTestCase { public void run() { try { Socket socket = new Socket("localhost", server.getLocalPort()); + // Make sure that each write()+flush() turns into a packet: + // disable Nagle. + socket.setTcpNoDelay(true); OutputStream out = socket.getOutputStream(); - byte[] buf = new byte[1024]; - for (int i = 0; i < 1024; i++) out.write(buf); + byte[] buf = new byte[byteCount]; + for (int i = 0; i < packetCount; i++) { + out.write(buf); + out.flush(); + } out.close(); socket.close(); } catch (IOException e) { @@ -75,9 +91,9 @@ public class TrafficStatsTest extends AndroidTestCase { try { Socket socket = server.accept(); InputStream in = socket.getInputStream(); - byte[] buf = new byte[1024]; + byte[] buf = new byte[byteCount]; int read = 0; - while (read < 1048576) { + while (read < byteCount * packetCount) { int n = in.read(buf); assertTrue("Unexpected EOF", n > 0); read += n; @@ -92,50 +108,76 @@ public class TrafficStatsTest extends AndroidTestCase { } catch (InterruptedException e) { } - long mobileTxPacketsAfter = TrafficStats.getTotalTxPackets(); - long mobileRxPacketsAfter = TrafficStats.getTotalRxPackets(); - long mobileTxBytesAfter = TrafficStats.getTotalTxBytes(); - long mobileRxBytesAfter = TrafficStats.getTotalRxBytes(); + long mobileTxPacketsAfter = TrafficStats.getMobileTxPackets(); + long mobileRxPacketsAfter = TrafficStats.getMobileRxPackets(); + long mobileTxBytesAfter = TrafficStats.getMobileTxBytes(); + long mobileRxBytesAfter = TrafficStats.getMobileRxBytes(); long totalTxPacketsAfter = TrafficStats.getTotalTxPackets(); long totalRxPacketsAfter = TrafficStats.getTotalRxPackets(); long totalTxBytesAfter = TrafficStats.getTotalTxBytes(); long totalRxBytesAfter = TrafficStats.getTotalRxBytes(); long uidTxBytesAfter = TrafficStats.getUidTxBytes(Process.myUid()); long uidRxBytesAfter = TrafficStats.getUidRxBytes(Process.myUid()); - - // Localhost traffic should *not* count against mobile or total stats. - // There might be some other traffic, but nowhere near 1MB. - - assertTrue("mtxp: " + mobileTxPacketsBefore + " -> " + mobileTxPacketsAfter, - mobileTxPacketsAfter >= mobileTxPacketsBefore && - mobileTxPacketsAfter <= mobileTxPacketsBefore + 500); - assertTrue("mrxp: " + mobileRxPacketsBefore + " -> " + mobileRxPacketsAfter, - mobileRxPacketsAfter >= mobileRxPacketsBefore && - mobileRxPacketsAfter <= mobileRxPacketsBefore + 500); - assertTrue("mtxb: " + mobileTxBytesBefore + " -> " + mobileTxBytesAfter, - mobileTxBytesAfter >= mobileTxBytesBefore && - mobileTxBytesAfter <= mobileTxBytesBefore + 200000); - assertTrue("mrxb: " + mobileRxBytesBefore + " -> " + mobileRxBytesAfter, - mobileRxBytesAfter >= mobileRxBytesBefore && - mobileRxBytesAfter <= mobileRxBytesBefore + 200000); - - assertTrue("ttxp: " + totalTxPacketsBefore + " -> " + totalTxPacketsAfter, - totalTxPacketsAfter >= totalTxPacketsBefore && - totalTxPacketsAfter <= totalTxPacketsBefore + 500); - assertTrue("trxp: " + totalRxPacketsBefore + " -> " + totalRxPacketsAfter, - totalRxPacketsAfter >= totalRxPacketsBefore && - totalRxPacketsAfter <= totalRxPacketsBefore + 500); - assertTrue("ttxb: " + totalTxBytesBefore + " -> " + totalTxBytesAfter, - totalTxBytesAfter >= totalTxBytesBefore && - totalTxBytesAfter <= totalTxBytesBefore + 200000); - assertTrue("trxb: " + totalRxBytesBefore + " -> " + totalRxBytesAfter, - totalRxBytesAfter >= totalRxBytesBefore && - totalRxBytesAfter <= totalRxBytesBefore + 200000); + long uidTxPacketsAfter = TrafficStats.getUidTxPackets(Process.myUid()); + long uidRxPacketsAfter = TrafficStats.getUidRxPackets(Process.myUid()); + long uidTxDeltaBytes = uidTxBytesAfter - uidTxBytesBefore; + long uidTxDeltaPackets = uidTxPacketsAfter - uidTxPacketsBefore; + long uidRxDeltaBytes = uidRxBytesAfter - uidRxBytesBefore; + long uidRxDeltaPackets = uidRxPacketsAfter - uidRxPacketsBefore; // Localhost traffic *does* count against per-UID stats. - assertTrue("uidtxb: " + uidTxBytesBefore + " -> " + uidTxBytesAfter, - uidTxBytesAfter >= uidTxBytesBefore + 1048576); - assertTrue("uidrxb: " + uidRxBytesBefore + " -> " + uidRxBytesAfter, - uidRxBytesAfter >= uidRxBytesBefore + 1048576); + /* + * Calculations: + * - bytes + * bytes is approx: packets * data + packets * acks; + * but sometimes there are less acks than packets, so we set a lower + * limit of 1 ack. + * - setup/teardown + * + 7 approx.: syn, syn-ack, ack, fin-ack, ack, fin-ack, ack; + * but sometimes the last find-acks just vanish, so we set a lower limit of +5. + */ + assertTrue("uidtxp: " + uidTxPacketsBefore + " -> " + uidTxPacketsAfter + " delta=" + uidTxDeltaPackets, + uidTxDeltaPackets >= packetCount + 5 && + uidTxDeltaPackets <= packetCount + packetCount + 7); + assertTrue("uidrxp: " + uidRxPacketsBefore + " -> " + uidRxPacketsAfter + " delta=" + uidRxDeltaPackets, + uidRxDeltaPackets >= packetCount + 5 && + uidRxDeltaPackets <= packetCount + packetCount + 7); + assertTrue("uidtxb: " + uidTxBytesBefore + " -> " + uidTxBytesAfter + " delta=" + uidTxDeltaBytes, + uidTxDeltaBytes >= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(5, 0) && + uidTxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + 7, 0)); + assertTrue("uidrxb: " + uidRxBytesBefore + " -> " + uidRxBytesAfter + " delta=" + uidRxDeltaBytes, + uidRxDeltaBytes >= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(5, 0) && + uidRxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + 7, 0)); + + // Localhost traffic *does* count against total stats. + // Fudge by 132 packets of 1500 bytes not related to the test. + assertTrue("ttxp: " + totalTxPacketsBefore + " -> " + totalTxPacketsAfter, + totalTxPacketsAfter >= totalTxPacketsBefore + uidTxDeltaPackets && + totalTxPacketsAfter <= totalTxPacketsBefore + uidTxDeltaPackets + 132); + assertTrue("trxp: " + totalRxPacketsBefore + " -> " + totalRxPacketsAfter, + totalRxPacketsAfter >= totalRxPacketsBefore + uidRxDeltaPackets && + totalRxPacketsAfter <= totalRxPacketsBefore + uidRxDeltaPackets + 132); + assertTrue("ttxb: " + totalTxBytesBefore + " -> " + totalTxBytesAfter, + totalTxBytesAfter >= totalTxBytesBefore + uidTxDeltaBytes && + totalTxBytesAfter <= totalTxBytesBefore + uidTxDeltaBytes + 132 * 1500); + assertTrue("trxb: " + totalRxBytesBefore + " -> " + totalRxBytesAfter, + totalRxBytesAfter >= totalRxBytesBefore + uidRxDeltaBytes && + totalRxBytesAfter <= totalRxBytesBefore + uidRxDeltaBytes + 132 * 1500); + + // Localhost traffic should *not* count against mobile stats, + // There might be some other traffic, but nowhere near 1MB. + assertTrue("mtxp: " + mobileTxPacketsBefore + " -> " + mobileTxPacketsAfter, + mobileTxPacketsAfter >= mobileTxPacketsBefore && + mobileTxPacketsAfter <= mobileTxPacketsBefore + 500); + assertTrue("mrxp: " + mobileRxPacketsBefore + " -> " + mobileRxPacketsAfter, + mobileRxPacketsAfter >= mobileRxPacketsBefore && + mobileRxPacketsAfter <= mobileRxPacketsBefore + 500); + assertTrue("mtxb: " + mobileTxBytesBefore + " -> " + mobileTxBytesAfter, + mobileTxBytesAfter >= mobileTxBytesBefore && + mobileTxBytesAfter <= mobileTxBytesBefore + 200000); + assertTrue("mrxb: " + mobileRxBytesBefore + " -> " + mobileRxBytesAfter, + mobileRxBytesAfter >= mobileRxBytesBefore && + mobileRxBytesAfter <= mobileRxBytesBefore + 200000); + } } From 98eea9f03a0fc047c7ae6821f5220c4a4556fee3 Mon Sep 17 00:00:00 2001 From: Irfan Sheriff Date: Fri, 22 Mar 2013 13:56:03 -0700 Subject: [PATCH 0104/1109] Add cts to test quotes on ssid in WifiInfo Bug: 7892415 Change-Id: I0e7b97762aa755f9d10655572be0ad550e370716 --- tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java index 16dc57de2b..8719b6b029 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java @@ -122,7 +122,13 @@ public class WifiInfoTest extends AndroidTestCase { assertNotNull(wifiInfo.toString()); SupplicantState.isValidState(wifiInfo.getSupplicantState()); WifiInfo.getDetailedStateOf(SupplicantState.DISCONNECTED); - wifiInfo.getSSID(); + String ssid = wifiInfo.getSSID(); + if (ssid.startsWith("0x") == false) { + // Non-hex string should be quoted + assertTrue(ssid.charAt(0) == '"'); + assertTrue(ssid.charAt(ssid.length() - 1) == '"'); + } + wifiInfo.getBSSID(); wifiInfo.getIpAddress(); wifiInfo.getLinkSpeed(); From 66bc4595dc8f98817fbc1529f2a8c7df7fb46580 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Tue, 26 Mar 2013 14:00:34 -0700 Subject: [PATCH 0105/1109] TrafficStats are always supported, tag tests. Bug: 8417220 Change-Id: I2a06d2e752606cec4bfe35266d9e37271c275d95 --- .../src/android/net/cts/TrafficStatsTest.java | 47 +++++++++++++++---- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java index 89933bfc5c..180d259bbc 100644 --- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java +++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java @@ -16,7 +16,6 @@ package android.net.cts; - import android.net.TrafficStats; import android.os.Process; import android.test.AndroidTestCase; @@ -26,20 +25,48 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; public class TrafficStatsTest extends AndroidTestCase { - public void testGetMobileStats() { + public void testValidMobileStats() { // We can't assume a mobile network is even present in this test, so // we simply assert that a valid value is returned. - assertTrue(TrafficStats.getMobileTxPackets() == TrafficStats.UNSUPPORTED || - TrafficStats.getMobileTxPackets() >= 0); - assertTrue(TrafficStats.getMobileRxPackets() == TrafficStats.UNSUPPORTED || - TrafficStats.getMobileRxPackets() >= 0); - assertTrue(TrafficStats.getMobileTxBytes() == TrafficStats.UNSUPPORTED || - TrafficStats.getMobileTxBytes() >= 0); - assertTrue(TrafficStats.getMobileRxBytes() == TrafficStats.UNSUPPORTED || - TrafficStats.getMobileRxBytes() >= 0); + assertTrue(TrafficStats.getMobileTxPackets() >= 0); + assertTrue(TrafficStats.getMobileRxPackets() >= 0); + assertTrue(TrafficStats.getMobileTxBytes() >= 0); + assertTrue(TrafficStats.getMobileRxBytes() >= 0); + } + + public void testValidTotalStats() { + assertTrue(TrafficStats.getTotalTxPackets() >= 0); + assertTrue(TrafficStats.getTotalRxPackets() >= 0); + assertTrue(TrafficStats.getTotalTxBytes() >= 0); + assertTrue(TrafficStats.getTotalRxBytes() >= 0); + } + + public void testThreadStatsTag() throws Exception { + TrafficStats.setThreadStatsTag(0xf00d); + assertTrue("Tag didn't stick", TrafficStats.getThreadStatsTag() == 0xf00d); + + final CountDownLatch latch = new CountDownLatch(1); + + new Thread("TrafficStatsTest.testThreadStatsTag") { + @Override + public void run() { + assertTrue("Tag leaked", TrafficStats.getThreadStatsTag() != 0xf00d); + TrafficStats.setThreadStatsTag(0xcafe); + assertTrue("Tag didn't stick", TrafficStats.getThreadStatsTag() == 0xcafe); + latch.countDown(); + } + }.start(); + + latch.await(5, TimeUnit.SECONDS); + assertTrue("Tag lost", TrafficStats.getThreadStatsTag() == 0xf00d); + + TrafficStats.clearThreadStatsTag(); + assertTrue("Tag not cleared", TrafficStats.getThreadStatsTag() != 0xf00d); } long tcpPacketToIpBytes(long packetCount, long bytes) { From 5e1b502ce8b8639e20458e058ef00b311ccdd38e Mon Sep 17 00:00:00 2001 From: Robert Greenwalt Date: Mon, 11 Mar 2013 14:32:33 -0700 Subject: [PATCH 0106/1109] Add CTS tests for ConnectivityService bug:4074341 Change-Id: Ic02d08e51c051789ed7fa1c949d42fa22bdc8a08 --- .../net/cts/ConnectivityManagerTest.java | 184 +++++++++++++----- 1 file changed, 138 insertions(+), 46 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 4fa69a88f3..c24415901c 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -23,6 +23,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.net.ConnectivityManager; +import android.net.NetworkConfig; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; @@ -30,7 +31,10 @@ import android.net.wifi.WifiManager; import android.test.AndroidTestCase; import android.util.Log; +import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -51,6 +55,9 @@ public class ConnectivityManagerTest extends AndroidTestCase { private ConnectivityManager mCm; private WifiManager mWifiManager; private PackageManager mPackageManager; + private final HashMap mNetworks = + new HashMap(); + private final ListmProtectedNetworks = new ArrayList(); @Override protected void setUp() throws Exception { @@ -58,45 +65,115 @@ public class ConnectivityManagerTest extends AndroidTestCase { mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); mPackageManager = getContext().getPackageManager(); - } - public void testGetNetworkInfo() { - assertTrue(mCm.getAllNetworkInfo().length >= MIN_NUM_NETWORK_TYPES); - NetworkInfo ni = mCm.getNetworkInfo(TYPE_WIFI); - if (ni != null) { - State state = ni.getState(); - assertTrue(State.UNKNOWN.ordinal() >= state.ordinal() - && state.ordinal() >= State.CONNECTING.ordinal()); - DetailedState ds = ni.getDetailedState(); - assertTrue(DetailedState.FAILED.ordinal() >= ds.ordinal() - && ds.ordinal() >= DetailedState.IDLE.ordinal()); + String[] naStrings = getContext().getResources().getStringArray( + com.android.internal.R.array.networkAttributes); + for (String naString : naStrings) { + try { + NetworkConfig n = new NetworkConfig(naString); + mNetworks.put(n.type, n); + } catch (Exception e) {} } - ni = mCm.getNetworkInfo(TYPE_MOBILE); - if (ni != null) { - State state = ni.getState(); - assertTrue(State.UNKNOWN.ordinal() >= state.ordinal() - && state.ordinal() >= State.CONNECTING.ordinal()); - DetailedState ds = ni.getDetailedState(); - assertTrue(DetailedState.FAILED.ordinal() >= ds.ordinal() - && ds.ordinal() >= DetailedState.IDLE.ordinal()); + + int[] protectedNetworks = getContext().getResources().getIntArray( + com.android.internal.R.array.config_protectedNetworks); + for (int p : protectedNetworks) { + mProtectedNetworks.add(p); } - ni = mCm.getNetworkInfo(-1); - assertNull(ni); } public void testIsNetworkTypeValid() { + assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE)); + assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_WIFI)); + assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_MMS)); + assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_SUPL)); + assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_DUN)); + assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_HIPRI)); + assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_WIMAX)); + assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_BLUETOOTH)); + assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_DUMMY)); + assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_ETHERNET)); + assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_FOTA)); + assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_IMS)); + assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_CBS)); + assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_WIFI_P2P)); + assertFalse(mCm.isNetworkTypeValid(-1)); + assertTrue(mCm.isNetworkTypeValid(0)); + assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.MAX_NETWORK_TYPE)); + assertFalse(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.MAX_NETWORK_TYPE+1)); NetworkInfo[] ni = mCm.getAllNetworkInfo(); - for (NetworkInfo n : ni) { + for (NetworkInfo n: ni) { assertTrue(ConnectivityManager.isNetworkTypeValid(n.getType())); } - assertFalse(ConnectivityManager.isNetworkTypeValid(-1)); + + } + + public void testSetNetworkPreference() { + // verify swtiching between two default networks - need to connectable networks though + // could use test and whatever the current active network is + NetworkInfo active = mCm.getActiveNetworkInfo(); + int originalPref = mCm.getNetworkPreference(); + int currentPref = originalPref; + for (int type = -1; type <= ConnectivityManager.MAX_NETWORK_TYPE+1; type++) { + mCm.setNetworkPreference(type); + NetworkConfig c = mNetworks.get(type); + boolean expectWorked = (c != null && c.isDefault()); + try { + Thread.currentThread().sleep(100); + } catch (InterruptedException e) {} + int foundType = mCm.getNetworkPreference(); + if (expectWorked) { + assertTrue("We should have been able to switch prefered type " + type, + foundType == type); + currentPref = foundType; + } else { + assertTrue("We should not have been able to switch type " + type, + foundType == currentPref); + } + } + mCm.setNetworkPreference(originalPref); + } + + public void testGetActiveNetworkInfo() { + NetworkInfo ni = mCm.getActiveNetworkInfo(); + + assertTrue("You must have an active network connection to complete CTS", ni != null); + assertTrue(ConnectivityManager.isNetworkTypeValid(ni.getType())); + assertTrue(ni.getState() == State.CONNECTED); + } + + public void testGetNetworkInfo() { + for (int type = -1; type <= ConnectivityManager.MAX_NETWORK_TYPE+1; type++) { + if (isSupported(type)) { + NetworkInfo ni = mCm.getNetworkInfo(type); + assertTrue("Info shouldn't be null for " + type, ni != null); + State state = ni.getState(); + assertTrue("Bad state for " + type, State.UNKNOWN.ordinal() >= state.ordinal() + && state.ordinal() >= State.CONNECTING.ordinal()); + DetailedState ds = ni.getDetailedState(); + assertTrue("Bad detailed state for " + type, + DetailedState.FAILED.ordinal() >= ds.ordinal() + && ds.ordinal() >= DetailedState.IDLE.ordinal()); + } else { + assertNull("Info should be null for " + type, mCm.getNetworkInfo(type)); + } + } } public void testGetAllNetworkInfo() { NetworkInfo[] ni = mCm.getAllNetworkInfo(); assertTrue(ni.length >= MIN_NUM_NETWORK_TYPES); + for (int type = 0; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) { + int desiredFoundCount = (isSupported(type) ? 1 : 0); + int foundCount = 0; + for (NetworkInfo i : ni) { + if (i.getType() == type) foundCount++; + } + assertTrue("Unexpected foundCount of " + foundCount + " for type " + type, + foundCount == desiredFoundCount); + } } public void testStartUsingNetworkFeature() { @@ -130,35 +207,46 @@ public class ConnectivityManagerTest extends AndroidTestCase { } } - public void testRequestRouteToHost() { - Set exceptionFreeTypes = new HashSet(); - exceptionFreeTypes.add(ConnectivityManager.TYPE_BLUETOOTH); - exceptionFreeTypes.add(ConnectivityManager.TYPE_ETHERNET); - exceptionFreeTypes.add(ConnectivityManager.TYPE_MOBILE); - exceptionFreeTypes.add(ConnectivityManager.TYPE_MOBILE_DUN); - exceptionFreeTypes.add(ConnectivityManager.TYPE_MOBILE_HIPRI); - exceptionFreeTypes.add(ConnectivityManager.TYPE_MOBILE_MMS); - exceptionFreeTypes.add(ConnectivityManager.TYPE_MOBILE_SUPL); + private boolean isSupported(int networkType) { + return mNetworks.containsKey(networkType); + } - NetworkInfo[] ni = mCm.getAllNetworkInfo(); - for (NetworkInfo n : ni) { - if (n.isConnected() && exceptionFreeTypes.contains(n.getType())) { - assertTrue("Network type: " + n.getType(), mCm.requestRouteToHost(n.getType(), - HOST_ADDRESS)); + // true if only the system can turn it on + private boolean isNetworkProtected(int networkType) { + return mProtectedNetworks.contains(networkType); + } + + public void testIsNetworkSupported() { + for (int type = -1; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) { + boolean supported = mCm.isNetworkSupported(type); + if (isSupported(type)) { + assertTrue(supported); + } else { + assertFalse(supported); } } + } + + public void testRequestRouteToHost() { + for (int type = -1 ; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) { + NetworkInfo ni = mCm.getNetworkInfo(type); + boolean expectToWork = isSupported(type) && !isNetworkProtected(type) && + ni != null && ni.isConnected(); + + try { + assertTrue("Network type " + type, + mCm.requestRouteToHost(type, HOST_ADDRESS) == expectToWork); + } catch (Exception e) { + Log.d(TAG, "got exception in requestRouteToHost for type " + type); + assertFalse("Exception received for type " + type, expectToWork); + } + + //TODO verify route table + } assertFalse(mCm.requestRouteToHost(-1, HOST_ADDRESS)); } - public void testGetActiveNetworkInfo() { - NetworkInfo ni = mCm.getActiveNetworkInfo(); - - if (ni != null) { - assertTrue(ni.getType() >= 0); - } - } - public void testTest() { mCm.getBackgroundDataSetting(); } @@ -197,12 +285,16 @@ public class ConnectivityManagerTest extends AndroidTestCase { assertTrue("Couldn't requestRouteToHost using HIPRI.", mCm.requestRouteToHost(ConnectivityManager.TYPE_MOBILE_HIPRI, HOST_ADDRESS)); - + // TODO check dns selection + // TODO check routes } catch (InterruptedException e) { fail("Broadcast receiver waiting for ConnectivityManager interrupted."); } finally { mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, FEATURE_ENABLE_HIPRI); + // TODO wait for HIPRI to go + // TODO check dns selection + // TODO check routes if (!isWifiConnected) { mWifiManager.setWifiEnabled(false); } From 9d24abdc7db2b70fae03a44e013ae02f06ba3daf Mon Sep 17 00:00:00 2001 From: Irfan Sheriff Date: Fri, 19 Apr 2013 10:47:42 -0700 Subject: [PATCH 0107/1109] EAP API CTS tests Bug: 8646305 Change-Id: Id5595ee0d1bfedae827df8c99516cd4e27d0a97a --- .../wifi/cts/WifiEnterpriseConfigTest.java | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java new file mode 100644 index 0000000000..58298d5f10 --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2013 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.wifi.cts; + +import android.content.Context; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiEnterpriseConfig; +import android.net.wifi.WifiEnterpriseConfig.Eap; +import android.net.wifi.WifiEnterpriseConfig.Phase2; +import android.net.wifi.WifiManager; +import android.test.AndroidTestCase; + +public class WifiEnterpriseConfigTest extends AndroidTestCase { + private WifiManager mWifiManager; + + private static final String SSID = "\"TestSSID\""; + private static final String IDENTITY = "identity"; + private static final String PASSWORD = "password"; + private static final String SUBJECT_MATCH = "subjectmatch"; + private static final String ANON_IDENTITY = "anonidentity"; + private static final int ENABLE_DELAY = 10000; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mWifiManager = (WifiManager) mContext + .getSystemService(Context.WIFI_SERVICE); + assertNotNull(mWifiManager); + mWifiManager.setWifiEnabled(true); + Thread.sleep(ENABLE_DELAY); + assertTrue(mWifiManager.isWifiEnabled()); + } + + public void testSettersAndGetters() { + WifiEnterpriseConfig config = new WifiEnterpriseConfig(); + assertTrue(config.getEapMethod() == Eap.NONE); + config.setEapMethod(Eap.PEAP); + assertTrue(config.getEapMethod() == Eap.PEAP); + config.setEapMethod(Eap.PWD); + assertTrue(config.getEapMethod() == Eap.PWD); + config.setEapMethod(Eap.TLS); + assertTrue(config.getEapMethod() == Eap.TLS); + config.setEapMethod(Eap.TTLS); + assertTrue(config.getEapMethod() == Eap.TTLS); + assertTrue(config.getPhase2Method() == Phase2.NONE); + config.setPhase2Method(Phase2.PAP); + assertTrue(config.getPhase2Method() == Phase2.PAP); + config.setPhase2Method(Phase2.MSCHAP); + assertTrue(config.getPhase2Method() == Phase2.MSCHAP); + config.setPhase2Method(Phase2.MSCHAPV2); + assertTrue(config.getPhase2Method() == Phase2.MSCHAPV2); + config.setPhase2Method(Phase2.GTC); + assertTrue(config.getPhase2Method() == Phase2.GTC); + config.setIdentity(IDENTITY); + assertTrue(config.getIdentity().equals(IDENTITY)); + config.setAnonymousIdentity(ANON_IDENTITY); + assertTrue(config.getAnonymousIdentity().equals(ANON_IDENTITY)); + config.setPassword(PASSWORD); + assertTrue(config.getPassword().equals(PASSWORD)); + config.setCaCertificate(null); + config.setClientKeyEntry(null, null); + config.setSubjectMatch(SUBJECT_MATCH); + assertTrue(config.getSubjectMatch().equals(SUBJECT_MATCH)); + } + + public void testAddEapNetwork() { + WifiConfiguration config = new WifiConfiguration(); + WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); + enterpriseConfig.setEapMethod(Eap.PWD); + enterpriseConfig.setIdentity(IDENTITY); + enterpriseConfig.setPassword(PASSWORD); + config.SSID = SSID; + config.enterpriseConfig = enterpriseConfig; + + int netId = mWifiManager.addNetwork(config); + assertTrue(doesSsidExist(SSID)); + mWifiManager.removeNetwork(netId); + assertFalse(doesSsidExist(SSID)); + } + + private boolean doesSsidExist(String ssid) { + for (final WifiConfiguration w : mWifiManager.getConfiguredNetworks()) { + if (w.SSID.equals(ssid)) + return true; + } + return false; + } +} From a47523d872cd4a07cf660692fabd38bd8abd505f Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Thu, 25 Apr 2013 12:55:58 -0700 Subject: [PATCH 0108/1109] Fix file permissions Java source files are not generally executable. Change-Id: I4fe45a3eb7bc136ba29dd6632bf9865f2f940bf3 --- tests/cts/net/src/android/net/http/cts/SslErrorTest.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 tests/cts/net/src/android/net/http/cts/SslErrorTest.java diff --git a/tests/cts/net/src/android/net/http/cts/SslErrorTest.java b/tests/cts/net/src/android/net/http/cts/SslErrorTest.java old mode 100755 new mode 100644 From fc0f6f4721bb6fbe3a938b58abd2e2e0cb2b8018 Mon Sep 17 00:00:00 2001 From: Robert Greenwalt Date: Thu, 25 Apr 2013 17:08:18 -0700 Subject: [PATCH 0109/1109] Add debug logging. Also fix timing issue with setNetworkPreference bug:8658717 Change-Id: Ifc6de4758a3d800a52f4e53cb4c6d2a4c6109390 --- .../net/cts/ConnectivityManagerTest.java | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index c24415901c..d4bff12a18 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -113,25 +113,30 @@ public class ConnectivityManagerTest extends AndroidTestCase { public void testSetNetworkPreference() { // verify swtiching between two default networks - need to connectable networks though // could use test and whatever the current active network is - NetworkInfo active = mCm.getActiveNetworkInfo(); int originalPref = mCm.getNetworkPreference(); int currentPref = originalPref; for (int type = -1; type <= ConnectivityManager.MAX_NETWORK_TYPE+1; type++) { mCm.setNetworkPreference(type); NetworkConfig c = mNetworks.get(type); boolean expectWorked = (c != null && c.isDefault()); - try { - Thread.currentThread().sleep(100); - } catch (InterruptedException e) {} - int foundType = mCm.getNetworkPreference(); + int totalSleep = 0; + int foundType = ConnectivityManager.TYPE_NONE; + while (totalSleep < 1000) { + try { + Thread.currentThread().sleep(100); + } catch (InterruptedException e) {} + totalSleep += 100; + foundType = mCm.getNetworkPreference(); + if (currentPref != foundType) break; + } if (expectWorked) { assertTrue("We should have been able to switch prefered type " + type, foundType == type); - currentPref = foundType; } else { assertTrue("We should not have been able to switch type " + type, - foundType == currentPref); + foundType != type); } + currentPref = foundType; } mCm.setNetworkPreference(originalPref); } @@ -171,6 +176,10 @@ public class ConnectivityManagerTest extends AndroidTestCase { for (NetworkInfo i : ni) { if (i.getType() == type) foundCount++; } + if (foundCount != desiredFoundCount) { + Log.e(TAG, "failure in testGetAllNetworkInfo. Dump of returned NetworkInfos:"); + for (NetworkInfo networkInfo : ni) Log.e(TAG, " " + networkInfo); + } assertTrue("Unexpected foundCount of " + foundCount + " for type " + type, foundCount == desiredFoundCount); } From e2b2f9f3900aabae17251d6eb41dccb1d7e03c08 Mon Sep 17 00:00:00 2001 From: Robert Greenwalt Date: Thu, 25 Apr 2013 17:08:18 -0700 Subject: [PATCH 0110/1109] Add debug logging. Also fix timing issue with setNetworkPreference bug:8658717 Change-Id: Ifc6de4758a3d800a52f4e53cb4c6d2a4c6109390 --- .../net/cts/ConnectivityManagerTest.java | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index c24415901c..d4bff12a18 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -113,25 +113,30 @@ public class ConnectivityManagerTest extends AndroidTestCase { public void testSetNetworkPreference() { // verify swtiching between two default networks - need to connectable networks though // could use test and whatever the current active network is - NetworkInfo active = mCm.getActiveNetworkInfo(); int originalPref = mCm.getNetworkPreference(); int currentPref = originalPref; for (int type = -1; type <= ConnectivityManager.MAX_NETWORK_TYPE+1; type++) { mCm.setNetworkPreference(type); NetworkConfig c = mNetworks.get(type); boolean expectWorked = (c != null && c.isDefault()); - try { - Thread.currentThread().sleep(100); - } catch (InterruptedException e) {} - int foundType = mCm.getNetworkPreference(); + int totalSleep = 0; + int foundType = ConnectivityManager.TYPE_NONE; + while (totalSleep < 1000) { + try { + Thread.currentThread().sleep(100); + } catch (InterruptedException e) {} + totalSleep += 100; + foundType = mCm.getNetworkPreference(); + if (currentPref != foundType) break; + } if (expectWorked) { assertTrue("We should have been able to switch prefered type " + type, foundType == type); - currentPref = foundType; } else { assertTrue("We should not have been able to switch type " + type, - foundType == currentPref); + foundType != type); } + currentPref = foundType; } mCm.setNetworkPreference(originalPref); } @@ -171,6 +176,10 @@ public class ConnectivityManagerTest extends AndroidTestCase { for (NetworkInfo i : ni) { if (i.getType() == type) foundCount++; } + if (foundCount != desiredFoundCount) { + Log.e(TAG, "failure in testGetAllNetworkInfo. Dump of returned NetworkInfos:"); + for (NetworkInfo networkInfo : ni) Log.e(TAG, " " + networkInfo); + } assertTrue("Unexpected foundCount of " + foundCount + " for type " + type, foundCount == desiredFoundCount); } From 69f9447ac9d12cda32307ea987fab8080cff93e5 Mon Sep 17 00:00:00 2001 From: Robert Greenwalt Date: Mon, 20 May 2013 10:32:34 -0700 Subject: [PATCH 0111/1109] DO NOT MERGE - remove dns test from MR2 bug:8658901 Change-Id: I979f38545d7bde91e3711d09ba4278e02183a05b --- .../cts/net/src/android/net/cts/DnsTest.java | 237 ------------------ 1 file changed, 237 deletions(-) delete mode 100644 tests/cts/net/src/android/net/cts/DnsTest.java diff --git a/tests/cts/net/src/android/net/cts/DnsTest.java b/tests/cts/net/src/android/net/cts/DnsTest.java deleted file mode 100644 index cdd95aa077..0000000000 --- a/tests/cts/net/src/android/net/cts/DnsTest.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (C) 2013 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.os.SystemClock; -import android.test.AndroidTestCase; -import android.util.Log; - -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; - -public class DnsTest extends AndroidTestCase { - - static { - System.loadLibrary("nativedns_jni"); - } - - private static final boolean DBG = false; - private static final String TAG = "DnsTest"; - - /** - * @return true on success - */ - private static native boolean testNativeDns(); - - /** - * Verify: - * DNS works - forwards and backwards, giving ipv4 and ipv6 - * Test that DNS work on v4 and v6 networks - * Test Native dns calls (4) - * Todo: - * Cache is flushed when we change networks - * have per-network caches - * No cache when there's no network - * Perf - measure size of first and second tier caches and their effect - * Assert requires network permission - */ - public void testDnsWorks() { - InetAddress addrs[] = {}; - try { - addrs = InetAddress.getAllByName("www.google.com"); - } catch (UnknownHostException e) {} - assertTrue(addrs.length != 0); - boolean foundV4 = false, foundV6 = false; - for (InetAddress addr : addrs) { - if (addr instanceof Inet4Address) foundV4 = true; - else if (addr instanceof Inet6Address) foundV6 = true; - if (DBG) Log.e(TAG, "www.google.com gave " + addr.toString()); - } - assertTrue(foundV4); - assertTrue(foundV6); - try { - addrs = InetAddress.getAllByName("ipv6.google.com"); - } catch (UnknownHostException e) {} - assertTrue(addrs.length != 0); - foundV4 = false; - foundV6 = false; - for (InetAddress addr : addrs) { - if (addr instanceof Inet4Address) foundV4 = true; - else if (addr instanceof Inet6Address) foundV6 = true; - if (DBG) Log.e(TAG, "ipv6.google.com gave " + addr.toString()); - } - assertTrue(foundV4 == false); - assertTrue(foundV6 == true); - assertTrue(testNativeDns()); - } - - private static final String[] URLS = { "www.google.com", "ipv6.google.com", "www.yahoo.com", - "facebook.com", "youtube.com", "blogspot.com", "baidu.com", "wikipedia.org", -// live.com fails rev lookup. - "twitter.com", "qq.com", "msn.com", "yahoo.co.jp", "linkedin.com", - "taobao.com", "google.co.in", "sina.com.cn", "amazon.com", "wordpress.com", - "google.co.uk", "ebay.com", "yandex.ru", "163.com", "google.co.jp", "google.fr", - "microsoft.com", "paypal.com", "google.com.br", "flickr.com", - "mail.ru", "craigslist.org", "fc2.com", "google.it", -// "apple.com", fails rev lookup - "google.es", - "imdb.com", "google.ru", "soho.com", "bbc.co.uk", "vkontakte.ru", "ask.com", - "tumblr.com", "weibo.com", "go.com", "xvideos.com", "livejasmin.com", "cnn.com", - "youku.com", "blogspot.com", "soso.com", "google.ca", "aol.com", "tudou.com", - "xhamster.com", "megaupload.com", "ifeng.com", "zedo.com", "mediafire.com", "ameblo.jp", - "pornhub.com", "google.co.id", "godaddy.com", "adobe.com", "rakuten.co.jp", "about.com", - "espn.go.com", "4shared.com", "alibaba.com","ebay.de", "yieldmanager.com", - "wordpress.org", "livejournal.com", "google.com.tr", "google.com.mx", "renren.com", - "livedoor.com", "google.com.au", "youporn.com", "uol.com.br", "cnet.com", "conduit.com", - "google.pl", "myspace.com", "nytimes.com", "ebay.co.uk", "chinaz.com", "hao123.com", - "thepiratebay.org", "doubleclick.com", "alipay.com", "netflix.com", "cnzz.com", - "huffingtonpost.com", "twitpic.com", "weather.com", "babylon.com", "amazon.de", - "dailymotion.com", "orkut.com", "orkut.com.br", "google.com.sa", "odnoklassniki.ru", - "amazon.co.jp", "google.nl", "goo.ne.jp", "stumbleupon.com", "tube8.com", "tmall.com", - "imgur.com", "globo.com", "secureserver.net", "fileserve.com", "tianya.cn", "badoo.com", - "ehow.com", "photobucket.com", "imageshack.us", "xnxx.com", "deviantart.com", - "filestube.com", "addthis.com", "douban.com", "vimeo.com", "sogou.com", - "stackoverflow.com", "reddit.com", "dailymail.co.uk", "redtube.com", "megavideo.com", - "taringa.net", "pengyou.com", "amazon.co.uk", "fbcdn.net", "aweber.com", "spiegel.de", - "rapidshare.com", "mixi.jp", "360buy.com", "google.cn", "digg.com", "answers.com", - "bit.ly", "indiatimes.com", "skype.com", "yfrog.com", "optmd.com", "google.com.eg", - "google.com.pk", "58.com", "hotfile.com", "google.co.th", - "bankofamerica.com", "sourceforge.net", "maktoob.com", "warriorforum.com", "rediff.com", - "google.co.za", "56.com", "torrentz.eu", "clicksor.com", "avg.com", - "download.com", "ku6.com", "statcounter.com", "foxnews.com", "google.com.ar", - "nicovideo.jp", "reference.com", "liveinternet.ru", "ucoz.ru", "xinhuanet.com", - "xtendmedia.com", "naver.com", "youjizz.com", "domaintools.com", "sparkstudios.com", - "rambler.ru", "scribd.com", "kaixin001.com", "mashable.com", "adultfirendfinder.com", - "files.wordpress.com", "guardian.co.uk", "bild.de", "yelp.com", "wikimedia.org", - "chase.com", "onet.pl", "ameba.jp", "pconline.com.cn", "free.fr", "etsy.com", - "typepad.com", "youdao.com", "megaclick.com", "digitalpoint.com", "blogfa.com", - "salesforce.com", "adf.ly", "ganji.com", "wikia.com", "archive.org", "terra.com.br", - "w3schools.com", "ezinearticles.com", "wjs.com", "google.com.my", "clickbank.com", - "squidoo.com", "hulu.com", "repubblica.it", "google.be", "allegro.pl", "comcast.net", - "narod.ru", "zol.com.cn", "orange.fr", "soufun.com", "hatena.ne.jp", "google.gr", - "in.com", "techcrunch.com", "orkut.co.in", "xunlei.com", - "reuters.com", "google.com.vn", "hostgator.com", "kaskus.us", "espncricinfo.com", - "hootsuite.com", "qiyi.com", "gmx.net", "xing.com", "php.net", "soku.com", "web.de", - "libero.it", "groupon.com", "51.la", "slideshare.net", "booking.com", "seesaa.net", - "126.com", "telegraph.co.uk", "wretch.cc", "twimg.com", "rutracker.org", "angege.com", - "nba.com", "dell.com", "leboncoin.fr", "people.com", "google.com.tw", "walmart.com", - "daum.net", "2ch.net", "constantcontact.com", "nifty.com", "mywebsearch.com", - "tripadvisor.com", "google.se", "paipai.com", "google.com.ua", "ning.com", "hp.com", - "google.at", "joomla.org", "icio.us", "hudong.com", "csdn.net", "getfirebug.com", - "ups.com", "cj.com", "google.ch", "camzap.com", "wordreference.com", "tagged.com", - "wp.pl", "mozilla.com", "google.ru", "usps.com", "china.com", "themeforest.net", - "search-results.com", "tribalfusion.com", "thefreedictionary.com", "isohunt.com", - "linkwithin.com", "cam4.com", "plentyoffish.com", "wellsfargo.com", "metacafe.com", - "depositfiles.com", "freelancer.com", "opendns.com", "homeway.com", "engadget.com", - "10086.cn", "360.cn", "marca.com", "dropbox.com", "ign.com", "match.com", "google.pt", - "facemoods.com", "hardsextube.com", "google.com.ph", "lockerz.com", "istockphoto.com", - "partypoker.com", "netlog.com", "outbrain.com", "elpais.com", "fiverr.com", - "biglobe.ne.jp", "corriere.it", "love21cn.com", "yesky.com", "spankwire.com", - "ig.com.br", "imagevenue.com", "hubpages.com", "google.co.ve"}; - -// TODO - this works, but is slow and cts doesn't do anything with the result. -// Maybe require a min performance, a min cache size (detectable) and/or move -// to perf testing - private static final int LOOKUP_COUNT_GOAL = URLS.length; - public void skiptestDnsPerf() { - ArrayList results = new ArrayList(); - int failures = 0; - try { - for (int numberOfUrls = URLS.length; numberOfUrls > 0; numberOfUrls--) { - failures = 0; - int iterationLimit = LOOKUP_COUNT_GOAL / numberOfUrls; - long startTime = SystemClock.elapsedRealtimeNanos(); - for (int iteration = 0; iteration < iterationLimit; iteration++) { - for (int urlIndex = 0; urlIndex < numberOfUrls; urlIndex++) { - try { - InetAddress addr = InetAddress.getByName(URLS[urlIndex]); - } catch (UnknownHostException e) { - Log.e(TAG, "failed first lookup of " + URLS[urlIndex]); - failures++; - try { - InetAddress addr = InetAddress.getByName(URLS[urlIndex]); - } catch (UnknownHostException ee) { - failures++; - Log.e(TAG, "failed SECOND lookup of " + URLS[urlIndex]); - } - } - } - } - long endTime = SystemClock.elapsedRealtimeNanos(); - float nsPer = ((float)(endTime-startTime) / iterationLimit) / numberOfUrls/ 1000; - String thisResult = new String("getByName for " + numberOfUrls + " took " + - (endTime - startTime)/1000 + "(" + nsPer + ") with " + - failures + " failures\n"); - Log.d(TAG, thisResult); - results.add(thisResult); - } - // build up a list of addresses - ArrayList addressList = new ArrayList(); - for (String url : URLS) { - try { - InetAddress addr = InetAddress.getByName(url); - addressList.add(addr.getAddress()); - } catch (UnknownHostException e) { - Log.e(TAG, "Exception making reverseDNS list: " + e.toString()); - } - } - for (int numberOfAddrs = addressList.size(); numberOfAddrs > 0; numberOfAddrs--) { - int iterationLimit = LOOKUP_COUNT_GOAL / numberOfAddrs; - failures = 0; - long startTime = SystemClock.elapsedRealtimeNanos(); - for (int iteration = 0; iteration < iterationLimit; iteration++) { - for (int addrIndex = 0; addrIndex < numberOfAddrs; addrIndex++) { - try { - InetAddress addr = InetAddress.getByAddress(addressList.get(addrIndex)); - String hostname = addr.getHostName(); - } catch (UnknownHostException e) { - failures++; - Log.e(TAG, "Failure doing reverse DNS lookup: " + e.toString()); - try { - InetAddress addr = - InetAddress.getByAddress(addressList.get(addrIndex)); - String hostname = addr.getHostName(); - - } catch (UnknownHostException ee) { - failures++; - Log.e(TAG, "Failure doing SECOND reverse DNS lookup: " + - ee.toString()); - } - } - } - } - long endTime = SystemClock.elapsedRealtimeNanos(); - float nsPer = ((endTime-startTime) / iterationLimit) / numberOfAddrs / 1000; - String thisResult = new String("getHostName for " + numberOfAddrs + " took " + - (endTime - startTime)/1000 + "(" + nsPer + ") with " + - failures + " failures\n"); - Log.d(TAG, thisResult); - results.add(thisResult); - } - for (String result : results) Log.d(TAG, result); - - InetAddress exit = InetAddress.getByName("exitrightnow.com"); - Log.e(TAG, " exit address= "+exit.toString()); - - } catch (Exception e) { - Log.e(TAG, "bad URL in testDnsPerf: " + e.toString()); - } - } -} From ff53e104b1dc85f380551a5d5698b0a165cd2233 Mon Sep 17 00:00:00 2001 From: Robert Greenwalt Date: Mon, 20 May 2013 10:32:34 -0700 Subject: [PATCH 0112/1109] DO NOT MERGE - remove dns test from MR2 bug:8658901 Change-Id: I979f38545d7bde91e3711d09ba4278e02183a05b --- .../cts/net/src/android/net/cts/DnsTest.java | 237 ------------------ 1 file changed, 237 deletions(-) delete mode 100644 tests/cts/net/src/android/net/cts/DnsTest.java diff --git a/tests/cts/net/src/android/net/cts/DnsTest.java b/tests/cts/net/src/android/net/cts/DnsTest.java deleted file mode 100644 index cdd95aa077..0000000000 --- a/tests/cts/net/src/android/net/cts/DnsTest.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (C) 2013 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.os.SystemClock; -import android.test.AndroidTestCase; -import android.util.Log; - -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; - -public class DnsTest extends AndroidTestCase { - - static { - System.loadLibrary("nativedns_jni"); - } - - private static final boolean DBG = false; - private static final String TAG = "DnsTest"; - - /** - * @return true on success - */ - private static native boolean testNativeDns(); - - /** - * Verify: - * DNS works - forwards and backwards, giving ipv4 and ipv6 - * Test that DNS work on v4 and v6 networks - * Test Native dns calls (4) - * Todo: - * Cache is flushed when we change networks - * have per-network caches - * No cache when there's no network - * Perf - measure size of first and second tier caches and their effect - * Assert requires network permission - */ - public void testDnsWorks() { - InetAddress addrs[] = {}; - try { - addrs = InetAddress.getAllByName("www.google.com"); - } catch (UnknownHostException e) {} - assertTrue(addrs.length != 0); - boolean foundV4 = false, foundV6 = false; - for (InetAddress addr : addrs) { - if (addr instanceof Inet4Address) foundV4 = true; - else if (addr instanceof Inet6Address) foundV6 = true; - if (DBG) Log.e(TAG, "www.google.com gave " + addr.toString()); - } - assertTrue(foundV4); - assertTrue(foundV6); - try { - addrs = InetAddress.getAllByName("ipv6.google.com"); - } catch (UnknownHostException e) {} - assertTrue(addrs.length != 0); - foundV4 = false; - foundV6 = false; - for (InetAddress addr : addrs) { - if (addr instanceof Inet4Address) foundV4 = true; - else if (addr instanceof Inet6Address) foundV6 = true; - if (DBG) Log.e(TAG, "ipv6.google.com gave " + addr.toString()); - } - assertTrue(foundV4 == false); - assertTrue(foundV6 == true); - assertTrue(testNativeDns()); - } - - private static final String[] URLS = { "www.google.com", "ipv6.google.com", "www.yahoo.com", - "facebook.com", "youtube.com", "blogspot.com", "baidu.com", "wikipedia.org", -// live.com fails rev lookup. - "twitter.com", "qq.com", "msn.com", "yahoo.co.jp", "linkedin.com", - "taobao.com", "google.co.in", "sina.com.cn", "amazon.com", "wordpress.com", - "google.co.uk", "ebay.com", "yandex.ru", "163.com", "google.co.jp", "google.fr", - "microsoft.com", "paypal.com", "google.com.br", "flickr.com", - "mail.ru", "craigslist.org", "fc2.com", "google.it", -// "apple.com", fails rev lookup - "google.es", - "imdb.com", "google.ru", "soho.com", "bbc.co.uk", "vkontakte.ru", "ask.com", - "tumblr.com", "weibo.com", "go.com", "xvideos.com", "livejasmin.com", "cnn.com", - "youku.com", "blogspot.com", "soso.com", "google.ca", "aol.com", "tudou.com", - "xhamster.com", "megaupload.com", "ifeng.com", "zedo.com", "mediafire.com", "ameblo.jp", - "pornhub.com", "google.co.id", "godaddy.com", "adobe.com", "rakuten.co.jp", "about.com", - "espn.go.com", "4shared.com", "alibaba.com","ebay.de", "yieldmanager.com", - "wordpress.org", "livejournal.com", "google.com.tr", "google.com.mx", "renren.com", - "livedoor.com", "google.com.au", "youporn.com", "uol.com.br", "cnet.com", "conduit.com", - "google.pl", "myspace.com", "nytimes.com", "ebay.co.uk", "chinaz.com", "hao123.com", - "thepiratebay.org", "doubleclick.com", "alipay.com", "netflix.com", "cnzz.com", - "huffingtonpost.com", "twitpic.com", "weather.com", "babylon.com", "amazon.de", - "dailymotion.com", "orkut.com", "orkut.com.br", "google.com.sa", "odnoklassniki.ru", - "amazon.co.jp", "google.nl", "goo.ne.jp", "stumbleupon.com", "tube8.com", "tmall.com", - "imgur.com", "globo.com", "secureserver.net", "fileserve.com", "tianya.cn", "badoo.com", - "ehow.com", "photobucket.com", "imageshack.us", "xnxx.com", "deviantart.com", - "filestube.com", "addthis.com", "douban.com", "vimeo.com", "sogou.com", - "stackoverflow.com", "reddit.com", "dailymail.co.uk", "redtube.com", "megavideo.com", - "taringa.net", "pengyou.com", "amazon.co.uk", "fbcdn.net", "aweber.com", "spiegel.de", - "rapidshare.com", "mixi.jp", "360buy.com", "google.cn", "digg.com", "answers.com", - "bit.ly", "indiatimes.com", "skype.com", "yfrog.com", "optmd.com", "google.com.eg", - "google.com.pk", "58.com", "hotfile.com", "google.co.th", - "bankofamerica.com", "sourceforge.net", "maktoob.com", "warriorforum.com", "rediff.com", - "google.co.za", "56.com", "torrentz.eu", "clicksor.com", "avg.com", - "download.com", "ku6.com", "statcounter.com", "foxnews.com", "google.com.ar", - "nicovideo.jp", "reference.com", "liveinternet.ru", "ucoz.ru", "xinhuanet.com", - "xtendmedia.com", "naver.com", "youjizz.com", "domaintools.com", "sparkstudios.com", - "rambler.ru", "scribd.com", "kaixin001.com", "mashable.com", "adultfirendfinder.com", - "files.wordpress.com", "guardian.co.uk", "bild.de", "yelp.com", "wikimedia.org", - "chase.com", "onet.pl", "ameba.jp", "pconline.com.cn", "free.fr", "etsy.com", - "typepad.com", "youdao.com", "megaclick.com", "digitalpoint.com", "blogfa.com", - "salesforce.com", "adf.ly", "ganji.com", "wikia.com", "archive.org", "terra.com.br", - "w3schools.com", "ezinearticles.com", "wjs.com", "google.com.my", "clickbank.com", - "squidoo.com", "hulu.com", "repubblica.it", "google.be", "allegro.pl", "comcast.net", - "narod.ru", "zol.com.cn", "orange.fr", "soufun.com", "hatena.ne.jp", "google.gr", - "in.com", "techcrunch.com", "orkut.co.in", "xunlei.com", - "reuters.com", "google.com.vn", "hostgator.com", "kaskus.us", "espncricinfo.com", - "hootsuite.com", "qiyi.com", "gmx.net", "xing.com", "php.net", "soku.com", "web.de", - "libero.it", "groupon.com", "51.la", "slideshare.net", "booking.com", "seesaa.net", - "126.com", "telegraph.co.uk", "wretch.cc", "twimg.com", "rutracker.org", "angege.com", - "nba.com", "dell.com", "leboncoin.fr", "people.com", "google.com.tw", "walmart.com", - "daum.net", "2ch.net", "constantcontact.com", "nifty.com", "mywebsearch.com", - "tripadvisor.com", "google.se", "paipai.com", "google.com.ua", "ning.com", "hp.com", - "google.at", "joomla.org", "icio.us", "hudong.com", "csdn.net", "getfirebug.com", - "ups.com", "cj.com", "google.ch", "camzap.com", "wordreference.com", "tagged.com", - "wp.pl", "mozilla.com", "google.ru", "usps.com", "china.com", "themeforest.net", - "search-results.com", "tribalfusion.com", "thefreedictionary.com", "isohunt.com", - "linkwithin.com", "cam4.com", "plentyoffish.com", "wellsfargo.com", "metacafe.com", - "depositfiles.com", "freelancer.com", "opendns.com", "homeway.com", "engadget.com", - "10086.cn", "360.cn", "marca.com", "dropbox.com", "ign.com", "match.com", "google.pt", - "facemoods.com", "hardsextube.com", "google.com.ph", "lockerz.com", "istockphoto.com", - "partypoker.com", "netlog.com", "outbrain.com", "elpais.com", "fiverr.com", - "biglobe.ne.jp", "corriere.it", "love21cn.com", "yesky.com", "spankwire.com", - "ig.com.br", "imagevenue.com", "hubpages.com", "google.co.ve"}; - -// TODO - this works, but is slow and cts doesn't do anything with the result. -// Maybe require a min performance, a min cache size (detectable) and/or move -// to perf testing - private static final int LOOKUP_COUNT_GOAL = URLS.length; - public void skiptestDnsPerf() { - ArrayList results = new ArrayList(); - int failures = 0; - try { - for (int numberOfUrls = URLS.length; numberOfUrls > 0; numberOfUrls--) { - failures = 0; - int iterationLimit = LOOKUP_COUNT_GOAL / numberOfUrls; - long startTime = SystemClock.elapsedRealtimeNanos(); - for (int iteration = 0; iteration < iterationLimit; iteration++) { - for (int urlIndex = 0; urlIndex < numberOfUrls; urlIndex++) { - try { - InetAddress addr = InetAddress.getByName(URLS[urlIndex]); - } catch (UnknownHostException e) { - Log.e(TAG, "failed first lookup of " + URLS[urlIndex]); - failures++; - try { - InetAddress addr = InetAddress.getByName(URLS[urlIndex]); - } catch (UnknownHostException ee) { - failures++; - Log.e(TAG, "failed SECOND lookup of " + URLS[urlIndex]); - } - } - } - } - long endTime = SystemClock.elapsedRealtimeNanos(); - float nsPer = ((float)(endTime-startTime) / iterationLimit) / numberOfUrls/ 1000; - String thisResult = new String("getByName for " + numberOfUrls + " took " + - (endTime - startTime)/1000 + "(" + nsPer + ") with " + - failures + " failures\n"); - Log.d(TAG, thisResult); - results.add(thisResult); - } - // build up a list of addresses - ArrayList addressList = new ArrayList(); - for (String url : URLS) { - try { - InetAddress addr = InetAddress.getByName(url); - addressList.add(addr.getAddress()); - } catch (UnknownHostException e) { - Log.e(TAG, "Exception making reverseDNS list: " + e.toString()); - } - } - for (int numberOfAddrs = addressList.size(); numberOfAddrs > 0; numberOfAddrs--) { - int iterationLimit = LOOKUP_COUNT_GOAL / numberOfAddrs; - failures = 0; - long startTime = SystemClock.elapsedRealtimeNanos(); - for (int iteration = 0; iteration < iterationLimit; iteration++) { - for (int addrIndex = 0; addrIndex < numberOfAddrs; addrIndex++) { - try { - InetAddress addr = InetAddress.getByAddress(addressList.get(addrIndex)); - String hostname = addr.getHostName(); - } catch (UnknownHostException e) { - failures++; - Log.e(TAG, "Failure doing reverse DNS lookup: " + e.toString()); - try { - InetAddress addr = - InetAddress.getByAddress(addressList.get(addrIndex)); - String hostname = addr.getHostName(); - - } catch (UnknownHostException ee) { - failures++; - Log.e(TAG, "Failure doing SECOND reverse DNS lookup: " + - ee.toString()); - } - } - } - } - long endTime = SystemClock.elapsedRealtimeNanos(); - float nsPer = ((endTime-startTime) / iterationLimit) / numberOfAddrs / 1000; - String thisResult = new String("getHostName for " + numberOfAddrs + " took " + - (endTime - startTime)/1000 + "(" + nsPer + ") with " + - failures + " failures\n"); - Log.d(TAG, thisResult); - results.add(thisResult); - } - for (String result : results) Log.d(TAG, result); - - InetAddress exit = InetAddress.getByName("exitrightnow.com"); - Log.e(TAG, " exit address= "+exit.toString()); - - } catch (Exception e) { - Log.e(TAG, "bad URL in testDnsPerf: " + e.toString()); - } - } -} From c8ddd2d7809b9ee490444193bb0b919c1b6bdc4c Mon Sep 17 00:00:00 2001 From: Robert Greenwalt Date: Thu, 27 Jun 2013 11:28:11 -0700 Subject: [PATCH 0113/1109] Fix CTS test for scan-always-available env Even if you disable wifi the supplicant will still be pingable if we're set in always scanning mode. Make the test aware. bug:9545987 Change-Id: I7f1bd0166b877a706de51f8ef169355c98ae25a3 --- tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 283f63b5d4..2580dbee9f 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -233,7 +233,7 @@ public class WifiManagerTest extends AndroidTestCase { startScan(); setWifiEnabled(false); Thread.sleep(DURATION); - assertFalse(mWifiManager.pingSupplicant()); + assertTrue(mWifiManager.pingSupplicant() == mWifiManager.isScanAlwaysAvailable()); final String TAG = "Test"; assertNotNull(mWifiManager.createWifiLock(TAG)); assertNotNull(mWifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, TAG)); From 4fd65d09bc6c77bd6157d3c92bd889f5cac49bd2 Mon Sep 17 00:00:00 2001 From: Vinit Deshapnde Date: Tue, 23 Jul 2013 16:04:58 -0700 Subject: [PATCH 0114/1109] Add a CTS test for NSD manager API A simple test that registers, discovers and then resolves a service. Bug: 9574276 Change-Id: I685df3c02112cf79b11b2c97efd560dda7232fda --- .../android/net/wifi/cts/NsdManagerTest.java | 424 ++++++++++++++++++ 1 file changed, 424 insertions(+) create mode 100644 tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java diff --git a/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java new file mode 100644 index 0000000000..482a4e39a6 --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java @@ -0,0 +1,424 @@ +/* + * Copyright (C) 2012 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.wifi.cts; + +import android.content.Context; +import android.net.nsd.NsdManager; +import android.net.nsd.NsdServiceInfo; +import android.test.AndroidTestCase; +import android.util.Log; + +import java.io.IOException; +import java.net.ServerSocket; +import java.util.Random; +import java.util.List; +import java.util.ArrayList; + +public class NsdManagerTest extends AndroidTestCase { + + private static final String TAG = "NsdManagerTest"; + private static final String SERVICE_TYPE = "_nmt._tcp"; + private static final int TIMEOUT = 2000; + + private static final boolean DBG = false; + + NsdManager mNsdManager; + + NsdManager.RegistrationListener mRegistrationListener; + NsdManager.DiscoveryListener mDiscoveryListener; + NsdManager.ResolveListener mResolveListener; + + public NsdManagerTest() { + mRegistrationListener = new NsdManager.RegistrationListener() { + @Override + public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) { + setEvent("onRegistrationFailed", errorCode); + } + + @Override + public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) { + setEvent("onUnregistrationFailed", errorCode); + } + + @Override + public void onServiceRegistered(NsdServiceInfo serviceInfo) { + setEvent("onServiceRegistered", serviceInfo); + } + + @Override + public void onServiceUnregistered(NsdServiceInfo serviceInfo) { + setEvent("onServiceUnregistered", serviceInfo); + } + }; + mDiscoveryListener = new NsdManager.DiscoveryListener() { + @Override + public void onStartDiscoveryFailed(String serviceType, int errorCode) { + setEvent("onStartDiscoveryFailed", errorCode); + } + + @Override + public void onStopDiscoveryFailed(String serviceType, int errorCode) { + setEvent("onStopDiscoveryFailed", errorCode); + } + + @Override + public void onDiscoveryStarted(String serviceType) { + NsdServiceInfo info = new NsdServiceInfo(); + info.setServiceType(serviceType); + setEvent("onDiscoveryStarted", info); + } + + @Override + public void onDiscoveryStopped(String serviceType) { + NsdServiceInfo info = new NsdServiceInfo(); + info.setServiceType(serviceType); + setEvent("onDiscoveryStopped", info); + } + + @Override + public void onServiceFound(NsdServiceInfo serviceInfo) { + setEvent("onServiceFound", serviceInfo); + } + + @Override + public void onServiceLost(NsdServiceInfo serviceInfo) { + setEvent("onServiceLost", serviceInfo); + } + }; + mResolveListener = new NsdManager.ResolveListener() { + @Override + public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { + setEvent("onResolveFailed", errorCode); + } + + @Override + public void onServiceResolved(NsdServiceInfo serviceInfo) { + setEvent("onServiceResolved", serviceInfo); + } + }; + } + + private final class EventData { + EventData(String callbackName, NsdServiceInfo info) { + mCallbackName = callbackName; + mSucceeded = true; + mErrorCode = 0; + mInfo = info; + } + EventData(String callbackName, int errorCode) { + mCallbackName = callbackName; + mSucceeded = false; + mErrorCode = errorCode; + mInfo = null; + } + private final String mCallbackName; + private final boolean mSucceeded; + private final int mErrorCode; + private final NsdServiceInfo mInfo; + } + + private final List mEventCache = new ArrayList(); + + private void setEvent(String callbackName, int errorCode) { + if (DBG) Log.d(TAG, callbackName + " failed with " + String.valueOf(errorCode)); + EventData eventData = new EventData(callbackName, errorCode); + synchronized (mEventCache) { + mEventCache.add(eventData); + mEventCache.notify(); + } + } + + private void setEvent(String callbackName, NsdServiceInfo info) { + if (DBG) Log.d(TAG, "Received event " + callbackName + " for " + info.getServiceName()); + EventData eventData = new EventData(callbackName, info); + synchronized (mEventCache) { + mEventCache.add(eventData); + mEventCache.notify(); + } + } + + void clearEventCache() { + synchronized(mEventCache) { + mEventCache.clear(); + } + } + + int eventCacheSize() { + synchronized(mEventCache) { + return mEventCache.size(); + } + } + + private int mWaitId = 0; + private EventData waitForCallback(String callbackName) { + + synchronized(mEventCache) { + + mWaitId ++; + if (DBG) Log.d(TAG, "Waiting for " + callbackName + ", id=" + String.valueOf(mWaitId)); + + try { + long startTime = android.os.SystemClock.uptimeMillis(); + long elapsedTime = 0; + int index = 0; + while (elapsedTime < TIMEOUT ) { + // first check if we've received that event + for (; index < mEventCache.size(); index++) { + EventData e = mEventCache.get(index); + if (e.mCallbackName.equals(callbackName)) { + if (DBG) Log.d(TAG, "exiting wait id=" + String.valueOf(mWaitId)); + return e; + } + } + + // Not yet received, just wait + mEventCache.wait(TIMEOUT - elapsedTime); + elapsedTime = android.os.SystemClock.uptimeMillis() - startTime; + } + // we exited the loop because of TIMEOUT; fail the call + if (DBG) Log.d(TAG, "timed out waiting id=" + String.valueOf(mWaitId)); + return null; + } catch (InterruptedException e) { + return null; // wait timed out! + } + } + } + + private String mServiceName; + + @Override + public void setUp() { + if (DBG) Log.d(TAG, "Setup test ..."); + mNsdManager = (NsdManager) getContext().getSystemService(Context.NSD_SERVICE); + + Random rand = new Random(); + mServiceName = new String("NsdTest"); + for (int i = 0; i < 4; i++) { + mServiceName = mServiceName + String.valueOf(rand.nextInt(10)); + } + } + + @Override + public void tearDown() { + if (DBG) Log.d(TAG, "Tear down test ..."); + } + + public void runTest() throws Exception { + NsdServiceInfo si = new NsdServiceInfo(); + si.setServiceType(SERVICE_TYPE); + si.setServiceName(mServiceName); + + EventData lastEvent = null; + + if (DBG) Log.d(TAG, "Starting test ..."); + + ServerSocket socket; + int localPort; + + try { + socket = new ServerSocket(0); + localPort = socket.getLocalPort(); + si.setPort(localPort); + } catch (IOException e) { + if (DBG) Log.d(TAG, "Could not open a local socket"); + assertTrue(false); + return; + } + + if (DBG) Log.d(TAG, "Port = " + String.valueOf(localPort)); + + clearEventCache(); + + mNsdManager.registerService(si, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener); + lastEvent = waitForCallback("onServiceRegistered"); // id = 1 + assertTrue(lastEvent != null); + assertTrue(lastEvent.mSucceeded); + assertTrue(eventCacheSize() == 1); + + // We may not always get the name that we tried to register; + // This events tells us the name that was registered. + String registeredName = lastEvent.mInfo.getServiceName(); + si.setServiceName(registeredName); + + clearEventCache(); + + mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, + mDiscoveryListener); + + // Expect discovery started + lastEvent = waitForCallback("onDiscoveryStarted"); // id = 2 + + assertTrue(lastEvent != null); + assertTrue(lastEvent.mSucceeded); + + // Remove this event, so accounting becomes easier later + mEventCache.remove(lastEvent); + + // Expect a service record to be discovered (and filter the ones + // that are unrelated to this test) + boolean found = false; + for (int i = 0; i < 32; i++) { + + lastEvent = waitForCallback("onServiceFound"); // id = 3 + if (lastEvent == null) { + // no more onServiceFound events are being reported! + break; + } + + assertTrue(lastEvent.mSucceeded); + + if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": ServiceName = " + + lastEvent.mInfo.getServiceName()); + + if (lastEvent.mInfo.getServiceName().equals(registeredName)) { + // Save it, as it will get overwritten with new serviceFound events + si = lastEvent.mInfo; + found = true; + } + + // Remove this event from the event cache, so it won't be found by subsequent + // calls to waitForCallback + mEventCache.remove(lastEvent); + } + + assertTrue(found); + + // We've removed all serviceFound events, and we've removed the discoveryStarted + // event as well, so now the event cache should be empty! + assertTrue(eventCacheSize() == 0); + + // Resolve the service + clearEventCache(); + mNsdManager.resolveService(si, mResolveListener); + lastEvent = waitForCallback("onServiceResolved"); // id = 4 + + assertTrue(lastEvent != null); + assertTrue(lastEvent.mSucceeded); + + if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": Port = " + + String.valueOf(lastEvent.mInfo.getPort())); + + assertTrue(lastEvent.mInfo.getPort() == localPort); + assertTrue(eventCacheSize() == 1); + + clearEventCache(); + + // Unregister the service + mNsdManager.unregisterService(mRegistrationListener); + lastEvent = waitForCallback("onServiceUnregistered"); // id = 5 + + assertTrue(lastEvent != null); + assertTrue(lastEvent.mSucceeded); + + // Expect a callback for service lost + lastEvent = waitForCallback("onServiceLost"); // id = 6 + + assertTrue(lastEvent != null); + assertTrue(lastEvent.mInfo.getServiceName().equals(registeredName)); + + assertTrue(eventCacheSize() == 2); + + // Register service again to see if we discover it + clearEventCache(); + + si = new NsdServiceInfo(); + si.setServiceType(SERVICE_TYPE); + si.setServiceName(mServiceName); + si.setPort(localPort); + mNsdManager.registerService(si, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener); + + lastEvent = waitForCallback("onServiceRegistered"); // id = 7 + + assertTrue(lastEvent != null); + assertTrue(lastEvent.mSucceeded); + + registeredName = lastEvent.mInfo.getServiceName(); + + // Expect a record to be discovered + lastEvent = waitForCallback("onServiceFound"); // id = 8 + + assertTrue(lastEvent != null); + assertTrue(lastEvent.mSucceeded); + + if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": ServiceName = " + + lastEvent.mInfo.getServiceName()); + + assertTrue(lastEvent.mInfo.getServiceName().equals(registeredName)); + + assertTrue(eventCacheSize() == 2); + clearEventCache(); + + mNsdManager.stopServiceDiscovery(mDiscoveryListener); + lastEvent = waitForCallback("onDiscoveryStopped"); // id = 9 + assertTrue(lastEvent != null); + assertTrue(lastEvent.mSucceeded); + assertTrue(eventCacheSize() == 1); + + clearEventCache(); + mNsdManager.unregisterService(mRegistrationListener); + + lastEvent = waitForCallback("onServiceUnregistered"); // id = 10 + assertTrue(lastEvent != null); + assertTrue(lastEvent.mSucceeded); + assertTrue(eventCacheSize() == 1); + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From a73db07a5373747a804e0cabe4c077278d97f3aa Mon Sep 17 00:00:00 2001 From: Wink Saville Date: Sat, 17 Aug 2013 16:47:29 -0700 Subject: [PATCH 0115/1109] Add test for TYPE_MOBILE_IA. Bug: 10373518 Change-Id: Ifb976760ea91a858bfc5387fb93e465665cf078f --- tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index d4bff12a18..6f67ed99ea 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -97,6 +97,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_IMS)); assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_CBS)); assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_WIFI_P2P)); + assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_IA)); assertFalse(mCm.isNetworkTypeValid(-1)); assertTrue(mCm.isNetworkTypeValid(0)); assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.MAX_NETWORK_TYPE)); From 58a91ac733b29226e2e5447060db6d15e71b7d07 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Mon, 12 Aug 2013 16:55:27 +0900 Subject: [PATCH 0116/1109] Add a CTS test for IPv6 ping socket support. IPv6 ping socket support is needed for apps to successfully run ping6, but the kernel support was only merged recently. This test ensures that the required kernel support is available. Bug: 9701153 Change-Id: Ieac32ca9dbcaf3890fa3e57c1326fa83787ac6d1 --- .../src/android/net/ipv6/cts/PingTest.java | 144 ++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 tests/cts/net/src/android/net/ipv6/cts/PingTest.java diff --git a/tests/cts/net/src/android/net/ipv6/cts/PingTest.java b/tests/cts/net/src/android/net/ipv6/cts/PingTest.java new file mode 100644 index 0000000000..41eb03d34d --- /dev/null +++ b/tests/cts/net/src/android/net/ipv6/cts/PingTest.java @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2013 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.ipv6.cts; + +import android.test.AndroidTestCase; +import android.util.Log; + +import libcore.io.ErrnoException; +import libcore.io.Libcore; +import libcore.io.StructTimeval; +import static libcore.io.OsConstants.*; + +import java.io.FileDescriptor; +import java.io.IOException; +import java.net.InetAddress; +import java.net.Inet6Address; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.Random; + +public class PingTest extends AndroidTestCase { + /** Maximum size of the packets we're using to test. */ + private static final int MAX_SIZE = 4096; + + /** Number of packets to test. */ + private static final int NUM_PACKETS = 10; + + /** The beginning of an ICMPv6 echo request: type, code, and uninitialized checksum. */ + private static final byte[] PING_HEADER = new byte[] { + (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00 + }; + + /** + * Returns a byte array containing an ICMPv6 echo request with the specified payload length. + */ + private byte[] pingPacket(int payloadLength) { + byte[] packet = new byte[payloadLength + 8]; + new Random().nextBytes(packet); + System.arraycopy(PING_HEADER, 0, packet, 0, PING_HEADER.length); + return packet; + } + + /** + * Checks that the first length bytes of two byte arrays are equal. + */ + private void assertArrayBytesEqual(byte[] expected, byte[] actual, int length) { + for (int i = 0; i < length; i++) { + assertEquals("Arrays differ at index " + i + ":", expected[i], actual[i]); + } + } + + /** + * Creates an IPv6 ping socket and sets a receive timeout of 100ms. + */ + private FileDescriptor createPingSocket() throws ErrnoException { + FileDescriptor s = Libcore.os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6); + Libcore.os.setsockoptTimeval(s, SOL_SOCKET, SO_RCVTIMEO, StructTimeval.fromMillis(100)); + return s; + } + + /** + * Sends a ping packet to a random port on the specified address on the specified socket. + */ + private void sendPing(FileDescriptor s, + InetAddress address, byte[] packet) throws ErrnoException, IOException { + // Pick a random port. Choose a range that gives a reasonable chance of picking a low port. + int port = (int) (Math.random() * 2048); + + // Send the packet. + int ret = Libcore.os.sendto(s, ByteBuffer.wrap(packet), 0, address, port); + assertEquals(packet.length, ret); + } + + /** + * Checks that a socket has received a response appropriate to the specified packet. + */ + private void checkResponse(FileDescriptor s, + InetAddress dest, byte[] sent) throws ErrnoException, IOException { + // Receive the response. + InetSocketAddress from = new InetSocketAddress(); + ByteBuffer responseBuffer = ByteBuffer.allocate(MAX_SIZE); + int bytesRead = Libcore.os.recvfrom(s, responseBuffer, 0, from); + + // Check the source address and scope ID. + assertTrue(from.getAddress() instanceof Inet6Address); + Inet6Address fromAddress = (Inet6Address) from.getAddress(); + assertEquals(0, fromAddress.getScopeId()); + assertNull(fromAddress.getScopedInterface()); + assertEquals(dest.getHostAddress(), fromAddress.getHostAddress()); + + // Check the packet length. + assertEquals(sent.length, bytesRead); + + // Check the response is an echo reply. + byte[] response = new byte[bytesRead]; + responseBuffer.get(response, 0, bytesRead); + assertEquals((byte) 0x81, response[0]); + + // Find out what ICMP ID was used in the packet that was sent. + int id = ((InetSocketAddress) Libcore.os.getsockname(s)).getPort(); + sent[4] = (byte) (id / 256); + sent[5] = (byte) (id % 256); + + // Ensure the response is the same as the packet, except for the type (which is 0x81) + // and the ID and checksum, which are set by the kernel. + response[0] = (byte) 0x80; // Type. + response[2] = response[3] = (byte) 0x00; // Checksum. + assertArrayBytesEqual(response, sent, bytesRead); + } + + /** + * Sends NUM_PACKETS random ping packets to ::1 and checks the replies. + */ + public void testLoopbackPing() throws ErrnoException, IOException { + // Generate a random ping packet and send it to localhost. + InetAddress ipv6Loopback = InetAddress.getByName(null); + assertEquals("localhost/::1", ipv6Loopback.toString()); + + for (int i = 0; i < NUM_PACKETS; i++) { + byte[] packet = pingPacket((int) (Math.random() * MAX_SIZE)); + FileDescriptor s = createPingSocket(); + sendPing(s, ipv6Loopback, packet); + checkResponse(s, ipv6Loopback, packet); + // Check closing the socket doesn't raise an exception. + Libcore.os.close(s); + } + } +} From 5d5ff5a81da9c43e84a29588b3b4ed7ba39d3e97 Mon Sep 17 00:00:00 2001 From: Brian Carlstrom Date: Tue, 20 Aug 2013 21:59:33 -0700 Subject: [PATCH 0117/1109] Change SSLCertificateSocketFactoryTest to use googlemail.com Bug: 10351880 Change-Id: I759fe361b0c543535d100ca26ca5047ff4dbc026 --- .../android/net/cts/SSLCertificateSocketFactoryTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java index 70ab54d3cd..ceb74d1f31 100644 --- a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java +++ b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java @@ -86,9 +86,9 @@ public class SSLCertificateSocketFactoryTest extends AndroidTestCase { } // a host and port that are expected to be available but have - // a cert with a different CN, in this case CN=mtalk.google.com - private static String TEST_CREATE_SOCKET_HOST = "mobile-gtalk.l.google.com"; - private static int TEST_CREATE_SOCKET_PORT = 5228; + // a cert with a different CN, in this case CN=mail.google.com + private static String TEST_CREATE_SOCKET_HOST = "googlemail.com"; + private static int TEST_CREATE_SOCKET_PORT = 443; /** * b/2807618 Make sure that hostname verifcation in cases were it From 27c7fe542070a4c5fec4b1e16261adc4661eb9f9 Mon Sep 17 00:00:00 2001 From: Brian Carlstrom Date: Tue, 20 Aug 2013 21:59:33 -0700 Subject: [PATCH 0118/1109] Change SSLCertificateSocketFactoryTest to use googlemail.com Bug: 10351880 (cherry picked from commit d6e12427d0b69032fc82d0635a7b10bdbd39c78c) Change-Id: I0d2708c507da5cd84f61bdd50ac3b76b3ac15a0d --- .../android/net/cts/SSLCertificateSocketFactoryTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java index 70ab54d3cd..ceb74d1f31 100644 --- a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java +++ b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java @@ -86,9 +86,9 @@ public class SSLCertificateSocketFactoryTest extends AndroidTestCase { } // a host and port that are expected to be available but have - // a cert with a different CN, in this case CN=mtalk.google.com - private static String TEST_CREATE_SOCKET_HOST = "mobile-gtalk.l.google.com"; - private static int TEST_CREATE_SOCKET_PORT = 5228; + // a cert with a different CN, in this case CN=mail.google.com + private static String TEST_CREATE_SOCKET_HOST = "googlemail.com"; + private static int TEST_CREATE_SOCKET_PORT = 443; /** * b/2807618 Make sure that hostname verifcation in cases were it From 4bc10e0fbe66b1e1a7987795d16bc1b6a5cef977 Mon Sep 17 00:00:00 2001 From: Brian Carlstrom Date: Tue, 20 Aug 2013 21:59:33 -0700 Subject: [PATCH 0119/1109] Change SSLCertificateSocketFactoryTest to use googlemail.com Bug: 10351880 (cherry picked from commit 5d5ff5a81da9c43e84a29588b3b4ed7ba39d3e97) Change-Id: Ied4db819e0a62352776f7b19365e30a079a51b9f --- .../android/net/cts/SSLCertificateSocketFactoryTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java index 70ab54d3cd..ceb74d1f31 100644 --- a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java +++ b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java @@ -86,9 +86,9 @@ public class SSLCertificateSocketFactoryTest extends AndroidTestCase { } // a host and port that are expected to be available but have - // a cert with a different CN, in this case CN=mtalk.google.com - private static String TEST_CREATE_SOCKET_HOST = "mobile-gtalk.l.google.com"; - private static int TEST_CREATE_SOCKET_PORT = 5228; + // a cert with a different CN, in this case CN=mail.google.com + private static String TEST_CREATE_SOCKET_HOST = "googlemail.com"; + private static int TEST_CREATE_SOCKET_PORT = 443; /** * b/2807618 Make sure that hostname verifcation in cases were it From af3296605b2072078d9881bfd27d913adcef006f Mon Sep 17 00:00:00 2001 From: JP Abgrall Date: Thu, 12 Sep 2013 15:04:37 -0700 Subject: [PATCH 0120/1109] TrafficStats: fix uncertainty in flushing network traffic Flushing TCP traffic isn't reliable enough to force a packet on the socket, even with Nagle disabled. The kernel's socket sendto() is being invoked with 1024 bytes each time, but something deeper in the stack is merging packets. So now we wait 5ms between each of the 1024 packets after flushing. This allows running the test overnight in a loop without failure instead of only ~5 times. The error messages are now more detailed. Bug: 10668088 Change-Id: Ic47bec81c6dba2fad8b96eb4a41f183115c371de --- .../src/android/net/cts/TrafficStatsTest.java | 103 +++++++++++++----- 1 file changed, 78 insertions(+), 25 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java index 180d259bbc..9483bdccf1 100644 --- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java +++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java @@ -19,7 +19,11 @@ package android.net.cts; import android.net.TrafficStats; import android.os.Process; import android.test.AndroidTestCase; +import android.util.Log; +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -29,6 +33,8 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; public class TrafficStatsTest extends AndroidTestCase { + private static final String LOG_TAG = "TrafficStatsTest"; + public void testValidMobileStats() { // We can't assume a mobile network is even present in this test, so // we simply assert that a valid value is returned. @@ -75,19 +81,39 @@ public class TrafficStatsTest extends AndroidTestCase { return packetCount * (20 + 32 + bytes); } + private void accessOwnTrafficStats() throws IOException { + final int ownAppUid = getContext().getApplicationInfo().uid; + Log.d(LOG_TAG, "accesOwnTrafficStatsWithTags(): about to read qtaguid stats for own uid " + ownAppUid); + + boolean foundOwnDetailedStats = false; + try { + BufferedReader qtaguidReader = new BufferedReader(new FileReader("/proc/net/xt_qtaguid/stats")); + String line; + while ((line = qtaguidReader.readLine()) != null) { + String tokens[] = line.split(" "); + if (tokens.length > 3 && tokens[3].equals(String.valueOf(ownAppUid))) { + Log.d(LOG_TAG, "accessOwnTrafficStatsWithTags(): got own stats: " + line); + } + } + qtaguidReader.close(); + } catch (FileNotFoundException e) { + fail("Was not able to access qtaguid/stats: " + e); + } + } + public void testTrafficStatsForLocalhost() throws IOException { - long mobileTxPacketsBefore = TrafficStats.getMobileTxPackets(); - long mobileRxPacketsBefore = TrafficStats.getMobileRxPackets(); - long mobileTxBytesBefore = TrafficStats.getMobileTxBytes(); - long mobileRxBytesBefore = TrafficStats.getMobileRxBytes(); - long totalTxPacketsBefore = TrafficStats.getTotalTxPackets(); - long totalRxPacketsBefore = TrafficStats.getTotalRxPackets(); - long totalTxBytesBefore = TrafficStats.getTotalTxBytes(); - long totalRxBytesBefore = TrafficStats.getTotalRxBytes(); - long uidTxBytesBefore = TrafficStats.getUidTxBytes(Process.myUid()); - long uidRxBytesBefore = TrafficStats.getUidRxBytes(Process.myUid()); - long uidTxPacketsBefore = TrafficStats.getUidTxPackets(Process.myUid()); - long uidRxPacketsBefore = TrafficStats.getUidRxPackets(Process.myUid()); + final long mobileTxPacketsBefore = TrafficStats.getMobileTxPackets(); + final long mobileRxPacketsBefore = TrafficStats.getMobileRxPackets(); + final long mobileTxBytesBefore = TrafficStats.getMobileTxBytes(); + final long mobileRxBytesBefore = TrafficStats.getMobileRxBytes(); + final long totalTxPacketsBefore = TrafficStats.getTotalTxPackets(); + final long totalRxPacketsBefore = TrafficStats.getTotalRxPackets(); + final long totalTxBytesBefore = TrafficStats.getTotalTxBytes(); + final long totalRxBytesBefore = TrafficStats.getTotalRxBytes(); + final long uidTxBytesBefore = TrafficStats.getUidTxBytes(Process.myUid()); + final long uidRxBytesBefore = TrafficStats.getUidRxBytes(Process.myUid()); + final long uidTxPacketsBefore = TrafficStats.getUidTxPackets(Process.myUid()); + final long uidRxPacketsBefore = TrafficStats.getUidRxPackets(Process.myUid()); // Transfer 1MB of data across an explicitly localhost socket. final int byteCount = 1024; @@ -104,22 +130,36 @@ public class TrafficStatsTest extends AndroidTestCase { socket.setTcpNoDelay(true); OutputStream out = socket.getOutputStream(); byte[] buf = new byte[byteCount]; + TrafficStats.setThreadStatsTag(0x42); + TrafficStats.tagSocket(socket); + accessOwnTrafficStats(); for (int i = 0; i < packetCount; i++) { out.write(buf); out.flush(); + try { + // Bug: 10668088, Even with Nagle disabled, and flushing the 1024 bytes + // the kernel still regroups data into a larger packet. + Thread.sleep(5); + } catch (InterruptedException e) { + } } out.close(); socket.close(); + accessOwnTrafficStats(); } catch (IOException e) { + Log.i(LOG_TAG, "Badness during writes to socket: " + e); } } }.start(); + int read = 0; try { Socket socket = server.accept(); + socket.setTcpNoDelay(true); + TrafficStats.setThreadStatsTag(0x43); + TrafficStats.tagSocket(socket); InputStream in = socket.getInputStream(); byte[] buf = new byte[byteCount]; - int read = 0; while (read < byteCount * packetCount) { int n = in.read(buf); assertTrue("Unexpected EOF", n > 0); @@ -128,6 +168,7 @@ public class TrafficStatsTest extends AndroidTestCase { } finally { server.close(); } + assertTrue("Not all data read back", read >= byteCount * packetCount); // It's too fast to call getUidTxBytes function. try { @@ -163,18 +204,30 @@ public class TrafficStatsTest extends AndroidTestCase { * + 7 approx.: syn, syn-ack, ack, fin-ack, ack, fin-ack, ack; * but sometimes the last find-acks just vanish, so we set a lower limit of +5. */ - assertTrue("uidtxp: " + uidTxPacketsBefore + " -> " + uidTxPacketsAfter + " delta=" + uidTxDeltaPackets, - uidTxDeltaPackets >= packetCount + 5 && - uidTxDeltaPackets <= packetCount + packetCount + 7); - assertTrue("uidrxp: " + uidRxPacketsBefore + " -> " + uidRxPacketsAfter + " delta=" + uidRxDeltaPackets, - uidRxDeltaPackets >= packetCount + 5 && - uidRxDeltaPackets <= packetCount + packetCount + 7); - assertTrue("uidtxb: " + uidTxBytesBefore + " -> " + uidTxBytesAfter + " delta=" + uidTxDeltaBytes, - uidTxDeltaBytes >= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(5, 0) && - uidTxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + 7, 0)); - assertTrue("uidrxb: " + uidRxBytesBefore + " -> " + uidRxBytesAfter + " delta=" + uidRxDeltaBytes, - uidRxDeltaBytes >= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(5, 0) && - uidRxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + 7, 0)); + final int maxExpectedExtraPackets = 7; + final int minExpectedExtraPackets = 5; + + + assertTrue("uidtxp: " + uidTxPacketsBefore + " -> " + uidTxPacketsAfter + " delta=" + uidTxDeltaPackets + + " Wanted: " + uidTxDeltaPackets + ">=" + packetCount + "+" + minExpectedExtraPackets + " && " + + uidTxDeltaPackets + "<=" + packetCount + "+" + packetCount + "+" + maxExpectedExtraPackets, + uidTxDeltaPackets >= packetCount + minExpectedExtraPackets && + uidTxDeltaPackets <= packetCount + packetCount + maxExpectedExtraPackets); + assertTrue("uidrxp: " + uidRxPacketsBefore + " -> " + uidRxPacketsAfter + " delta=" + uidRxDeltaPackets + + " Wanted: " + uidRxDeltaPackets + ">=" + packetCount + "+" + minExpectedExtraPackets + " && " + + uidRxDeltaPackets + "<=" + packetCount + "+" + packetCount + "+" + maxExpectedExtraPackets, + uidRxDeltaPackets >= packetCount + minExpectedExtraPackets && + uidRxDeltaPackets <= packetCount + packetCount + maxExpectedExtraPackets); + assertTrue("uidtxb: " + uidTxBytesBefore + " -> " + uidTxBytesAfter + " delta=" + uidTxDeltaBytes + + " Wanted: " + uidTxDeltaBytes + ">=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(minExpectedExtraPackets, 0) + " && " + + uidTxDeltaBytes + "<=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets, 0), + uidTxDeltaBytes >= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(minExpectedExtraPackets, 0) && + uidTxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets, 0)); + assertTrue("uidrxb: " + uidRxBytesBefore + " -> " + uidRxBytesAfter + " delta=" + uidRxDeltaBytes + + " Wanted: " + uidRxDeltaBytes + ">=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(minExpectedExtraPackets, 0) + " && " + + uidRxDeltaBytes + "<=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets, 0), + uidRxDeltaBytes >= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(minExpectedExtraPackets, 0) && + uidRxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets, 0)); // Localhost traffic *does* count against total stats. // Fudge by 132 packets of 1500 bytes not related to the test. From e52091e2cca0a5c1195581d0405c5cace3a82901 Mon Sep 17 00:00:00 2001 From: Vinit Deshapnde Date: Mon, 23 Sep 2013 16:21:04 -0700 Subject: [PATCH 0121/1109] Fix broken DNS Test Couple of lines were just wrong (typo?) - and I have reduced our dependence on multiple static IPs (used to test reverse mapping). It can still get broken when external servers change their IP addresses though. Bug: 8658901 Change-Id: I745c958df2f61130798552f0f5f736c73fb5de30 --- tests/cts/net/jni/NativeDnsJni.c | 50 +++++++++++-------- .../cts/net/src/android/net/cts/DnsTest.java | 11 +++- 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/tests/cts/net/jni/NativeDnsJni.c b/tests/cts/net/jni/NativeDnsJni.c index de9bb677b5..b975594b26 100644 --- a/tests/cts/net/jni/NativeDnsJni.c +++ b/tests/cts/net/jni/NativeDnsJni.c @@ -20,6 +20,11 @@ #include #include +const char *GoogleDNSIpV4Address="8.8.8.8"; +const char *GoogleDNSIpV4Address2="8.8.4.4"; +const char *GoogleDNSIpV6Address="2001:4860:4860::8888"; +const char *GoogleDNSIpV6Address2="2001:4860:4860::8844"; + JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclass class) { const char *node = "www.google.com"; @@ -53,8 +58,8 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas freeaddrinfo(answer); answer = NULL; - if (foundv4 != 1 || foundv6 != 1) { - ALOGD("getaddrinfo(www.google.com) didn't find both v4 and v6"); + if (foundv4 != 1 && foundv6 != 1) { + ALOGD("getaddrinfo(www.google.com) didn't find either v4 or v6 address"); return JNI_FALSE; } } @@ -96,49 +101,50 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas struct sockaddr_in sa4; sa4.sin_family = AF_INET; sa4.sin_port = 0; - inet_pton(AF_INET, "173.252.110.27", &(sa4.sin_addr)); + inet_pton(AF_INET, GoogleDNSIpV4Address, &(sa4.sin_addr)); struct sockaddr_in6 sa6; sa6.sin6_family = AF_INET6; sa6.sin6_port = 0; sa6.sin6_flowinfo = 0; sa6.sin6_scope_id = 0; - inet_pton(AF_INET6, "2001:4860:4001:802::1008", &(sa6.sin6_addr)); + inet_pton(AF_INET6, GoogleDNSIpV6Address2, &(sa6.sin6_addr)); char buf[NI_MAXHOST]; int flags = NI_NAMEREQD; res = getnameinfo((const struct sockaddr*)&sa4, sizeof(sa4), buf, sizeof(buf), NULL, 0, flags); if (res != 0) { - ALOGD("getnameinfo(173.252.110.27 (facebook) ) gave error %d (%s)", res, gai_strerror(res)); + ALOGD("getnameinfo(%s (GoogleDNS) ) gave error %d (%s)", GoogleDNSIpV4Address, res, + gai_strerror(res)); return JNI_FALSE; } - if (strstr(buf, "facebook.com") == NULL) { - ALOGD("getnameinfo(173.252.110.27 (facebook) ) didn't return facebook.com: %s", buf); + if (strstr(buf, "google.com") == NULL) { + ALOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com: %s", + GoogleDNSIpV4Address, buf); return JNI_FALSE; } memset(buf, sizeof(buf), 0); - res = getnameinfo((const struct sockaddr*)&sa6, sizeof(sa6), buf, sizeof(buf), - NULL, 0, flags); + res = getnameinfo((const struct sockaddr*)&sa6, sizeof(sa6), buf, sizeof(buf), NULL, 0, flags); if (res != 0) { - ALOGD("getnameinfo(2a03:2880:2110:df01:face:b00c::8 (facebook) ) gave error %d (%s)", - res, gai_strerror(res)); + ALOGD("getnameinfo(%s (GoogleDNS) ) gave error %d (%s)", GoogleDNSIpV6Address2, + res, gai_strerror(res)); return JNI_FALSE; } - if (strstr(buf, "1e100.net") == NULL) { - ALOGD("getnameinfo(2a03:2880:2110:df01:face:b00c::8) didn't return facebook.com: %s", buf); + if (strstr(buf, "google.com") == NULL) { + ALOGD("getnameinfo(%s) didn't return google.com: %s", GoogleDNSIpV6Address2, buf); return JNI_FALSE; } // gethostbyname - struct hostent *my_hostent = gethostbyname("www.mit.edu"); + struct hostent *my_hostent = gethostbyname("www.youtube.com"); if (my_hostent == NULL) { - ALOGD("gethostbyname(www.mit.edu) gave null response"); + ALOGD("gethostbyname(www.youtube.com) gave null response"); return JNI_FALSE; } if ((my_hostent->h_addr_list == NULL) || (*my_hostent->h_addr_list == NULL)) { - ALOGD("gethostbyname(www.mit.edu) gave 0 addresses"); + ALOGD("gethostbyname(www.youtube.com) gave 0 addresses"); return JNI_FALSE; } { @@ -146,21 +152,23 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas while (*current != NULL) { char buf[256]; inet_ntop(my_hostent->h_addrtype, *current, buf, sizeof(buf)); - ALOGD("gethostbyname(www.mit.edu) gave %s", buf); + ALOGD("gethostbyname(www.youtube.com) gave %s", buf); current++; } } // gethostbyaddr char addr6[16]; - inet_pton(AF_INET6, "2001:4b10:bbc::2", addr6); + inet_pton(AF_INET6, GoogleDNSIpV6Address, addr6); my_hostent = gethostbyaddr(addr6, sizeof(addr6), AF_INET6); if (my_hostent == NULL) { - ALOGD("gethostbyaddr(2001:4b10:bbc::2 (bbc) ) gave null response"); + ALOGD("gethostbyaddr(%s (GoogleDNS) ) gave null response", GoogleDNSIpV6Address); return JNI_FALSE; } - ALOGD("gethostbyaddr(2001:4b10:bbc::2 (bbc) ) gave %s for name", - my_hostent->h_name ? my_hostent->h_name : "null"); + + ALOGD("gethostbyaddr(%s (GoogleDNS) ) gave %s for name", GoogleDNSIpV6Address, + my_hostent->h_name ? my_hostent->h_name : "null"); + if (my_hostent->h_name == NULL) return JNI_FALSE; return JNI_TRUE; } diff --git a/tests/cts/net/src/android/net/cts/DnsTest.java b/tests/cts/net/src/android/net/cts/DnsTest.java index cdd95aa077..879a962233 100644 --- a/tests/cts/net/src/android/net/cts/DnsTest.java +++ b/tests/cts/net/src/android/net/cts/DnsTest.java @@ -64,8 +64,13 @@ public class DnsTest extends AndroidTestCase { else if (addr instanceof Inet6Address) foundV6 = true; if (DBG) Log.e(TAG, "www.google.com gave " + addr.toString()); } - assertTrue(foundV4); - assertTrue(foundV6); + + // assertTrue(foundV4); + // assertTrue(foundV6); + + // We should have at least one of the addresses to connect! + assertTrue(foundV4 || foundV6); + try { addrs = InetAddress.getAllByName("ipv6.google.com"); } catch (UnknownHostException e) {} @@ -77,8 +82,10 @@ public class DnsTest extends AndroidTestCase { else if (addr instanceof Inet6Address) foundV6 = true; if (DBG) Log.e(TAG, "ipv6.google.com gave " + addr.toString()); } + assertTrue(foundV4 == false); assertTrue(foundV6 == true); + assertTrue(testNativeDns()); } From 851672c1ed70e93049280e862e68d8c0874ada96 Mon Sep 17 00:00:00 2001 From: Vinit Deshapnde Date: Thu, 10 Oct 2013 14:56:43 -0700 Subject: [PATCH 0122/1109] Ignore duplicate events from mDNS stack in CTS It is too late to fix the duplicate events, and they may have existed in JB-MR2 as well. So fixing CTS to ignore them for now. Bug: 11049532 Change-Id: I0785a32dbac04eacb6994b428b12ce1ec27945d2 --- .../android/net/wifi/cts/NsdManagerTest.java | 133 +++++++++++------- 1 file changed, 84 insertions(+), 49 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java index 482a4e39a6..d1e4c447c3 100644 --- a/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java @@ -43,6 +43,12 @@ public class NsdManagerTest extends AndroidTestCase { NsdManager.ResolveListener mResolveListener; public NsdManagerTest() { + initRegistrationListener(); + initDiscoveryListener(); + initResolveListener(); + } + + private void initRegistrationListener() { mRegistrationListener = new NsdManager.RegistrationListener() { @Override public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) { @@ -64,6 +70,9 @@ public class NsdManagerTest extends AndroidTestCase { setEvent("onServiceUnregistered", serviceInfo); } }; + } + + private void initDiscoveryListener() { mDiscoveryListener = new NsdManager.DiscoveryListener() { @Override public void onStartDiscoveryFailed(String serviceType, int errorCode) { @@ -99,6 +108,9 @@ public class NsdManagerTest extends AndroidTestCase { setEvent("onServiceLost", serviceInfo); } }; + } + + private void initResolveListener() { mResolveListener = new NsdManager.ResolveListener() { @Override public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { @@ -112,6 +124,8 @@ public class NsdManagerTest extends AndroidTestCase { }; } + + private final class EventData { EventData(String callbackName, NsdServiceInfo info) { mCallbackName = callbackName; @@ -198,6 +212,29 @@ public class NsdManagerTest extends AndroidTestCase { } } + private EventData waitForNewEvents() throws InterruptedException { + if (DBG) Log.d(TAG, "Waiting for a bit, id=" + String.valueOf(mWaitId)); + + long startTime = android.os.SystemClock.uptimeMillis(); + long elapsedTime = 0; + synchronized (mEventCache) { + int index = mEventCache.size(); + while (elapsedTime < TIMEOUT ) { + // first check if we've received that event + for (; index < mEventCache.size(); index++) { + EventData e = mEventCache.get(index); + return e; + } + + // Not yet received, just wait + mEventCache.wait(TIMEOUT - elapsedTime); + elapsedTime = android.os.SystemClock.uptimeMillis() - startTime; + } + } + + return null; + } + private String mServiceName; @Override @@ -266,7 +303,9 @@ public class NsdManagerTest extends AndroidTestCase { assertTrue(lastEvent.mSucceeded); // Remove this event, so accounting becomes easier later - mEventCache.remove(lastEvent); + synchronized (mEventCache) { + mEventCache.remove(lastEvent); + } // Expect a service record to be discovered (and filter the ones // that are unrelated to this test) @@ -292,7 +331,9 @@ public class NsdManagerTest extends AndroidTestCase { // Remove this event from the event cache, so it won't be found by subsequent // calls to waitForCallback - mEventCache.remove(lastEvent); + synchronized (mEventCache) { + mEventCache.remove(lastEvent); + } } assertTrue(found); @@ -315,6 +356,7 @@ public class NsdManagerTest extends AndroidTestCase { assertTrue(lastEvent.mInfo.getPort() == localPort); assertTrue(eventCacheSize() == 1); + assertTrue(checkForAdditionalEvents()); clearEventCache(); // Unregister the service @@ -333,12 +375,17 @@ public class NsdManagerTest extends AndroidTestCase { assertTrue(eventCacheSize() == 2); // Register service again to see if we discover it + checkForAdditionalEvents(); clearEventCache(); si = new NsdServiceInfo(); si.setServiceType(SERVICE_TYPE); si.setServiceName(mServiceName); si.setPort(localPort); + + // Create a new registration listener and register same service again + initRegistrationListener(); + mNsdManager.registerService(si, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener); lastEvent = waitForCallback("onServiceRegistered"); // id = 7 @@ -358,67 +405,55 @@ public class NsdManagerTest extends AndroidTestCase { lastEvent.mInfo.getServiceName()); assertTrue(lastEvent.mInfo.getServiceName().equals(registeredName)); + assertTrue(checkCacheSize(2)); - assertTrue(eventCacheSize() == 2); + checkForAdditionalEvents(); clearEventCache(); mNsdManager.stopServiceDiscovery(mDiscoveryListener); lastEvent = waitForCallback("onDiscoveryStopped"); // id = 9 assertTrue(lastEvent != null); assertTrue(lastEvent.mSucceeded); - assertTrue(eventCacheSize() == 1); + assertTrue(checkCacheSize(1)); + checkForAdditionalEvents(); clearEventCache(); + mNsdManager.unregisterService(mRegistrationListener); lastEvent = waitForCallback("onServiceUnregistered"); // id = 10 assertTrue(lastEvent != null); assertTrue(lastEvent.mSucceeded); - assertTrue(eventCacheSize() == 1); + assertTrue(checkCacheSize(1)); + } + + boolean checkCacheSize(int size) { + synchronized (mEventCache) { + int cacheSize = mEventCache.size(); + if (cacheSize != size) { + Log.d(TAG, "id = " + mWaitId + ": event cache size = " + cacheSize); + for (int i = 0; i < cacheSize; i++) { + EventData e = mEventCache.get(i); + String sname = (e.mInfo != null) ? "(" + e.mInfo.getServiceName() + ")" : ""; + Log.d(TAG, "eventName is " + e.mCallbackName + sname); + } + } + return (cacheSize == size); + } + } + + boolean checkForAdditionalEvents() { + try { + EventData e = waitForNewEvents(); + if (e != null) { + String sname = (e.mInfo != null) ? "(" + e.mInfo.getServiceName() + ")" : ""; + Log.d(TAG, "ignoring unexpected event " + e.mCallbackName + sname); + } + return (e == null); + } + catch (InterruptedException ex) { + return false; + } } } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From b29370db3447b4115523c03cb5019df601984f23 Mon Sep 17 00:00:00 2001 From: Johan Redestig Date: Wed, 30 Oct 2013 14:14:58 +0100 Subject: [PATCH 0123/1109] Lookup private resources in run-time This fixes the following cases for us: android.net.cts.ConnectivityManagerTest#testGetAllNetworkInfo android.net.cts.ConnectivityManagerTest#testGetNetworkInfo android.net.cts.ConnectivityManagerTest#testIsNetworkSupported android.net.cts.ConnectivityManagerTest#testRequestRouteToHost android.net.cts.ConnectivityManagerTest#testSetNetworkPreference We need to use the prebuilt binary but that has dependency to private resource identities that differs in our environment. With this change the resources are looked up in run-time to avoid the build time dependency. Change-Id: I6579338b591ca7a0da3f03f796136269c7789780 --- .../src/android/net/cts/ConnectivityManagerTest.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index d4bff12a18..b93e115ba0 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -66,8 +66,10 @@ public class ConnectivityManagerTest extends AndroidTestCase { mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); mPackageManager = getContext().getPackageManager(); - String[] naStrings = getContext().getResources().getStringArray( - com.android.internal.R.array.networkAttributes); + // Get com.android.internal.R.array.networkAttributes + int resId = getContext().getResources().getIdentifier("networkAttributes", "array", "android"); + String[] naStrings = getContext().getResources().getStringArray(resId); + for (String naString : naStrings) { try { NetworkConfig n = new NetworkConfig(naString); @@ -75,8 +77,9 @@ public class ConnectivityManagerTest extends AndroidTestCase { } catch (Exception e) {} } - int[] protectedNetworks = getContext().getResources().getIntArray( - com.android.internal.R.array.config_protectedNetworks); + // Get com.android.internal.R.array.config_protectedNetworks + resId = getContext().getResources().getIdentifier("config_protectedNetworks", "array", "android"); + int[] protectedNetworks = getContext().getResources().getIntArray(resId); for (int p : protectedNetworks) { mProtectedNetworks.add(p); } From 7fd24cb8dfb0a150a75dc02fa23a1e3a2ff156eb Mon Sep 17 00:00:00 2001 From: Stuart Scott Date: Thu, 7 Nov 2013 10:30:32 -0800 Subject: [PATCH 0124/1109] Refactoring CTS to remove PTS references. PTS is now a part of CTS bug: 11561456 Change-Id: I577296fe7735790e285aa4747dc7832bc8ae5b6d --- tests/cts/net/Android.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index a6543b3a6a..7219fc483f 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -30,7 +30,7 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := CtsNetTestCases -LOCAL_STATIC_JAVA_LIBRARIES := ctstestserver ctsutil ctstestrunner +LOCAL_STATIC_JAVA_LIBRARIES := ctstestserver ctsdeviceutil ctstestrunner # uncomment when dalvik.annotation.Test* are removed or part of SDK #LOCAL_SDK_VERSION := current From 638d1eeee7ade6ac512a5acd39b870b2fabdeeee Mon Sep 17 00:00:00 2001 From: William Luh Date: Tue, 12 Nov 2013 10:05:11 -0800 Subject: [PATCH 0125/1109] CTS test for X509TrustManagerExtensions.isUserAddedCertificate. Bug: 11257762 Change-Id: I4d8bec7b75613b3286063e28b0fe0cba4e5c716b --- tests/cts/net/Android.mk | 2 +- .../cts/X509TrustManagerExtensionsTest.java | 77 +++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 tests/cts/net/src/android/net/http/cts/X509TrustManagerExtensionsTest.java diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index a6543b3a6a..83523cc0b7 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -21,7 +21,7 @@ LOCAL_MODULE_TAGS := optional # and when built explicitly put it in the data partition LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) -LOCAL_JAVA_LIBRARIES := android.test.runner voip-common +LOCAL_JAVA_LIBRARIES := android.test.runner voip-common conscrypt LOCAL_JNI_SHARED_LIBRARIES := libnativedns_jni diff --git a/tests/cts/net/src/android/net/http/cts/X509TrustManagerExtensionsTest.java b/tests/cts/net/src/android/net/http/cts/X509TrustManagerExtensionsTest.java new file mode 100644 index 0000000000..9c0d7744c7 --- /dev/null +++ b/tests/cts/net/src/android/net/http/cts/X509TrustManagerExtensionsTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2012 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.http.cts; + +import android.net.http.X509TrustManagerExtensions; +import android.util.Base64; + +import java.io.File; +import java.io.ByteArrayInputStream; + +import java.security.KeyStore; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; + +import junit.framework.TestCase; + +import com.android.org.conscrypt.TrustedCertificateStore; +import com.android.org.conscrypt.TrustManagerImpl; + +public class X509TrustManagerExtensionsTest extends TestCase { + + public void testIsUserAddedCert() throws Exception { + final String testCert = + "MIICfjCCAeegAwIBAgIJAMefIzKHY5H4MA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV" + + "BAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEPMA0G" + + "A1UECgwGR2V3Z3VsMRMwEQYDVQQDDApnZXdndWwuY29tMB4XDTEzMTEwNTAwNDE0" + + "MFoXDTEzMTIwNTAwNDE0MFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRYw" + + "FAYDVQQHDA1Nb3VudGFpbiBWaWV3MQ8wDQYDVQQKDAZHZXdndWwxEzARBgNVBAMM" + + "Cmdld2d1bC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKpc/I0Ss4sm" + + "yV2iX5xRMM7+XXAhiWrceGair4MpvDrGIa1kFj2phtx4IqTfDnNU7AhRJYkDYmJQ" + + "fUJ8i6F+I08uNiGVO4DtPJbZcBXg9ME9EMaJCslm995ueeNWSw1Ky8zM0tt4p+94" + + "BcXJ7PC3N2WgkvtE8xwNbaeUfhGPzJKXAgMBAAGjUDBOMB0GA1UdDgQWBBQQ/iW7" + + "JCkSI2sbn4nTBiZ9PSiO8zAfBgNVHSMEGDAWgBQQ/iW7JCkSI2sbn4nTBiZ9PSiO" + + "8zAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBABQBrUOWTCSIl3vkRR3w" + + "3bPzh3BpqDmxH9xe4rZr+MVKKjpGjY1z2m2EEtyNz3tbgVQym5+si00DUHFL0IP1" + + "SuRULmPyEpTBVbV+PA5Kc967ZcDgYt4JtdMcCeKbIFaU6r8oEYEL2PTlNZmgbunM" + + "pXktkhVvNxZeSa8yM9bPhXkN"; + + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + X509Certificate cert = (X509Certificate)cf.generateCertificate( + new ByteArrayInputStream(Base64.decode(testCert, Base64.DEFAULT))); + + // Test without adding cert to keystore. + KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); + X509TrustManagerExtensions tmeNegative = + new X509TrustManagerExtensions(new TrustManagerImpl(keyStore)); + assertEquals(false, tmeNegative.isUserAddedCertificate(cert)); + + // Test with cert added to keystore. + final File DIR_TEMP = new File(System.getProperty("java.io.tmpdir")); + final File DIR_TEST = new File(DIR_TEMP, "test"); + final File system = new File(DIR_TEST, "system-test"); + final File added = new File(DIR_TEST, "added-test"); + final File deleted = new File(DIR_TEST, "deleted-test"); + + TrustedCertificateStore tcs = new TrustedCertificateStore(system, added, deleted); + added.mkdirs(); + tcs.installCertificate(cert); + X509TrustManagerExtensions tmePositive = + new X509TrustManagerExtensions(new TrustManagerImpl(keyStore, null, tcs)); + assertEquals(true, tmePositive.isUserAddedCertificate(cert)); + } +} From 652d30b4b586d90f6f6451a1bd470c00b41101ea Mon Sep 17 00:00:00 2001 From: Alex Klyubin Date: Thu, 16 Jan 2014 14:52:46 -0800 Subject: [PATCH 0126/1109] Test default config of SSLCertificateSocketFactory. Bug: 11220570 Change-Id: I37440f3e8eda18215b9af703c027e4c8ca0334bf --- tests/cts/net/Android.mk | 3 ++- .../android/net/cts/SSLCertificateSocketFactoryTest.java | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index 7219fc483f..82abd6265f 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -30,7 +30,8 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := CtsNetTestCases -LOCAL_STATIC_JAVA_LIBRARIES := ctstestserver ctsdeviceutil ctstestrunner +LOCAL_STATIC_JAVA_LIBRARIES := ctstestserver ctsdeviceutil ctstestrunner \ + core-tests-support # uncomment when dalvik.annotation.Test* are removed or part of SDK #LOCAL_SDK_VERSION := current diff --git a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java index ceb74d1f31..cb8aeaf711 100644 --- a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java +++ b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java @@ -28,6 +28,8 @@ import android.test.AndroidTestCase; import dalvik.annotation.BrokenTest; +import libcore.javax.net.ssl.SSLDefaultConfigurationAsserts; + public class SSLCertificateSocketFactoryTest extends AndroidTestCase { private SSLCertificateSocketFactory mFactory; private int mTimeout; @@ -39,6 +41,10 @@ public class SSLCertificateSocketFactoryTest extends AndroidTestCase { mFactory = (SSLCertificateSocketFactory) SSLCertificateSocketFactory.getDefault(mTimeout); } + public void testDefaultConfiguration() throws Exception { + SSLDefaultConfigurationAsserts.assertSSLSocketFactory(mFactory); + } + public void testAccessProperties() throws Exception { mFactory.getSupportedCipherSuites(); mFactory.getDefaultCipherSuites(); From 0244dd7e3e59ccc335923313a2f19a05ac8191f5 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Thu, 30 Jan 2014 11:55:49 -0800 Subject: [PATCH 0127/1109] Document kernel code necessary to pass PingTest. Change-Id: If6fec0c5193cd897b4c3534843bcd589b40c2948 --- .../net/src/android/net/ipv6/cts/PingTest.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/cts/net/src/android/net/ipv6/cts/PingTest.java b/tests/cts/net/src/android/net/ipv6/cts/PingTest.java index 41eb03d34d..2c8aaef4bc 100644 --- a/tests/cts/net/src/android/net/ipv6/cts/PingTest.java +++ b/tests/cts/net/src/android/net/ipv6/cts/PingTest.java @@ -34,6 +34,21 @@ import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Random; +/** + * Checks that the device has kernel support for the IPv6 ping socket. This allows ping6 to work + * without root privileges. The necessary kernel code is in Linux 3.11 or above, or the + * common/android-3.x kernel trees. If you are not running one of these kernels, the + * functionality can be obtained by cherry-picking the following patches from David Miller's + * net-next tree: + *
    + *
  • 6d0bfe2 net: ipv6: Add IPv6 support to the ping socket. + *
  • c26d6b4 ping: always initialize ->sin6_scope_id and ->sin6_flowinfo + *
  • fbfe80c net: ipv6: fix wrong ping_v6_sendmsg return value + *
  • a1bdc45 net: ipv6: add missing lock in ping_v6_sendmsg + *
  • cf970c0 ping: prevent NULL pointer dereference on write to msg_name + *
+ * or the equivalent backports to the common/android-3.x trees. + */ public class PingTest extends AndroidTestCase { /** Maximum size of the packets we're using to test. */ private static final int MAX_SIZE = 4096; From 0ffaf6dba79cd9f2e48d576ced2e8fcb31c85ab9 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Mon, 3 Feb 2014 12:40:20 -0800 Subject: [PATCH 0128/1109] Test both recvfrom() and read() in PingTest. Change-Id: I2f49534f22bd718ce08c3408e38eeb97e09e5d6c --- .../src/android/net/ipv6/cts/PingTest.java | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/tests/cts/net/src/android/net/ipv6/cts/PingTest.java b/tests/cts/net/src/android/net/ipv6/cts/PingTest.java index 2c8aaef4bc..acf474fce4 100644 --- a/tests/cts/net/src/android/net/ipv6/cts/PingTest.java +++ b/tests/cts/net/src/android/net/ipv6/cts/PingTest.java @@ -105,19 +105,25 @@ public class PingTest extends AndroidTestCase { /** * Checks that a socket has received a response appropriate to the specified packet. */ - private void checkResponse(FileDescriptor s, - InetAddress dest, byte[] sent) throws ErrnoException, IOException { - // Receive the response. - InetSocketAddress from = new InetSocketAddress(); + private void checkResponse(FileDescriptor s, InetAddress dest, + byte[] sent, boolean useRecvfrom) throws ErrnoException, IOException { ByteBuffer responseBuffer = ByteBuffer.allocate(MAX_SIZE); - int bytesRead = Libcore.os.recvfrom(s, responseBuffer, 0, from); + int bytesRead; - // Check the source address and scope ID. - assertTrue(from.getAddress() instanceof Inet6Address); - Inet6Address fromAddress = (Inet6Address) from.getAddress(); - assertEquals(0, fromAddress.getScopeId()); - assertNull(fromAddress.getScopedInterface()); - assertEquals(dest.getHostAddress(), fromAddress.getHostAddress()); + // Receive the response. + if (useRecvfrom) { + InetSocketAddress from = new InetSocketAddress(); + bytesRead = Libcore.os.recvfrom(s, responseBuffer, 0, from); + + // Check the source address and scope ID. + assertTrue(from.getAddress() instanceof Inet6Address); + Inet6Address fromAddress = (Inet6Address) from.getAddress(); + assertEquals(0, fromAddress.getScopeId()); + assertNull(fromAddress.getScopedInterface()); + assertEquals(dest.getHostAddress(), fromAddress.getHostAddress()); + } else { + bytesRead = Libcore.os.read(s, responseBuffer); + } // Check the packet length. assertEquals(sent.length, bytesRead); @@ -150,8 +156,11 @@ public class PingTest extends AndroidTestCase { for (int i = 0; i < NUM_PACKETS; i++) { byte[] packet = pingPacket((int) (Math.random() * MAX_SIZE)); FileDescriptor s = createPingSocket(); + // Use both recvfrom and read(). sendPing(s, ipv6Loopback, packet); - checkResponse(s, ipv6Loopback, packet); + checkResponse(s, ipv6Loopback, packet, true); + sendPing(s, ipv6Loopback, packet); + checkResponse(s, ipv6Loopback, packet, false); // Check closing the socket doesn't raise an exception. Libcore.os.close(s); } From 2678d5bcf77cd494967c1e4183168f7ea88c72bb Mon Sep 17 00:00:00 2001 From: Daniel Kim Date: Fri, 16 Aug 2013 12:00:28 -0700 Subject: [PATCH 0129/1109] cherry pick from aosp. https://android-review.googlesource.com/63805 Fix for Wifi watchdog test when Wifi is not supported Added a check to see if Wifi is supported like other tests in the class Signed-off-by: Daniel Kim --- tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 283f63b5d4..213dc1785f 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -407,6 +407,10 @@ public class WifiManagerTest extends AndroidTestCase { * To pass this CTS test, a connected WiFi link is required. */ public void testWifiWatchdog() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } // Make sure WiFi is enabled if (!mWifiManager.isWifiEnabled()) { setWifiEnabled(true); From cf8d741f3d677c32aeb600fb855287dcea08926e Mon Sep 17 00:00:00 2001 From: Brett Chabot Date: Thu, 9 Jan 2014 14:32:20 -0800 Subject: [PATCH 0130/1109] Move to android.support.test as CTS instrumentation runner. Also do the following related cleanup - Remove references to deprecated BrokenTest and KnownFailure - Switch CTS tests to build against SDK and not private android.test.runner where possible Bug: 12924356 Change-Id: If6151b836456eec4838f8d7d6e11c9834c007fca --- tests/cts/net/Android.mk | 4 ++-- tests/cts/net/AndroidManifest.xml | 7 +++++-- .../android/net/cts/SSLCertificateSocketFactoryTest.java | 2 -- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index 1653335046..da19a4da78 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -21,7 +21,7 @@ LOCAL_MODULE_TAGS := optional # and when built explicitly put it in the data partition LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) -LOCAL_JAVA_LIBRARIES := android.test.runner voip-common conscrypt +LOCAL_JAVA_LIBRARIES := voip-common conscrypt LOCAL_JNI_SHARED_LIBRARIES := libnativedns_jni @@ -33,7 +33,7 @@ LOCAL_PACKAGE_NAME := CtsNetTestCases LOCAL_STATIC_JAVA_LIBRARIES := ctstestserver ctsdeviceutil ctstestrunner \ core-tests-support -# uncomment when dalvik.annotation.Test* are removed or part of SDK +# uncomment when b/13249961 is fixed #LOCAL_SDK_VERSION := current include $(BUILD_CTS_PACKAGE) diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index ade6728a6e..652262d491 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -32,9 +32,12 @@ - + android:label="CTS tests of android.net"> + + diff --git a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java index cb8aeaf711..6175923e46 100644 --- a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java +++ b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java @@ -26,8 +26,6 @@ import javax.net.ssl.SSLPeerUnverifiedException; import android.net.SSLCertificateSocketFactory; import android.test.AndroidTestCase; -import dalvik.annotation.BrokenTest; - import libcore.javax.net.ssl.SSLDefaultConfigurationAsserts; public class SSLCertificateSocketFactoryTest extends AndroidTestCase { From 0d4434d998a9fc7c314523503b0a09a8422acc71 Mon Sep 17 00:00:00 2001 From: Junjie Hu Date: Thu, 13 Mar 2014 16:25:12 +0800 Subject: [PATCH 0131/1109] Fix CTS android.net package testTrafficStatsForLocalhost seldom fail issue For testTrafficStatsForLocalhost's UID testing, it will also calcuate the wlan0 interface. There are some TCP re-tranmission in SSLCertificateSocketFactoryTest and it is the same UID as this test case. Need to consider those extra pacetks. For example, Before testTrafficStatsForLocalhost test casae: 01-08 15:49:11.316 7826 7839 D TrafficStats: parseUidStats, buffer: 14 wlan0 0x0 10067 0 31857 67 4582 55 31857 67 0 0 0 0 4582 55 0 0 0 0 01-08 15:49:11.335 7826 7839 D TrafficStats: parseUidStats, buffer: 24 lo 0x0 10067 0 40 1 60 1 40 1 0 0 0 0 60 1 0 0 0 0 After testTrafficStatsForLocalhost test casae: 01-08 15:49:19.210 7826 7839 D TrafficStats: parseUidStats, buffer: 14 wlan0 0x0 10067 0 31857 67 4738 58 31857 67 0 0 0 0 4738 58 0 0 0 0 01-08 15:49:19.212 7826 7839 D TrafficStats: parseUidStats, buffer: 24 lo 0x0 10067 0 1155336 2053 1155408 2054 1155336 2053 0 0 0 0 1155408 2054 0 0 0 0 => There are three extra IP packets after testing due to TCP FIN retreamsisions in previous test case Suggest to add some extra IP packets for consider the extra traffic in wlan0 interface. Signed-off-by: Junjie Hu Change-Id: I981f98fc8647469fb105361516b6a59c53530c70 --- .../src/android/net/cts/TrafficStatsTest.java | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) mode change 100644 => 100755 tests/cts/net/src/android/net/cts/TrafficStatsTest.java diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java old mode 100644 new mode 100755 index 9483bdccf1..5b93beead5 --- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java +++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java @@ -207,27 +207,37 @@ public class TrafficStatsTest extends AndroidTestCase { final int maxExpectedExtraPackets = 7; final int minExpectedExtraPackets = 5; + // Some other tests don't cleanup connections correctly. + // They have the same UID, so we discount their lingering traffic + // which happens only on non-localhost, such as TCP FIN retranmission packets + long deltaTxOtherPackets = (totalTxPacketsAfter - totalTxPacketsBefore) - uidTxDeltaPackets; + long deltaRxOtherPackets = (totalRxPacketsAfter - totalRxPacketsBefore) - uidRxDeltaPackets; + if (deltaTxOtherPackets > 0 || deltaRxOtherPackets > 0) { + Log.i(LOG_TAG, "lingering traffic data: " + deltaTxOtherPackets + "/" + deltaRxOtherPackets); + // Make sure that not too many non-localhost packets are accounted for + assertTrue("too many non-localhost packets on the sam UID", deltaTxOtherPackets + deltaTxOtherPackets < 20); + } assertTrue("uidtxp: " + uidTxPacketsBefore + " -> " + uidTxPacketsAfter + " delta=" + uidTxDeltaPackets + " Wanted: " + uidTxDeltaPackets + ">=" + packetCount + "+" + minExpectedExtraPackets + " && " + - uidTxDeltaPackets + "<=" + packetCount + "+" + packetCount + "+" + maxExpectedExtraPackets, + uidTxDeltaPackets + "<=" + packetCount + "+" + packetCount + "+" + maxExpectedExtraPackets + "+" + deltaTxOtherPackets, uidTxDeltaPackets >= packetCount + minExpectedExtraPackets && - uidTxDeltaPackets <= packetCount + packetCount + maxExpectedExtraPackets); + uidTxDeltaPackets <= packetCount + packetCount + maxExpectedExtraPackets + deltaTxOtherPackets); assertTrue("uidrxp: " + uidRxPacketsBefore + " -> " + uidRxPacketsAfter + " delta=" + uidRxDeltaPackets + " Wanted: " + uidRxDeltaPackets + ">=" + packetCount + "+" + minExpectedExtraPackets + " && " + uidRxDeltaPackets + "<=" + packetCount + "+" + packetCount + "+" + maxExpectedExtraPackets, uidRxDeltaPackets >= packetCount + minExpectedExtraPackets && - uidRxDeltaPackets <= packetCount + packetCount + maxExpectedExtraPackets); + uidRxDeltaPackets <= packetCount + packetCount + maxExpectedExtraPackets + deltaRxOtherPackets); assertTrue("uidtxb: " + uidTxBytesBefore + " -> " + uidTxBytesAfter + " delta=" + uidTxDeltaBytes + " Wanted: " + uidTxDeltaBytes + ">=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(minExpectedExtraPackets, 0) + " && " + uidTxDeltaBytes + "<=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets, 0), uidTxDeltaBytes >= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(minExpectedExtraPackets, 0) && - uidTxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets, 0)); + uidTxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets + deltaTxOtherPackets, 0)); assertTrue("uidrxb: " + uidRxBytesBefore + " -> " + uidRxBytesAfter + " delta=" + uidRxDeltaBytes + " Wanted: " + uidRxDeltaBytes + ">=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(minExpectedExtraPackets, 0) + " && " + uidRxDeltaBytes + "<=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets, 0), uidRxDeltaBytes >= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(minExpectedExtraPackets, 0) && - uidRxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets, 0)); + uidRxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets + deltaRxOtherPackets, 0)); // Localhost traffic *does* count against total stats. // Fudge by 132 packets of 1500 bytes not related to the test. From 81f625634e59c74a68abb67188d7cad3b848eb97 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Thu, 24 Apr 2014 16:58:17 -0700 Subject: [PATCH 0132/1109] Libcore.os has moved to android.system.Os. Change-Id: Icfd1cffbed754c147f83fc42ce905beb7904340c --- .../src/android/net/ipv6/cts/PingTest.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/cts/net/src/android/net/ipv6/cts/PingTest.java b/tests/cts/net/src/android/net/ipv6/cts/PingTest.java index acf474fce4..49fc59c716 100644 --- a/tests/cts/net/src/android/net/ipv6/cts/PingTest.java +++ b/tests/cts/net/src/android/net/ipv6/cts/PingTest.java @@ -19,10 +19,10 @@ package android.net.ipv6.cts; import android.test.AndroidTestCase; import android.util.Log; -import libcore.io.ErrnoException; -import libcore.io.Libcore; -import libcore.io.StructTimeval; -import static libcore.io.OsConstants.*; +import android.system.ErrnoException; +import android.system.Os; +import android.system.StructTimeval; +import static android.system.OsConstants.*; import java.io.FileDescriptor; import java.io.IOException; @@ -84,8 +84,8 @@ public class PingTest extends AndroidTestCase { * Creates an IPv6 ping socket and sets a receive timeout of 100ms. */ private FileDescriptor createPingSocket() throws ErrnoException { - FileDescriptor s = Libcore.os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6); - Libcore.os.setsockoptTimeval(s, SOL_SOCKET, SO_RCVTIMEO, StructTimeval.fromMillis(100)); + FileDescriptor s = Os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6); + Os.setsockoptTimeval(s, SOL_SOCKET, SO_RCVTIMEO, StructTimeval.fromMillis(100)); return s; } @@ -98,7 +98,7 @@ public class PingTest extends AndroidTestCase { int port = (int) (Math.random() * 2048); // Send the packet. - int ret = Libcore.os.sendto(s, ByteBuffer.wrap(packet), 0, address, port); + int ret = Os.sendto(s, ByteBuffer.wrap(packet), 0, address, port); assertEquals(packet.length, ret); } @@ -113,7 +113,7 @@ public class PingTest extends AndroidTestCase { // Receive the response. if (useRecvfrom) { InetSocketAddress from = new InetSocketAddress(); - bytesRead = Libcore.os.recvfrom(s, responseBuffer, 0, from); + bytesRead = Os.recvfrom(s, responseBuffer, 0, from); // Check the source address and scope ID. assertTrue(from.getAddress() instanceof Inet6Address); @@ -122,7 +122,7 @@ public class PingTest extends AndroidTestCase { assertNull(fromAddress.getScopedInterface()); assertEquals(dest.getHostAddress(), fromAddress.getHostAddress()); } else { - bytesRead = Libcore.os.read(s, responseBuffer); + bytesRead = Os.read(s, responseBuffer); } // Check the packet length. @@ -134,7 +134,7 @@ public class PingTest extends AndroidTestCase { assertEquals((byte) 0x81, response[0]); // Find out what ICMP ID was used in the packet that was sent. - int id = ((InetSocketAddress) Libcore.os.getsockname(s)).getPort(); + int id = ((InetSocketAddress) Os.getsockname(s)).getPort(); sent[4] = (byte) (id / 256); sent[5] = (byte) (id % 256); @@ -162,7 +162,7 @@ public class PingTest extends AndroidTestCase { sendPing(s, ipv6Loopback, packet); checkResponse(s, ipv6Loopback, packet, false); // Check closing the socket doesn't raise an exception. - Libcore.os.close(s); + Os.close(s); } } } From 5f308a9b10d6b9d36f12ef46e1b88fc0b5c71999 Mon Sep 17 00:00:00 2001 From: Vinod Krishnan Date: Thu, 5 Jun 2014 15:03:18 -0700 Subject: [PATCH 0133/1109] Small change to CTS Change-Id: I7b31bd6b05dd1379dcf7d4627eee1856fda87164 --- tests/cts/net/src/android/net/cts/VpnServiceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/VpnServiceTest.java b/tests/cts/net/src/android/net/cts/VpnServiceTest.java index 9e35375970..8bdd7b0895 100644 --- a/tests/cts/net/src/android/net/cts/VpnServiceTest.java +++ b/tests/cts/net/src/android/net/cts/VpnServiceTest.java @@ -42,7 +42,7 @@ public class VpnServiceTest extends AndroidTestCase { // Should be always resolved by only one activity. int count = mContext.getPackageManager().queryIntentActivities(intent, 0).size(); - assertEquals(count, 1); + assertEquals(1, count); } public void testEstablish() throws Exception { From fd24c913c286c24c535f8ff4283275be84a0b9bb Mon Sep 17 00:00:00 2001 From: Jason Parks Date: Wed, 11 Jun 2014 12:37:49 -0500 Subject: [PATCH 0134/1109] =?UTF-8?q?Don=E2=80=99t=20run=20the=20WifiConfi?= =?UTF-8?q?g=20tests=20if=20there=20is=20no=20Wifi.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: 15090701 Change-Id: I19d3fd5fe8165d94dd5d4d952bd5674b5df19684 --- .../net/wifi/cts/WifiEnterpriseConfigTest.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java index 58298d5f10..6e395aaa14 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java @@ -17,6 +17,7 @@ package android.net.wifi.cts; import android.content.Context; +import android.content.pm.PackageManager; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiEnterpriseConfig; import android.net.wifi.WifiEnterpriseConfig.Eap; @@ -34,6 +35,11 @@ public class WifiEnterpriseConfigTest extends AndroidTestCase { private static final String ANON_IDENTITY = "anonidentity"; private static final int ENABLE_DELAY = 10000; + private boolean hasWifi() { + return getContext().getPackageManager().hasSystemFeature( + PackageManager.FEATURE_WIFI); + } + @Override protected void setUp() throws Exception { super.setUp(); @@ -42,10 +48,16 @@ public class WifiEnterpriseConfigTest extends AndroidTestCase { assertNotNull(mWifiManager); mWifiManager.setWifiEnabled(true); Thread.sleep(ENABLE_DELAY); - assertTrue(mWifiManager.isWifiEnabled()); + if (hasWifi()) { + assertTrue(mWifiManager.isWifiEnabled()); + } } public void testSettersAndGetters() { + if (!hasWifi()) { + return; + } + WifiEnterpriseConfig config = new WifiEnterpriseConfig(); assertTrue(config.getEapMethod() == Eap.NONE); config.setEapMethod(Eap.PEAP); @@ -78,6 +90,10 @@ public class WifiEnterpriseConfigTest extends AndroidTestCase { } public void testAddEapNetwork() { + if (!hasWifi()) { + return; + } + WifiConfiguration config = new WifiConfiguration(); WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); enterpriseConfig.setEapMethod(Eap.PWD); From d8b41009bdd19c976ec45c33eaf8025005475986 Mon Sep 17 00:00:00 2001 From: Benson Huang Date: Wed, 25 Jun 2014 15:02:11 +0800 Subject: [PATCH 0135/1109] Fix CTS testStartUsingNetworkFeature_enableHipri fail The return value of mWifiManager.isWifiEnabled() && mWifiManager.getConnectionInfo().getSSID() != null can not correctly identify if WiFi is connected or not. The fix is to modify the code logic used to judge if WiFi is connected. Bug 15578218 and 15578219 Change-Id: I8ae40980c9cd1ea91dafe0ca7c893c84b35709bf Signed-off-by: Benson Huang --- .../src/android/net/cts/ConnectivityManagerTest.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index adb2b3a35e..5656119d0f 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -272,9 +272,13 @@ public class ConnectivityManagerTest extends AndroidTestCase { return; } - boolean isWifiConnected = mWifiManager.isWifiEnabled() - && mWifiManager.getConnectionInfo().getSSID() != null; + boolean isWifiEnabled = mWifiManager.isWifiEnabled(); + boolean isWifiConnected = false; + NetworkInfo nwInfo = mCm.getNetworkInfo(ConnectivityManager.TYPE_WIFI); + if (nwInfo != null) { + isWifiConnected = nwInfo.isConnected(); + } try { // Make sure WiFi is connected to an access point. if (!isWifiConnected) { @@ -308,7 +312,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { // TODO wait for HIPRI to go // TODO check dns selection // TODO check routes - if (!isWifiConnected) { + if (!isWifiEnabled) { mWifiManager.setWifiEnabled(false); } } From c893f50f6f995cf2bb866eea22beede36881e20e Mon Sep 17 00:00:00 2001 From: Benson Huang Date: Wed, 25 Jun 2014 15:02:11 +0800 Subject: [PATCH 0136/1109] Fix CTS testStartUsingNetworkFeature_enableHipri fail The return value of mWifiManager.isWifiEnabled() && mWifiManager.getConnectionInfo().getSSID() != null can not correctly identify if WiFi is connected or not. The fix is to modify the code logic used to judge if WiFi is connected. Bug 15578218 and 15578219 Change-Id: I8ae40980c9cd1ea91dafe0ca7c893c84b35709bf Signed-off-by: Benson Huang --- .../src/android/net/cts/ConnectivityManagerTest.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 6f67ed99ea..e769be19ae 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -269,9 +269,13 @@ public class ConnectivityManagerTest extends AndroidTestCase { return; } - boolean isWifiConnected = mWifiManager.isWifiEnabled() - && mWifiManager.getConnectionInfo().getSSID() != null; + boolean isWifiEnabled = mWifiManager.isWifiEnabled(); + boolean isWifiConnected = false; + NetworkInfo nwInfo = mCm.getNetworkInfo(ConnectivityManager.TYPE_WIFI); + if (nwInfo != null) { + isWifiConnected = nwInfo.isConnected(); + } try { // Make sure WiFi is connected to an access point. if (!isWifiConnected) { @@ -305,7 +309,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { // TODO wait for HIPRI to go // TODO check dns selection // TODO check routes - if (!isWifiConnected) { + if (!isWifiEnabled) { mWifiManager.setWifiEnabled(false); } } From e6694c32fe5cff9d8fd7a47eaf30534ba67d2306 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Wed, 16 Jul 2014 18:47:53 +0900 Subject: [PATCH 0137/1109] Add a CTS test for multinetwork features. For now, just checks that the kernel sysctls are present and have the right permissions and expected values. Bug: 15605143 Change-Id: I5feb6cb5f25b97e88cd0d9e8071213d13d4cc6e8 --- .../src/android/net/cts/MultinetworkTest.java | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 tests/cts/net/src/android/net/cts/MultinetworkTest.java diff --git a/tests/cts/net/src/android/net/cts/MultinetworkTest.java b/tests/cts/net/src/android/net/cts/MultinetworkTest.java new file mode 100644 index 0000000000..256c03010a --- /dev/null +++ b/tests/cts/net/src/android/net/cts/MultinetworkTest.java @@ -0,0 +1,99 @@ +/* + * 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 functionality. + */ +public class MultinetworkTest extends AndroidTestCase { + + // 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 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); + } + + private void assertLess(String what, int a, int b) { + assertTrue(what + " 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 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) { + checkSysctlPermissions(sysctl); + int value = Integer.parseInt(readFile(sysctl).trim()); + assertEquals("value of " + 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(); + checkSysctlPermissions(sysctl); + int value = Integer.parseInt(readFile(sysctl).trim()); + assertLess("value of " + sysctl + ":", value, 0); + } + } +} From 39f61377a5b30302f9f85b6cb8ac1df5585b3ebc Mon Sep 17 00:00:00 2001 From: Constantin Musca Date: Fri, 23 May 2014 14:20:29 +0300 Subject: [PATCH 0138/1109] LocalSocketTest.testAccessors: fix the *SendBufferSize* test If one sets a *SendBufferSize* value which is less than (2048 + SKB_DATA_ALIGN(sizeof(struct sk_buff))) then the value retrieved will be (2 * (2048 + SKB_DATA_ALIGN(sizeof(struct sk_buff)))). Otherwise, the value will be doubled. Modify the test to use a larger value. Bug: 16442451 Change-Id: I2d89393b1ad441783c8a082b072a806b8901830c Signed-off-by: Constantin Musca --- tests/cts/net/src/android/net/cts/LocalSocketTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/LocalSocketTest.java b/tests/cts/net/src/android/net/cts/LocalSocketTest.java index 0a4bc0d4f2..865ec21da3 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketTest.java @@ -126,8 +126,8 @@ public class LocalSocketTest extends AndroidTestCase{ socket.setReceiveBufferSize(1999); assertEquals(1999 << 1, socket.getReceiveBufferSize()); - socket.setSendBufferSize(1998); - assertEquals(1998 << 1, socket.getSendBufferSize()); + socket.setSendBufferSize(3998); + assertEquals(3998 << 1, socket.getSendBufferSize()); // Timeout is not support at present, so set is ignored socket.setSoTimeout(1996); From 67e673f04eab563809c241a8d465bcd132741581 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Thu, 25 Sep 2014 10:07:21 -0400 Subject: [PATCH 0139/1109] Update CTS ConnectivityManager tests to work with L release. Removed most of getNetworkPreference() and setNetworkPreference() tests as these functions are now fully deprecated and do nothing. Just test that they are still callable. Adjust startUsingNetworkFeature() and stopUsingNetworkFeature() failure codes to match new behavior. Tested on devices with Wifi and Cellular radios, and Wifi-only. bug:17417896 bug:17354855 Change-Id: Iea8b25e399f4e5b6ec3d2101ebf520f89697c4da --- .../net/cts/ConnectivityManagerTest.java | 46 +++++-------------- 1 file changed, 11 insertions(+), 35 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 5656119d0f..d79ecdddb4 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -16,7 +16,6 @@ package android.net.cts; - import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -31,6 +30,8 @@ import android.net.wifi.WifiManager; import android.test.AndroidTestCase; import android.util.Log; +import com.android.internal.telephony.PhoneConstants; + import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -115,34 +116,9 @@ public class ConnectivityManagerTest extends AndroidTestCase { } public void testSetNetworkPreference() { - // verify swtiching between two default networks - need to connectable networks though - // could use test and whatever the current active network is - int originalPref = mCm.getNetworkPreference(); - int currentPref = originalPref; - for (int type = -1; type <= ConnectivityManager.MAX_NETWORK_TYPE+1; type++) { - mCm.setNetworkPreference(type); - NetworkConfig c = mNetworks.get(type); - boolean expectWorked = (c != null && c.isDefault()); - int totalSleep = 0; - int foundType = ConnectivityManager.TYPE_NONE; - while (totalSleep < 1000) { - try { - Thread.currentThread().sleep(100); - } catch (InterruptedException e) {} - totalSleep += 100; - foundType = mCm.getNetworkPreference(); - if (currentPref != foundType) break; - } - if (expectWorked) { - assertTrue("We should have been able to switch prefered type " + type, - foundType == type); - } else { - assertTrue("We should not have been able to switch type " + type, - foundType != type); - } - currentPref = foundType; - } - mCm.setNetworkPreference(originalPref); + // getNetworkPreference() and setNetworkPreference() are both deprecated so they do + // not preform any action. Verify they are at least still callable. + mCm.setNetworkPreference(mCm.getNetworkPreference()); } public void testGetActiveNetworkInfo() { @@ -194,13 +170,13 @@ public class ConnectivityManagerTest extends AndroidTestCase { final String invalidateFeature = "invalidateFeature"; final String mmsFeature = "enableMMS"; final int failureCode = -1; - final int wifiOnlyStartFailureCode = 3; - final int wifiOnlyStopFailureCode = 1; + final int wifiOnlyStartFailureCode = PhoneConstants.APN_REQUEST_FAILED; + final int wifiOnlyStopFailureCode = -1; NetworkInfo ni = mCm.getNetworkInfo(TYPE_MOBILE); if (ni != null) { - assertEquals(failureCode, mCm.startUsingNetworkFeature(TYPE_MOBILE, - invalidateFeature)); + assertEquals(PhoneConstants.APN_REQUEST_FAILED, + mCm.startUsingNetworkFeature(TYPE_MOBILE, invalidateFeature)); assertEquals(failureCode, mCm.stopUsingNetworkFeature(TYPE_MOBILE, invalidateFeature)); } else { @@ -212,8 +188,8 @@ public class ConnectivityManagerTest extends AndroidTestCase { ni = mCm.getNetworkInfo(TYPE_WIFI); if (ni != null) { - // Should return failure(-1) because MMS is not supported on WIFI. - assertEquals(failureCode, mCm.startUsingNetworkFeature(TYPE_WIFI, + // Should return failure because MMS is not supported on WIFI. + assertEquals(PhoneConstants.APN_REQUEST_FAILED, mCm.startUsingNetworkFeature(TYPE_WIFI, mmsFeature)); assertEquals(failureCode, mCm.stopUsingNetworkFeature(TYPE_WIFI, mmsFeature)); From 94995b1dc8d4f66bc13a45961a79c17f646acf55 Mon Sep 17 00:00:00 2001 From: Unsuk Jung Date: Thu, 9 Oct 2014 00:59:51 -0700 Subject: [PATCH 0140/1109] Build CTS tests as multilib apks CTS-tradefed uses the same apk for both 32 and 64 bit tests. Bug: 17924614 Change-Id: Idbf2d93c54efbb1c281ad9e93f0f39430614df61 --- tests/cts/net/Android.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index da19a4da78..46d4d819ac 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -21,6 +21,9 @@ LOCAL_MODULE_TAGS := optional # and when built explicitly put it in the data partition LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) +# Include both the 32 and 64 bit versions +LOCAL_MULTILIB := both + LOCAL_JAVA_LIBRARIES := voip-common conscrypt LOCAL_JNI_SHARED_LIBRARIES := libnativedns_jni From 383973418884541fd80308d9e124960dcc4719da Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Tue, 14 Oct 2014 18:40:09 -0700 Subject: [PATCH 0141/1109] Add cts test for wifi scan timestamp. Bug:18014366 Change-Id: Ie25c53eb12077f4f03f45c7e6828a8ace25c0fdb --- .../android/net/wifi/cts/WifiManagerTest.java | 52 +++++++++++++++++-- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 7faea64648..d8df064311 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -28,6 +28,7 @@ import android.net.wifi.WifiConfiguration.Status; import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.TxPacketCountListener; import android.net.wifi.WifiManager.WifiLock; +import android.os.SystemClock; import android.test.AndroidTestCase; import android.util.Log; @@ -36,6 +37,7 @@ import java.net.URL; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; public class WifiManagerTest extends AndroidTestCase { @@ -46,7 +48,7 @@ public class WifiManagerTest extends AndroidTestCase { private WifiManager mWifiManager; private WifiLock mWifiLock; private static MySync mMySync; - private List mScanResult = null; + private List mScanResults = null; private NetworkInfo mNetworkInfo; // Please refer to WifiManager @@ -66,6 +68,10 @@ public class WifiManagerTest extends AndroidTestCase { private static final int TIMEOUT_MSEC = 6000; private static final int WAIT_MSEC = 60; private static final int DURATION = 10000; + private static final int WIFI_SCAN_TEST_INTERVAL_MILLIS = 60 * 1000; + private static final int WIFI_SCAN_TEST_CACHE_DELAY_MILLIS = 3 * 60 * 1000; + private static final int WIFI_SCAN_TEST_ITERATIONS = 5; + private IntentFilter mIntentFilter; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override @@ -74,9 +80,9 @@ public class WifiManagerTest extends AndroidTestCase { if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { synchronized (mMySync) { if (mWifiManager.getScanResults() != null) { - mScanResult = mWifiManager.getScanResults(); + mScanResults = mWifiManager.getScanResults(); mMySync.expectedState = STATE_SCAN_RESULTS_AVAILABLE; - mScanResult = mWifiManager.getScanResults(); + mScanResults = mWifiManager.getScanResults(); mMySync.notifyAll(); } } @@ -260,6 +266,46 @@ public class WifiManagerTest extends AndroidTestCase { assertFalse(mWifiManager.isWifiEnabled()); } + /** + * Test WiFi scan timestamp - fails when WiFi scan timestamps are inconsistent with + * {@link SystemClock#elapsedRealtime()} on device.

+ * To run this test in cts-tradefed: + * run cts --class android.net.wifi.cts.WifiManagerTest --method testWifiScanTimestamp + */ + public void testWifiScanTimestamp() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + Log.d(TAG, "Skipping test as WiFi is not supported"); + return; + } + if (!mWifiManager.isWifiEnabled()) { + setWifiEnabled(true); + } + // Scan multiple times to make sure scan timestamps increase with device timestamp. + for (int i = 0; i < WIFI_SCAN_TEST_ITERATIONS; ++i) { + startScan(); + // Make sure at least one AP is found. + assertFalse("empty scan results!", mScanResults.isEmpty()); + long nowMillis = SystemClock.elapsedRealtime(); + // Keep track of how many APs are fresh in one scan. + int numFreshAps = 0; + for (ScanResult result : mScanResults) { + long scanTimeMillis = TimeUnit.MICROSECONDS.toMillis(result.timestamp); + if (Math.abs(nowMillis - scanTimeMillis) < WIFI_SCAN_TEST_CACHE_DELAY_MILLIS) { + numFreshAps++; + } + } + // At least half of the APs in the scan should be fresh. + int numTotalAps = mScanResults.size(); + String msg = "Stale AP count: " + (numTotalAps - numFreshAps) + ", fresh AP count: " + + numFreshAps; + assertTrue(msg, numFreshAps * 2 >= mScanResults.size()); + if (i < WIFI_SCAN_TEST_ITERATIONS - 1) { + // Wait before running next iteration. + Thread.sleep(WIFI_SCAN_TEST_INTERVAL_MILLIS); + } + } + } + /** * test point of wifiManager NetWork: * 1.add NetWork From 0b3e6eb196c105833b8fbdabaa4f73fcab8b5f8c Mon Sep 17 00:00:00 2001 From: Vinit Deshpande Date: Tue, 21 Oct 2014 11:54:37 -0700 Subject: [PATCH 0142/1109] Relax NsdManagerTest's duplicate event check We have seen quite a few of these; and it doesn't seem to be pointing to any device implementation problem. Hence relaxing the test. Bug: 18005417 Change-Id: Iee983527ddff4f5336ccb48c04ce851102f13349 --- tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java index d1e4c447c3..d43472805b 100644 --- a/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java @@ -356,7 +356,7 @@ public class NsdManagerTest extends AndroidTestCase { assertTrue(lastEvent.mInfo.getPort() == localPort); assertTrue(eventCacheSize() == 1); - assertTrue(checkForAdditionalEvents()); + checkForAdditionalEvents(); clearEventCache(); // Unregister the service From 164529620828506486a1f1055696698242299547 Mon Sep 17 00:00:00 2001 From: Vinit Deshpande Date: Thu, 23 Oct 2014 17:02:19 -0700 Subject: [PATCH 0143/1109] Remove enableNetwork(netId, disableOthers) check from CTS We don't really disable any networks anymore; so there's not much to be verified. Bug: 17937171 Change-Id: I57e16953bdc0a698f3bc5fba555b39bc450c13ab --- .../net/src/android/net/wifi/cts/WifiManagerTest.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index d8df064311..152789cafb 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -213,8 +213,9 @@ public class WifiManagerTest extends AndroidTestCase { private void assertDisableOthers(WifiConfiguration wifiConfiguration, boolean disableOthers) { for (WifiConfiguration w : mWifiManager.getConfiguredNetworks()) { if ((!w.SSID.equals(wifiConfiguration.SSID)) && w.status != Status.CURRENT) { - if (disableOthers) + if (disableOthers) { assertEquals(Status.DISABLED, w.status); + } } } } @@ -321,6 +322,7 @@ public class WifiManagerTest extends AndroidTestCase { // skip the test if WiFi is not supported return; } + // store the list of enabled networks, so they can be re-enabled after test completes Set enabledSsids = getEnabledNetworks(mWifiManager.getConfiguredNetworks()); try { @@ -353,11 +355,6 @@ public class WifiManagerTest extends AndroidTestCase { wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); assertDisableOthers(wifiConfiguration, disableOthers); assertEquals(Status.ENABLED, wifiConfiguration.status); - disableOthers = true; - - assertTrue(mWifiManager.enableNetwork(netId, disableOthers)); - wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); - assertDisableOthers(wifiConfiguration, disableOthers); assertTrue(mWifiManager.disableNetwork(netId)); wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); From 5bba35cb162393646ba4e89e65988e8e949d04a5 Mon Sep 17 00:00:00 2001 From: Alex Klyubin Date: Tue, 18 Nov 2014 20:15:25 -0800 Subject: [PATCH 0144/1109] Fix build breakage due to SSLDefaultConfigurationAsserts rename. libcore's SSLDefaultConfigurationAsserts was renamed and refactored into SSLConfigurationAsserts in 782740701db73dd2dc4fef9df8cde270b0e631a4. This CL adjusts the affected CTS test for android.net.SSLCertificateSocketFactory accordingly. Change-Id: I663042e7c08ad616b2dedc226acda54c95fd6968 --- .../src/android/net/cts/SSLCertificateSocketFactoryTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java index 6175923e46..60ac226440 100644 --- a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java +++ b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java @@ -26,7 +26,7 @@ import javax.net.ssl.SSLPeerUnverifiedException; import android.net.SSLCertificateSocketFactory; import android.test.AndroidTestCase; -import libcore.javax.net.ssl.SSLDefaultConfigurationAsserts; +import libcore.javax.net.ssl.SSLConfigurationAsserts; public class SSLCertificateSocketFactoryTest extends AndroidTestCase { private SSLCertificateSocketFactory mFactory; @@ -40,7 +40,7 @@ public class SSLCertificateSocketFactoryTest extends AndroidTestCase { } public void testDefaultConfiguration() throws Exception { - SSLDefaultConfigurationAsserts.assertSSLSocketFactory(mFactory); + SSLConfigurationAsserts.assertSSLSocketFactoryDefaultConfiguration(mFactory); } public void testAccessProperties() throws Exception { From 5d5cd1f27d85f5b90573b31f80e860cc2c4ba4a8 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Sun, 16 Nov 2014 20:09:24 -0800 Subject: [PATCH 0145/1109] Add a CTS test for the VPN API. Bug: 15605143 Change-Id: I8e5f8b281b6ee16acf8daf1b4a1113847e1ccabd --- tests/cts/hostside/Android.mk | 31 ++ tests/cts/hostside/app/Android.mk | 32 ++ tests/cts/hostside/app/AndroidManifest.xml | 38 +++ .../android/cts/net/hostside/MyActivity.java | 53 ++++ .../cts/net/hostside/MyVpnService.java | 155 ++++++++++ .../cts/net/hostside/UdpReflector.java | 113 +++++++ .../com/android/cts/net/hostside/VpnTest.java | 281 ++++++++++++++++++ .../android/cts/net/HostsideNetworkTests.java | 105 +++++++ 8 files changed, 808 insertions(+) create mode 100644 tests/cts/hostside/Android.mk create mode 100644 tests/cts/hostside/app/Android.mk create mode 100644 tests/cts/hostside/app/AndroidManifest.xml create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/MyActivity.java create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/MyVpnService.java create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/UdpReflector.java create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java create mode 100644 tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTests.java diff --git a/tests/cts/hostside/Android.mk b/tests/cts/hostside/Android.mk new file mode 100644 index 0000000000..6637d6186f --- /dev/null +++ b/tests/cts/hostside/Android.mk @@ -0,0 +1,31 @@ +# 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. + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +# Only compile source java files in this apk. +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_MODULE := CtsHostsideNetworkTests + +LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt + +LOCAL_CTS_TEST_PACKAGE := android.net.hostsidenetwork + +include $(BUILD_CTS_HOST_JAVA_LIBRARY) + +# Build the test APKs using their own makefiles +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tests/cts/hostside/app/Android.mk b/tests/cts/hostside/app/Android.mk new file mode 100644 index 0000000000..29b620d2c3 --- /dev/null +++ b/tests/cts/hostside/app/Android.mk @@ -0,0 +1,32 @@ +# +# 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. +# + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests +LOCAL_SDK_VERSION := current +LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner ub-uiautomator + +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_PACKAGE_NAME := CtsHostsideNetworkTestsApp + +LOCAL_PROGUARD_ENABLED := disabled +LOCAL_DEX_PREOPT := false + +include $(BUILD_PACKAGE) diff --git a/tests/cts/hostside/app/AndroidManifest.xml b/tests/cts/hostside/app/AndroidManifest.xml new file mode 100644 index 0000000000..cdde7dcb34 --- /dev/null +++ b/tests/cts/hostside/app/AndroidManifest.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyActivity.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyActivity.java new file mode 100644 index 0000000000..375c8523c8 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyActivity.java @@ -0,0 +1,53 @@ +/* + * 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 com.android.cts.net.hostside; + +import android.app.Activity; +import android.content.Intent; +import android.net.VpnService; +import android.os.Bundle; +import android.os.ParcelFileDescriptor; +import android.view.WindowManager; + +import java.util.Arrays; +import java.util.ArrayList; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +public class MyActivity extends Activity { + private final LinkedBlockingQueue mResult = new LinkedBlockingQueue<>(1); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON + | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON + | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (mResult.offer(resultCode) == false) { + throw new RuntimeException("Queue is full! This should never happen"); + } + } + + public Integer getResult(int timeoutMs) throws InterruptedException { + return mResult.poll(timeoutMs, TimeUnit.MILLISECONDS); + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyVpnService.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyVpnService.java new file mode 100644 index 0000000000..1a12aaa14f --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyVpnService.java @@ -0,0 +1,155 @@ +/* + * 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 com.android.cts.net.hostside; + +import android.content.Intent; +import android.net.VpnService; +import android.os.ParcelFileDescriptor; +import android.content.pm.PackageManager.NameNotFoundException; +import android.text.TextUtils; +import android.util.Log; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; + +public class MyVpnService extends VpnService { + + private static String TAG = "MyVpnService"; + private static int MTU = 1799; + + private ParcelFileDescriptor mFd = null; + private UdpReflector mUdpReflector = null; + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + String packageName = getPackageName(); + String cmd = intent.getStringExtra(packageName + ".cmd"); + if ("disconnect".equals(cmd)) { + stop(); + } else if ("connect".equals(cmd)) { + start(packageName, intent); + } + + return START_NOT_STICKY; + } + + private void start(String packageName, Intent intent) { + Builder builder = new Builder(); + + String addresses = intent.getStringExtra(packageName + ".addresses"); + if (addresses != null) { + String[] addressArray = addresses.split(","); + for (int i = 0; i < addressArray.length; i++) { + String[] prefixAndMask = addressArray[i].split("/"); + try { + InetAddress address = InetAddress.getByName(prefixAndMask[0]); + int prefixLength = Integer.parseInt(prefixAndMask[1]); + builder.addAddress(address, prefixLength); + } catch (UnknownHostException|NumberFormatException| + ArrayIndexOutOfBoundsException e) { + continue; + } + } + } + + String routes = intent.getStringExtra(packageName + ".routes"); + if (routes != null) { + String[] routeArray = routes.split(","); + for (int i = 0; i < routeArray.length; i++) { + String[] prefixAndMask = routeArray[i].split("/"); + try { + InetAddress address = InetAddress.getByName(prefixAndMask[0]); + int prefixLength = Integer.parseInt(prefixAndMask[1]); + builder.addRoute(address, prefixLength); + } catch (UnknownHostException|NumberFormatException| + ArrayIndexOutOfBoundsException e) { + continue; + } + } + } + + String allowed = intent.getStringExtra(packageName + ".allowedapplications"); + if (allowed != null) { + String[] packageArray = allowed.split(","); + for (int i = 0; i < packageArray.length; i++) { + String allowedPackage = packageArray[i]; + if (!TextUtils.isEmpty(allowedPackage)) { + try { + builder.addAllowedApplication(allowedPackage); + } catch(NameNotFoundException e) { + continue; + } + } + } + } + + String disallowed = intent.getStringExtra(packageName + ".disallowedapplications"); + if (disallowed != null) { + String[] packageArray = disallowed.split(","); + for (int i = 0; i < packageArray.length; i++) { + String disallowedPackage = packageArray[i]; + if (!TextUtils.isEmpty(disallowedPackage)) { + try { + builder.addDisallowedApplication(disallowedPackage); + } catch(NameNotFoundException e) { + continue; + } + } + } + } + + builder.setMtu(MTU); + builder.setBlocking(true); + builder.setSession("MyVpnService"); + + Log.i(TAG, "Establishing VPN," + + " addresses=" + addresses + + " routes=" + routes + + " allowedApplications=" + allowed + + " disallowedApplications=" + disallowed); + + mFd = builder.establish(); + Log.i(TAG, "Established, fd=" + (mFd == null ? "null" : mFd.getFd())); + + mUdpReflector = new UdpReflector(mFd.getFileDescriptor(), MTU); + mUdpReflector.start(); + } + + private void stop() { + if (mUdpReflector != null) { + mUdpReflector.interrupt(); + mUdpReflector = null; + } + try { + if (mFd != null) { + Log.i(TAG, "Closing filedescriptor"); + mFd.close(); + } + } catch(IOException e) { + } finally { + mFd = null; + } + } + + @Override + public void onDestroy() { + stop(); + super.onDestroy(); + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/UdpReflector.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/UdpReflector.java new file mode 100644 index 0000000000..a730fed08a --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/UdpReflector.java @@ -0,0 +1,113 @@ +/* + * 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 com.android.cts.net.hostside; + +import android.system.Os; +import android.system.ErrnoException; +import android.util.Log; + +import java.io.FileDescriptor; +import java.io.IOException; + +public class UdpReflector extends Thread { + + private static int IPV4_HEADER_LENGTH = 20; + private static int IPV6_HEADER_LENGTH = 40; + private static int UDP_HEADER_LENGTH = 8; + + private static int IPV4_PROTO_OFFSET = 9; + private static int IPV6_PROTO_OFFSET = 6; + private static int IPPROTO_UDP = 17; + + private static int IPV4_ADDR_OFFSET = 12; + private static int IPV6_ADDR_OFFSET = 8; + private static int IPV4_ADDR_LENGTH = 4; + private static int IPV6_ADDR_LENGTH = 16; + + private static String TAG = "UdpReflector"; + + private FileDescriptor mFd; + private byte[] mBuf; + + public UdpReflector(FileDescriptor fd, int mtu) { + super("UdpReflector"); + mFd = fd; + mBuf = new byte[mtu]; + } + + private static void swapBytes(byte[] buf, int pos1, int pos2, int len) { + for (int i = 0; i < len; i++) { + byte b = buf[pos1 + i]; + buf[pos1 + i] = buf[pos2 + i]; + buf[pos2 + i] = b; + } + } + + /** Reads one packet from our mFd, and possibly writes the packet back. */ + private void processPacket() { + int len; + try { + len = Os.read(mFd, mBuf, 0, mBuf.length); + } catch (ErrnoException|IOException e) { + Log.e(TAG, "Error reading packet: " + e.getMessage()); + return; + } + + int version = mBuf[0] >> 4; + int addressOffset, protoOffset, headerLength, addressLength; + if (version == 4) { + headerLength = IPV4_HEADER_LENGTH; + protoOffset = IPV4_PROTO_OFFSET; + addressOffset = IPV4_ADDR_OFFSET; + addressLength = IPV4_ADDR_LENGTH; + } else if (version == 6) { + headerLength = IPV6_HEADER_LENGTH; + protoOffset = IPV6_PROTO_OFFSET; + addressOffset = IPV6_ADDR_OFFSET; + addressLength = IPV6_ADDR_LENGTH; + } else { + return; + } + + if (len < headerLength + UDP_HEADER_LENGTH || mBuf[protoOffset] != IPPROTO_UDP) { + return; + } + + // Swap src and dst IP addresses. + swapBytes(mBuf, addressOffset, addressOffset + addressLength, addressLength); + + // Swap dst and src ports. + int portOffset = headerLength; + swapBytes(mBuf, portOffset, portOffset + 2, 2); + + // Send the packet back. We don't need to recalculate the checksum because we didn't change + // the packet bytes, we only moved them around. + try { + len = Os.write(mFd, mBuf, 0, len); + } catch (ErrnoException|IOException e) { + Log.e(TAG, "Error writing packet: " + e.getMessage()); + } + } + + public void run() { + Log.i(TAG, "UdpReflector starting fd=" + mFd + " valid=" + mFd.valid()); + while (!interrupted() && mFd.valid()) { + processPacket(); + } + Log.i(TAG, "UdpReflector exiting fd=" + mFd + " valid=" + mFd.valid()); + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java new file mode 100644 index 0000000000..cdd370ee67 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java @@ -0,0 +1,281 @@ +/* + * 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 com.android.cts.net.hostside; + +import android.content.Intent; +import android.content.pm.PackageManager; +import android.net.ConnectivityManager; +import android.net.ConnectivityManager.NetworkCallback; +import android.net.LinkProperties; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.NetworkRequest; +import android.net.VpnService; +import android.os.ParcelFileDescriptor; +import android.os.SystemClock; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject; +import android.support.test.uiautomator.UiObjectNotFoundException; +import android.support.test.uiautomator.UiScrollable; +import android.support.test.uiautomator.UiSelector; +import android.test.MoreAsserts; +import android.test.InstrumentationTestCase; +import android.text.TextUtils; +import android.util.Log; + +import java.io.IOException; +import java.net.SocketTimeoutException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.Inet6Address; +import java.util.concurrent.atomic.AtomicReference; + +/** + * Tests for {@link DocumentsProvider} and interaction with platform intents + * like {@link Intent#ACTION_OPEN_DOCUMENT}. + */ +public class VpnTest extends InstrumentationTestCase { + + public static String TAG = "VpnTest"; + public static int TIMEOUT_MS = 3 * 1000; + + private UiDevice mDevice; + private MyActivity mActivity; + private String mPackageName; + private ConnectivityManager mCM; + Network mNetwork; + NetworkCallback mCallback; + final Object mLock = new Object(); + + private boolean supportedHardware() { + final PackageManager pm = getInstrumentation().getContext().getPackageManager(); + return !pm.hasSystemFeature("android.hardware.type.television") && + !pm.hasSystemFeature("android.hardware.type.watch"); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + + mNetwork = null; + mCallback = null; + + mDevice = UiDevice.getInstance(getInstrumentation()); + mActivity = launchActivity(getInstrumentation().getTargetContext().getPackageName(), + MyActivity.class, null); + mPackageName = mActivity.getPackageName(); + mCM = (ConnectivityManager) mActivity.getSystemService(mActivity.CONNECTIVITY_SERVICE); + mDevice.waitForIdle(); + } + + @Override + public void tearDown() throws Exception { + if (mCallback != null) { + mCM.unregisterNetworkCallback(mCallback); + } + Log.i(TAG, "Stopping VPN"); + stopVpn(); + mActivity.finish(); + super.tearDown(); + } + + private void prepareVpn() throws Exception { + final int REQUEST_ID = 42; + + // Attempt to prepare. + Log.i(TAG, "Preparing VPN"); + Intent intent = VpnService.prepare(mActivity); + + if (intent != null) { + // Start the confirmation dialog and click OK. + mActivity.startActivityForResult(intent, REQUEST_ID); + mDevice.waitForIdle(); + + String packageName = intent.getComponent().getPackageName(); + String resourceIdRegex = "android:id/button1$|button_start_vpn"; + final UiObject okButton = new UiObject(new UiSelector() + .className("android.widget.Button") + .packageName(packageName) + .resourceIdMatches(resourceIdRegex)); + if (okButton.waitForExists(TIMEOUT_MS) == false) { + mActivity.finishActivity(REQUEST_ID); + fail("VpnService.prepare returned an Intent for '" + intent.getComponent() + "' " + + "to display the VPN confirmation dialog, but this test could not find the " + + "button to allow the VPN application to connect. Please ensure that the " + + "component displays a button with a resource ID matching the regexp: '" + + resourceIdRegex + "'."); + } + + // Click the button and wait for RESULT_OK. + okButton.click(); + try { + int result = mActivity.getResult(TIMEOUT_MS); + if (result != MyActivity.RESULT_OK) { + fail("The VPN confirmation dialog did not return RESULT_OK when clicking on " + + "the button matching the regular expression '" + resourceIdRegex + + "' of " + intent.getComponent() + "'. Please ensure that clicking on " + + "that button allows the VPN application to connect. " + + "Return value: " + result); + } + } catch (InterruptedException e) { + fail("VPN confirmation dialog did not return after " + TIMEOUT_MS + "ms"); + } + + // Now we should be prepared. + intent = VpnService.prepare(mActivity); + if (intent != null) { + fail("VpnService.prepare returned non-null even after the VPN dialog " + + intent.getComponent() + "returned RESULT_OK."); + } + } + } + + private void startVpn( + String[] addresses, String[] routes, + String allowedApplications, String disallowedApplications) throws Exception { + + prepareVpn(); + + // Register a callback so we will be notified when our VPN comes up. + final NetworkRequest request = new NetworkRequest.Builder() + .addTransportType(NetworkCapabilities.TRANSPORT_VPN) + .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) + .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + .build(); + mCallback = new NetworkCallback() { + public void onAvailable(Network network) { + synchronized (mLock) { + Log.i(TAG, "Got available callback for network=" + network); + mNetwork = network; + mLock.notify(); + } + } + }; + mCM.registerNetworkCallback(request, mCallback); // Unregistered in tearDown. + + // Start the service and wait up for TIMEOUT_MS ms for the VPN to come up. + Intent intent = new Intent(mActivity, MyVpnService.class) + .putExtra(mPackageName + ".cmd", "connect") + .putExtra(mPackageName + ".addresses", TextUtils.join(",", addresses)) + .putExtra(mPackageName + ".routes", TextUtils.join(",", routes)) + .putExtra(mPackageName + ".allowedapplications", allowedApplications) + .putExtra(mPackageName + ".disallowedapplications", disallowedApplications); + mActivity.startService(intent); + synchronized (mLock) { + if (mNetwork == null) { + mLock.wait(TIMEOUT_MS); + } + } + + if (mNetwork == null) { + fail("VPN did not become available after " + TIMEOUT_MS + "ms"); + } + + // Unfortunately, when the available callback fires, the VPN UID ranges are not yet + // configured. Give the system some time to do so. http://b/18436087 . + try { Thread.sleep(300); } catch(InterruptedException e) {} + } + + private void stopVpn() { + // Simply calling mActivity.stopService() won't stop the service, because the system binds + // to the service for the purpose of sending it a revoke command if another VPN comes up, + // and stopping a bound service has no effect. Instead, "start" the service again with an + // Intent that tells it to disconnect. + Intent intent = new Intent(mActivity, MyVpnService.class) + .putExtra(mPackageName + ".cmd", "disconnect"); + mActivity.startService(intent); + } + + private static void checkUdpEcho( + String to, String expectedFrom, boolean expectReply) throws IOException { + DatagramSocket s; + InetAddress address = InetAddress.getByName(to); + if (address instanceof Inet6Address) { // http://b/18094870 + s = new DatagramSocket(0, InetAddress.getByName("::")); + } else { + s = new DatagramSocket(); + } + s.setSoTimeout(100); // ms. + + String msg = "Hello, world!"; + DatagramPacket p = new DatagramPacket(msg.getBytes(), msg.length()); + s.connect(address, 7); + + if (expectedFrom != null) { + assertEquals("Unexpected source address: ", + expectedFrom, s.getLocalAddress().getHostAddress()); + } + + try { + if (expectReply) { + s.send(p); + s.receive(p); + MoreAsserts.assertEquals(msg.getBytes(), p.getData()); + } else { + try { + s.send(p); + s.receive(p); + fail("Received unexpected reply"); + } catch(IOException expected) {} + } + } finally { + s.close(); + } + } + + private static void expectUdpEcho(String to, String expectedFrom) throws IOException { + checkUdpEcho(to, expectedFrom, true); + } + + private static void expectNoUdpEcho(String to) throws IOException { + checkUdpEcho(to, null, false); + } + + public void testDefault() throws Exception { + if (!supportedHardware()) return; + + startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"}, + new String[] {"192.0.2.0/24", "2001:db8::/32"}, + "", ""); + + expectUdpEcho("192.0.2.251", "192.0.2.2"); + expectUdpEcho("2001:db8:dead:beef::f00", "2001:db8:1:2::ffe"); + } + + public void testAppAllowed() throws Exception { + if (!supportedHardware()) return; + + startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"}, + new String[] {"0.0.0.0/0", "::/0"}, + mPackageName, ""); + + expectUdpEcho("192.0.2.251", "192.0.2.2"); + expectUdpEcho("2001:db8:dead:beef::f00", "2001:db8:1:2::ffe"); + } + + public void testAppDisallowed() throws Exception { + if (!supportedHardware()) return; + + startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"}, + new String[] {"192.0.2.0/24", "2001:db8::/32"}, + "", mPackageName); + + expectNoUdpEcho("192.0.2.251"); + expectNoUdpEcho("2001:db8:dead:beef::f00"); + } +} diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTests.java new file mode 100644 index 0000000000..a7698f36ac --- /dev/null +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTests.java @@ -0,0 +1,105 @@ +/* + * 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 com.android.cts.net; + +import com.android.cts.tradefed.build.CtsBuildHelper; +import com.android.ddmlib.testrunner.RemoteAndroidTestRunner; +import com.android.ddmlib.testrunner.TestIdentifier; +import com.android.ddmlib.testrunner.TestResult; +import com.android.ddmlib.testrunner.TestResult.TestStatus; +import com.android.ddmlib.testrunner.TestRunResult; +import com.android.tradefed.build.IBuildInfo; +import com.android.tradefed.device.DeviceNotAvailableException; +import com.android.tradefed.testtype.DeviceTestCase; +import com.android.tradefed.testtype.IAbi; +import com.android.tradefed.testtype.IAbiReceiver; +import com.android.tradefed.testtype.IBuildReceiver; +import com.android.tradefed.device.DeviceNotAvailableException; +import com.android.tradefed.device.ITestDevice; +import com.android.tradefed.result.CollectingTestListener; + +import java.util.Map; + +public class HostsideNetworkTests extends DeviceTestCase implements IAbiReceiver, IBuildReceiver { + private static final String TEST_PKG = "com.android.cts.net.hostside"; + private static final String TEST_APK = "CtsHostsideNetworkTestsApp.apk"; + + private IAbi mAbi; + private CtsBuildHelper mCtsBuild; + + @Override + public void setAbi(IAbi abi) { + mAbi = abi; + } + + @Override + public void setBuild(IBuildInfo buildInfo) { + mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + + assertNotNull(mAbi); + assertNotNull(mCtsBuild); + + getDevice().uninstallPackage(TEST_PKG); + + assertNull(getDevice().installPackage(mCtsBuild.getTestApp(TEST_APK), false)); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + + getDevice().uninstallPackage(TEST_PKG); + } + + public void testVpn() throws Exception { + runDeviceTests(TEST_PKG, ".VpnTest"); + } + + public void runDeviceTests(String packageName, String testClassName) + throws DeviceNotAvailableException { + RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(packageName, + "android.support.test.runner.AndroidJUnitRunner", getDevice().getIDevice()); + + final CollectingTestListener listener = new CollectingTestListener(); + getDevice().runInstrumentationTests(testRunner, listener); + + final TestRunResult result = listener.getCurrentRunResults(); + if (result.isRunFailure()) { + throw new AssertionError("Failed to successfully run device tests for " + + result.getName() + ": " + result.getRunFailureMessage()); + } + + if (result.hasFailedTests()) { + // build a meaningful error message + StringBuilder errorBuilder = new StringBuilder("on-device tests failed:\n"); + for (Map.Entry resultEntry : + result.getTestResults().entrySet()) { + if (!resultEntry.getValue().getStatus().equals(TestStatus.PASSED)) { + errorBuilder.append(resultEntry.getKey().toString()); + errorBuilder.append(":\n"); + errorBuilder.append(resultEntry.getValue().getStackTrace()); + } + } + throw new AssertionError(errorBuilder.toString()); + } + } +} From 96f656c39edf5983ce0bb8f6d5f9c0f1ac761507 Mon Sep 17 00:00:00 2001 From: Narayan Kamath Date: Tue, 9 Dec 2014 13:28:37 +0000 Subject: [PATCH 0146/1109] Track changes to Posix.* API. We need to flip() the byte buffer before attempting to read the data written to it. bug: 18641009 Change-Id: I4c69f67bb74d84583c6f71488bdc3c9a683a4f18 --- tests/cts/net/src/android/net/ipv6/cts/PingTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/cts/net/src/android/net/ipv6/cts/PingTest.java b/tests/cts/net/src/android/net/ipv6/cts/PingTest.java index 49fc59c716..e9bfb43b5e 100644 --- a/tests/cts/net/src/android/net/ipv6/cts/PingTest.java +++ b/tests/cts/net/src/android/net/ipv6/cts/PingTest.java @@ -130,6 +130,7 @@ public class PingTest extends AndroidTestCase { // Check the response is an echo reply. byte[] response = new byte[bytesRead]; + responseBuffer.flip(); responseBuffer.get(response, 0, bytesRead); assertEquals((byte) 0x81, response[0]); From 18fc2cd3c4ea315d0909cdfb1449431da1dc4429 Mon Sep 17 00:00:00 2001 From: Erik Kline Date: Wed, 10 Dec 2014 20:22:47 +0900 Subject: [PATCH 0147/1109] Consider VPN always to be a supported type. Change-Id I02eb5f22737720095f646f8db5c87fd66da129d6 adds VPN as a supported network type to all device configurations directly in software, independent of any external per-device configuration. Reflect this expectation in the test. Bug: 18439110 Bug: 18668362 Change-Id: I7fca77e564219c96e8a78372d4885c7b7f012a48 --- .../net/src/android/net/cts/ConnectivityManagerTest.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index d79ecdddb4..15d368f515 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -197,7 +197,11 @@ public class ConnectivityManagerTest extends AndroidTestCase { } private boolean isSupported(int networkType) { - return mNetworks.containsKey(networkType); + // Change-Id I02eb5f22737720095f646f8db5c87fd66da129d6 added VPN support + // to all devices directly in software, independent of any external + // configuration. + return mNetworks.containsKey(networkType) || + (networkType == ConnectivityManager.TYPE_VPN); } // true if only the system can turn it on From 913b99435035eca3be12eb31180dca54b2c79957 Mon Sep 17 00:00:00 2001 From: Wei Liu Date: Tue, 9 Dec 2014 15:48:50 -0800 Subject: [PATCH 0148/1109] Skip testDnsWorks if the active network for watch is proxy. Bug: 18625962 Change-Id: I56dacf8d93c1557b44eaf80fbc80eb6a596a9436 --- .../cts/net/src/android/net/cts/DnsTest.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/DnsTest.java b/tests/cts/net/src/android/net/cts/DnsTest.java index 879a962233..0377d048e7 100644 --- a/tests/cts/net/src/android/net/cts/DnsTest.java +++ b/tests/cts/net/src/android/net/cts/DnsTest.java @@ -16,6 +16,10 @@ package android.net.cts; +import android.content.Context; +import android.content.pm.PackageManager; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; import android.os.SystemClock; import android.test.AndroidTestCase; import android.util.Log; @@ -34,6 +38,7 @@ public class DnsTest extends AndroidTestCase { private static final boolean DBG = false; private static final String TAG = "DnsTest"; + private static final String PROXY_NETWORK_TYPE = "PROXY"; /** * @return true on success @@ -71,6 +76,14 @@ public class DnsTest extends AndroidTestCase { // We should have at least one of the addresses to connect! assertTrue(foundV4 || foundV6); + // Skip the rest of the test if the active network for watch is PROXY. + // TODO: Check NetworkInfo type in addition to type name once ag/601257 is merged. + if (getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH) + && activeNetworkInfoIsProxy()) { + Log.i(TAG, "Skipping test because the active network type name is PROXY."); + return; + } + try { addrs = InetAddress.getAllByName("ipv6.google.com"); } catch (UnknownHostException e) {} @@ -241,4 +254,15 @@ public class DnsTest extends AndroidTestCase { Log.e(TAG, "bad URL in testDnsPerf: " + e.toString()); } } + + private boolean activeNetworkInfoIsProxy() { + ConnectivityManager cm = (ConnectivityManager) + getContext().getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo info = cm.getActiveNetworkInfo(); + if (PROXY_NETWORK_TYPE.equals(info.getTypeName())) { + return true; + } + + return false; + } } From 0e87f2b861c61e0f53038cdd8d22fa7bca992354 Mon Sep 17 00:00:00 2001 From: Narayan Kamath Date: Tue, 9 Dec 2014 13:28:37 +0000 Subject: [PATCH 0149/1109] Track changes to Posix.* API. We need to flip() the byte buffer before attempting to read the data written to it. bug: 18641009 (cherry picked from commit 96f656c39edf5983ce0bb8f6d5f9c0f1ac761507) Change-Id: Ib796fafa1e4cf81351245fff6763ce17924acde9 --- tests/cts/net/src/android/net/ipv6/cts/PingTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/cts/net/src/android/net/ipv6/cts/PingTest.java b/tests/cts/net/src/android/net/ipv6/cts/PingTest.java index 49fc59c716..e9bfb43b5e 100644 --- a/tests/cts/net/src/android/net/ipv6/cts/PingTest.java +++ b/tests/cts/net/src/android/net/ipv6/cts/PingTest.java @@ -130,6 +130,7 @@ public class PingTest extends AndroidTestCase { // Check the response is an echo reply. byte[] response = new byte[bytesRead]; + responseBuffer.flip(); responseBuffer.get(response, 0, bytesRead); assertEquals((byte) 0x81, response[0]); From 83375d2bd22063f379b579be439883606ae296b8 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Sat, 29 Nov 2014 18:53:49 +0900 Subject: [PATCH 0150/1109] Test TCP and ICMPv6 on VPNs in addition to UDP. Bug: 15605143 Change-Id: Ifd7a646990619057e714a789902df2c157a768c0 --- .../cts/net/hostside/MyVpnService.java | 12 +- .../cts/net/hostside/PacketReflector.java | 234 ++++++++++++++++++ .../cts/net/hostside/UdpReflector.java | 113 --------- .../com/android/cts/net/hostside/VpnTest.java | 230 +++++++++++++++-- 4 files changed, 445 insertions(+), 144 deletions(-) create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/PacketReflector.java delete mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/UdpReflector.java diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyVpnService.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyVpnService.java index 1a12aaa14f..a3f400c388 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyVpnService.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyVpnService.java @@ -34,7 +34,7 @@ public class MyVpnService extends VpnService { private static int MTU = 1799; private ParcelFileDescriptor mFd = null; - private UdpReflector mUdpReflector = null; + private PacketReflector mPacketReflector = null; @Override public int onStartCommand(Intent intent, int flags, int startId) { @@ -127,14 +127,14 @@ public class MyVpnService extends VpnService { mFd = builder.establish(); Log.i(TAG, "Established, fd=" + (mFd == null ? "null" : mFd.getFd())); - mUdpReflector = new UdpReflector(mFd.getFileDescriptor(), MTU); - mUdpReflector.start(); + mPacketReflector = new PacketReflector(mFd.getFileDescriptor(), MTU); + mPacketReflector.start(); } private void stop() { - if (mUdpReflector != null) { - mUdpReflector.interrupt(); - mUdpReflector = null; + if (mPacketReflector != null) { + mPacketReflector.interrupt(); + mPacketReflector = null; } try { if (mFd != null) { diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/PacketReflector.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/PacketReflector.java new file mode 100644 index 0000000000..dd0f792b21 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/PacketReflector.java @@ -0,0 +1,234 @@ +/* + * 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 com.android.cts.net.hostside; + +import android.system.ErrnoException; +import android.system.Os; +import android.util.Log; + +import java.io.FileDescriptor; +import java.io.IOException; + +public class PacketReflector extends Thread { + + private static int IPV4_HEADER_LENGTH = 20; + private static int IPV6_HEADER_LENGTH = 40; + + private static int IPV4_ADDR_OFFSET = 12; + private static int IPV6_ADDR_OFFSET = 8; + private static int IPV4_ADDR_LENGTH = 4; + private static int IPV6_ADDR_LENGTH = 16; + + private static int IPV4_PROTO_OFFSET = 9; + private static int IPV6_PROTO_OFFSET = 6; + + private static final byte IPPROTO_ICMP = 1; + private static final byte IPPROTO_TCP = 6; + private static final byte IPPROTO_UDP = 17; + private static final byte IPPROTO_ICMPV6 = 58; + + private static int ICMP_HEADER_LENGTH = 8; + private static int TCP_HEADER_LENGTH = 20; + private static int UDP_HEADER_LENGTH = 8; + + private static final byte ICMP_ECHO = 8; + private static final byte ICMP_ECHOREPLY = 0; + private static final byte ICMPV6_ECHO_REQUEST = (byte) 128; + private static final byte ICMPV6_ECHO_REPLY = (byte) 129; + + private static String TAG = "PacketReflector"; + + private FileDescriptor mFd; + private byte[] mBuf; + + public PacketReflector(FileDescriptor fd, int mtu) { + super("PacketReflector"); + mFd = fd; + mBuf = new byte[mtu]; + } + + private static void swapBytes(byte[] buf, int pos1, int pos2, int len) { + for (int i = 0; i < len; i++) { + byte b = buf[pos1 + i]; + buf[pos1 + i] = buf[pos2 + i]; + buf[pos2 + i] = b; + } + } + + private static void swapAddresses(byte[] buf, int version) { + int addrPos, addrLen; + switch(version) { + case 4: + addrPos = IPV4_ADDR_OFFSET; + addrLen = IPV4_ADDR_LENGTH; + break; + case 6: + addrPos = IPV6_ADDR_OFFSET; + addrLen = IPV6_ADDR_LENGTH; + break; + default: + throw new IllegalArgumentException(); + } + swapBytes(buf, addrPos, addrPos + addrLen, addrLen); + } + + // Reflect TCP packets: swap the source and destination addresses, but don't change the ports. + // This is used by the test to "connect to itself" through the VPN. + private void processTcpPacket(byte[] buf, int version, int len, int hdrLen) { + if (len < hdrLen + TCP_HEADER_LENGTH) { + return; + } + + // Swap src and dst IP addresses. + swapAddresses(buf, version); + + // Send the packet back. + writePacket(buf, len); + } + + // Echo UDP packets: swap source and destination addresses, and source and destination ports. + // This is used by the test to check that the bytes it sends are echoed back. + private void processUdpPacket(byte[] buf, int version, int len, int hdrLen) { + if (len < hdrLen + UDP_HEADER_LENGTH) { + return; + } + + // Swap src and dst IP addresses. + swapAddresses(buf, version); + + // Swap dst and src ports. + int portOffset = hdrLen; + swapBytes(buf, portOffset, portOffset + 2, 2); + + // Send the packet back. + writePacket(buf, len); + } + + private void processIcmpPacket(byte[] buf, int version, int len, int hdrLen) { + if (len < hdrLen + ICMP_HEADER_LENGTH) { + return; + } + + byte type = buf[hdrLen]; + if (!(version == 4 && type == ICMP_ECHO) && + !(version == 6 && type == ICMPV6_ECHO_REQUEST)) { + return; + } + + // Save the ping packet we received. + byte[] request = buf.clone(); + + // Swap src and dst IP addresses, and send the packet back. + // This effectively pings the device to see if it replies. + swapAddresses(buf, version); + writePacket(buf, len); + + // The device should have replied, and buf should now contain a ping response. + int received = readPacket(buf); + if (received != len) { + Log.i(TAG, "Reflecting ping did not result in ping response: " + + "read=" + received + " expected=" + len); + return; + } + + // Compare the response we got with the original packet. + // The only thing that should have changed are addresses, type and checksum. + // Overwrite them with the received bytes and see if the packet is otherwise identical. + request[hdrLen] = buf[hdrLen]; // Type. + request[hdrLen + 2] = buf[hdrLen + 2]; // Checksum byte 1. + request[hdrLen + 3] = buf[hdrLen + 3]; // Checksum byte 2. + for (int i = 0; i < len; i++) { + if (buf[i] != request[i]) { + Log.i(TAG, "Received non-matching packet when expecting ping response."); + return; + } + } + + // Now swap the addresses again and reflect the packet. This sends a ping reply. + swapAddresses(buf, version); + writePacket(buf, len); + } + + private void writePacket(byte[] buf, int len) { + try { + Os.write(mFd, buf, 0, len); + } catch (ErrnoException|IOException e) { + Log.e(TAG, "Error writing packet: " + e.getMessage()); + } + } + + private int readPacket(byte[] buf) { + int len; + try { + len = Os.read(mFd, buf, 0, buf.length); + } catch (ErrnoException|IOException e) { + Log.e(TAG, "Error reading packet: " + e.getMessage()); + len = -1; + } + return len; + } + + // Reads one packet from our mFd, and possibly writes the packet back. + private void processPacket() { + int len = readPacket(mBuf); + if (len < 1) { + return; + } + + int version = mBuf[0] >> 4; + int addrPos, protoPos, hdrLen, addrLen; + if (version == 4) { + hdrLen = IPV4_HEADER_LENGTH; + protoPos = IPV4_PROTO_OFFSET; + addrPos = IPV4_ADDR_OFFSET; + addrLen = IPV4_ADDR_LENGTH; + } else if (version == 6) { + hdrLen = IPV6_HEADER_LENGTH; + protoPos = IPV6_PROTO_OFFSET; + addrPos = IPV6_ADDR_OFFSET; + addrLen = IPV6_ADDR_LENGTH; + } else { + return; + } + + if (len < hdrLen) { + return; + } + + byte proto = mBuf[protoPos]; + switch (proto) { + case IPPROTO_ICMP: + case IPPROTO_ICMPV6: + processIcmpPacket(mBuf, version, len, hdrLen); + break; + case IPPROTO_TCP: + processTcpPacket(mBuf, version, len, hdrLen); + break; + case IPPROTO_UDP: + processUdpPacket(mBuf, version, len, hdrLen); + break; + } + } + + public void run() { + Log.i(TAG, "PacketReflector starting fd=" + mFd + " valid=" + mFd.valid()); + while (!interrupted() && mFd.valid()) { + processPacket(); + } + Log.i(TAG, "PacketReflector exiting fd=" + mFd + " valid=" + mFd.valid()); + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/UdpReflector.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/UdpReflector.java deleted file mode 100644 index a730fed08a..0000000000 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/UdpReflector.java +++ /dev/null @@ -1,113 +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 com.android.cts.net.hostside; - -import android.system.Os; -import android.system.ErrnoException; -import android.util.Log; - -import java.io.FileDescriptor; -import java.io.IOException; - -public class UdpReflector extends Thread { - - private static int IPV4_HEADER_LENGTH = 20; - private static int IPV6_HEADER_LENGTH = 40; - private static int UDP_HEADER_LENGTH = 8; - - private static int IPV4_PROTO_OFFSET = 9; - private static int IPV6_PROTO_OFFSET = 6; - private static int IPPROTO_UDP = 17; - - private static int IPV4_ADDR_OFFSET = 12; - private static int IPV6_ADDR_OFFSET = 8; - private static int IPV4_ADDR_LENGTH = 4; - private static int IPV6_ADDR_LENGTH = 16; - - private static String TAG = "UdpReflector"; - - private FileDescriptor mFd; - private byte[] mBuf; - - public UdpReflector(FileDescriptor fd, int mtu) { - super("UdpReflector"); - mFd = fd; - mBuf = new byte[mtu]; - } - - private static void swapBytes(byte[] buf, int pos1, int pos2, int len) { - for (int i = 0; i < len; i++) { - byte b = buf[pos1 + i]; - buf[pos1 + i] = buf[pos2 + i]; - buf[pos2 + i] = b; - } - } - - /** Reads one packet from our mFd, and possibly writes the packet back. */ - private void processPacket() { - int len; - try { - len = Os.read(mFd, mBuf, 0, mBuf.length); - } catch (ErrnoException|IOException e) { - Log.e(TAG, "Error reading packet: " + e.getMessage()); - return; - } - - int version = mBuf[0] >> 4; - int addressOffset, protoOffset, headerLength, addressLength; - if (version == 4) { - headerLength = IPV4_HEADER_LENGTH; - protoOffset = IPV4_PROTO_OFFSET; - addressOffset = IPV4_ADDR_OFFSET; - addressLength = IPV4_ADDR_LENGTH; - } else if (version == 6) { - headerLength = IPV6_HEADER_LENGTH; - protoOffset = IPV6_PROTO_OFFSET; - addressOffset = IPV6_ADDR_OFFSET; - addressLength = IPV6_ADDR_LENGTH; - } else { - return; - } - - if (len < headerLength + UDP_HEADER_LENGTH || mBuf[protoOffset] != IPPROTO_UDP) { - return; - } - - // Swap src and dst IP addresses. - swapBytes(mBuf, addressOffset, addressOffset + addressLength, addressLength); - - // Swap dst and src ports. - int portOffset = headerLength; - swapBytes(mBuf, portOffset, portOffset + 2, 2); - - // Send the packet back. We don't need to recalculate the checksum because we didn't change - // the packet bytes, we only moved them around. - try { - len = Os.write(mFd, mBuf, 0, len); - } catch (ErrnoException|IOException e) { - Log.e(TAG, "Error writing packet: " + e.getMessage()); - } - } - - public void run() { - Log.i(TAG, "UdpReflector starting fd=" + mFd + " valid=" + mFd.valid()); - while (!interrupted() && mFd.valid()) { - processPacket(); - } - Log.i(TAG, "UdpReflector exiting fd=" + mFd + " valid=" + mFd.valid()); - } -} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java index cdd370ee67..8bb2a2c4c5 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java @@ -16,6 +16,8 @@ package com.android.cts.net.hostside; +import static android.system.OsConstants.*; + import android.content.Intent; import android.content.pm.PackageManager; import android.net.ConnectivityManager; @@ -25,34 +27,58 @@ import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkRequest; import android.net.VpnService; -import android.os.ParcelFileDescriptor; -import android.os.SystemClock; import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiObject; import android.support.test.uiautomator.UiObjectNotFoundException; import android.support.test.uiautomator.UiScrollable; import android.support.test.uiautomator.UiSelector; -import android.test.MoreAsserts; +import android.system.ErrnoException; +import android.system.Os; +import android.system.StructPollfd; import android.test.InstrumentationTestCase; +import android.test.MoreAsserts; import android.text.TextUtils; import android.util.Log; +import java.io.Closeable; +import java.io.FileDescriptor; import java.io.IOException; -import java.net.SocketTimeoutException; +import java.io.InputStream; +import java.io.OutputStream; import java.net.DatagramPacket; import java.net.DatagramSocket; -import java.net.InetAddress; import java.net.Inet6Address; -import java.util.concurrent.atomic.AtomicReference; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Random; /** - * Tests for {@link DocumentsProvider} and interaction with platform intents - * like {@link Intent#ACTION_OPEN_DOCUMENT}. + * Tests for the VpnService API. + * + * These tests establish a VPN via the VpnService API, and have the service reflect the packets back + * to the device without causing any network traffic. This allows testing the local VPN data path + * without a network connection or a VPN server. + * + * Note: in Lollipop, VPN functionality relies on kernel support for UID-based routing. If these + * tests fail, it may be due to the lack of kernel support. The necessary patches can be + * cherry-picked from the Android common kernel trees: + * + * android-3.10: + * https://android-review.googlesource.com/#/c/99220/ + * https://android-review.googlesource.com/#/c/100545/ + * + * android-3.4: + * https://android-review.googlesource.com/#/c/99225/ + * https://android-review.googlesource.com/#/c/100557/ + * */ public class VpnTest extends InstrumentationTestCase { public static String TAG = "VpnTest"; public static int TIMEOUT_MS = 3 * 1000; + public static int SOCKET_TIMEOUT_MS = 100; private UiDevice mDevice; private MyActivity mActivity; @@ -201,8 +227,156 @@ public class VpnTest extends InstrumentationTestCase { mActivity.startService(intent); } - private static void checkUdpEcho( - String to, String expectedFrom, boolean expectReply) throws IOException { + private static void closeQuietly(Closeable c) { + if (c != null) { + try { + c.close(); + } catch (IOException e) { + } + } + } + + private static void checkPing(String to) throws IOException, ErrnoException { + InetAddress address = InetAddress.getByName(to); + FileDescriptor s; + final int LENGTH = 64; + byte[] packet = new byte[LENGTH]; + byte[] header; + + // Construct a ping packet. + Random random = new Random(); + random.nextBytes(packet); + if (address instanceof Inet6Address) { + s = Os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6); + header = new byte[] { (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00 }; + } else { + // Note that this doesn't actually work due to http://b/18558481 . + s = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP); + header = new byte[] { (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x00 }; + } + System.arraycopy(header, 0, packet, 0, header.length); + + // Send the packet. + int port = random.nextInt(65534) + 1; + Os.connect(s, address, port); + Os.write(s, packet, 0, packet.length); + + // Expect a reply. + StructPollfd pollfd = new StructPollfd(); + pollfd.events = (short) POLLIN; // "error: possible loss of precision" + pollfd.fd = s; + int ret = Os.poll(new StructPollfd[] { pollfd }, SOCKET_TIMEOUT_MS); + assertEquals("Expected reply after sending ping", 1, ret); + + byte[] reply = new byte[LENGTH]; + int read = Os.read(s, reply, 0, LENGTH); + assertEquals(LENGTH, read); + + // Find out what the kernel set the ICMP ID to. + InetSocketAddress local = (InetSocketAddress) Os.getsockname(s); + port = local.getPort(); + packet[4] = (byte) ((port >> 8) & 0xff); + packet[5] = (byte) (port & 0xff); + + // Check the contents. + if (packet[0] == (byte) 0x80) { + packet[0] = (byte) 0x81; + } else { + packet[0] = 0; + } + // Zero out the checksum in the reply so it matches the uninitialized checksum in packet. + reply[2] = reply[3] = 0; + MoreAsserts.assertEquals(packet, reply); + } + + // Writes data to out and checks that it appears identically on in. + private static void writeAndCheckData( + OutputStream out, InputStream in, byte[] data) throws IOException { + out.write(data, 0, data.length); + out.flush(); + + byte[] read = new byte[data.length]; + int bytesRead = 0, totalRead = 0; + do { + bytesRead = in.read(read, totalRead, read.length - totalRead); + totalRead += bytesRead; + } while (bytesRead >= 0 && totalRead < data.length); + assertEquals(totalRead, data.length); + MoreAsserts.assertEquals(data, read); + } + + private static void checkTcpReflection(String to, String expectedFrom) throws IOException { + // Exercise TCP over the VPN by "connecting to ourselves". We open a server socket and a + // client socket, and connect the client socket to a remote host, with the port of the + // server socket. The PacketReflector reflects the packets, changing the source addresses + // but not the ports, so our client socket is connected to our server socket, though both + // sockets think their peers are on the "remote" IP address. + + // Open a listening socket. + ServerSocket listen = new ServerSocket(0, 10, InetAddress.getByName("::")); + + // Connect the client socket to it. + InetAddress toAddr = InetAddress.getByName(to); + Socket client = new Socket(); + try { + client.connect(new InetSocketAddress(toAddr, listen.getLocalPort()), SOCKET_TIMEOUT_MS); + if (expectedFrom == null) { + closeQuietly(listen); + closeQuietly(client); + fail("Expected connection to fail, but it succeeded."); + } + } catch (IOException e) { + if (expectedFrom != null) { + closeQuietly(listen); + fail("Expected connection to succeed, but it failed."); + } else { + // We expected the connection to fail, and it did, so there's nothing more to test. + return; + } + } + + // The connection succeeded, and we expected it to succeed. Send some data; if things are + // working, the data will be sent to the VPN, reflected by the PacketReflector, and arrive + // at our server socket. For good measure, send some data in the other direction. + Socket server = null; + try { + // Accept the connection on the server side. + listen.setSoTimeout(SOCKET_TIMEOUT_MS); + server = listen.accept(); + + // Check that the source and peer addresses are as expected. + assertEquals(expectedFrom, client.getLocalAddress().getHostAddress()); + assertEquals(expectedFrom, server.getLocalAddress().getHostAddress()); + assertEquals( + new InetSocketAddress(toAddr, client.getLocalPort()), + server.getRemoteSocketAddress()); + assertEquals( + new InetSocketAddress(toAddr, server.getLocalPort()), + client.getRemoteSocketAddress()); + + // Now write some data. + final int LENGTH = 32768; + byte[] data = new byte[LENGTH]; + new Random().nextBytes(data); + + // Make sure our writes don't block or time out, because we're single-threaded and can't + // read and write at the same time. + server.setReceiveBufferSize(LENGTH * 2); + client.setSendBufferSize(LENGTH * 2); + client.setSoTimeout(SOCKET_TIMEOUT_MS); + server.setSoTimeout(SOCKET_TIMEOUT_MS); + + // Send some data from client to server, then from server to client. + writeAndCheckData(client.getOutputStream(), server.getInputStream(), data); + writeAndCheckData(server.getOutputStream(), client.getInputStream(), data); + } finally { + closeQuietly(listen); + closeQuietly(client); + closeQuietly(server); + } + } + + private static void checkUdpEcho(String to, String expectedFrom) throws IOException { DatagramSocket s; InetAddress address = InetAddress.getByName(to); if (address instanceof Inet6Address) { // http://b/18094870 @@ -210,10 +384,12 @@ public class VpnTest extends InstrumentationTestCase { } else { s = new DatagramSocket(); } - s.setSoTimeout(100); // ms. + s.setSoTimeout(SOCKET_TIMEOUT_MS); - String msg = "Hello, world!"; - DatagramPacket p = new DatagramPacket(msg.getBytes(), msg.length()); + Random random = new Random(); + byte[] data = new byte[random.nextInt(1650)]; + random.nextBytes(data); + DatagramPacket p = new DatagramPacket(data, data.length); s.connect(address, 7); if (expectedFrom != null) { @@ -222,10 +398,10 @@ public class VpnTest extends InstrumentationTestCase { } try { - if (expectReply) { + if (expectedFrom != null) { s.send(p); s.receive(p); - MoreAsserts.assertEquals(msg.getBytes(), p.getData()); + MoreAsserts.assertEquals(data, p.getData()); } else { try { s.send(p); @@ -238,12 +414,19 @@ public class VpnTest extends InstrumentationTestCase { } } - private static void expectUdpEcho(String to, String expectedFrom) throws IOException { - checkUdpEcho(to, expectedFrom, true); + private void checkTrafficOnVpn() throws IOException, ErrnoException { + checkUdpEcho("192.0.2.251", "192.0.2.2"); + checkUdpEcho("2001:db8:dead:beef::f00", "2001:db8:1:2::ffe"); + checkPing("2001:db8:dead:beef::f00"); + checkTcpReflection("192.0.2.252", "192.0.2.2"); + checkTcpReflection("2001:db8:dead:beef::f00", "2001:db8:1:2::ffe"); } - private static void expectNoUdpEcho(String to) throws IOException { - checkUdpEcho(to, null, false); + private void checkNoTrafficOnVpn() throws IOException, ErrnoException { + checkUdpEcho("192.0.2.251", null); + checkUdpEcho("2001:db8:dead:beef::f00", null); + checkTcpReflection("192.0.2.252", null); + checkTcpReflection("2001:db8:dead:beef::f00", null); } public void testDefault() throws Exception { @@ -253,8 +436,7 @@ public class VpnTest extends InstrumentationTestCase { new String[] {"192.0.2.0/24", "2001:db8::/32"}, "", ""); - expectUdpEcho("192.0.2.251", "192.0.2.2"); - expectUdpEcho("2001:db8:dead:beef::f00", "2001:db8:1:2::ffe"); + checkTrafficOnVpn(); } public void testAppAllowed() throws Exception { @@ -264,8 +446,7 @@ public class VpnTest extends InstrumentationTestCase { new String[] {"0.0.0.0/0", "::/0"}, mPackageName, ""); - expectUdpEcho("192.0.2.251", "192.0.2.2"); - expectUdpEcho("2001:db8:dead:beef::f00", "2001:db8:1:2::ffe"); + checkTrafficOnVpn(); } public void testAppDisallowed() throws Exception { @@ -275,7 +456,6 @@ public class VpnTest extends InstrumentationTestCase { new String[] {"192.0.2.0/24", "2001:db8::/32"}, "", mPackageName); - expectNoUdpEcho("192.0.2.251"); - expectNoUdpEcho("2001:db8:dead:beef::f00"); + checkNoTrafficOnVpn(); } } From 51130c9726d50609d84d212dd0a54917ef2a9386 Mon Sep 17 00:00:00 2001 From: Neil Fuller Date: Thu, 15 Jan 2015 15:54:04 +0000 Subject: [PATCH 0151/1109] Add HttpResponseCacheTest as a CTS test Moving HttpResponseCacheTest.java from frameworks/base/core/tests/coretests/src/android/net/http to cts/tests/tests/net/src/android/net/http/cts And making it work in the CTS runner by setting temp directory permissions and making sure the cache is initialized. Change-Id: I032014789f27a66c1a7a0aee0fa0494f6041238e --- tests/cts/net/Android.mk | 6 +- .../net/http/cts/HttpResponseCacheTest.java | 158 ++++++++++++++++++ 2 files changed, 161 insertions(+), 3 deletions(-) create mode 100644 tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index 46d4d819ac..f6e5c90951 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -26,15 +26,15 @@ LOCAL_MULTILIB := both LOCAL_JAVA_LIBRARIES := voip-common conscrypt -LOCAL_JNI_SHARED_LIBRARIES := libnativedns_jni +LOCAL_JNI_SHARED_LIBRARIES := libcts_jni libnativedns_jni # include CtsTestServer as a temporary hack to free net.cts from cts.stub. LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := CtsNetTestCases -LOCAL_STATIC_JAVA_LIBRARIES := ctstestserver ctsdeviceutil ctstestrunner \ - core-tests-support +LOCAL_STATIC_JAVA_LIBRARIES := core-tests-support ctsdeviceutil \ + ctstestrunner ctstestserver mockwebserver # uncomment when b/13249961 is fixed #LOCAL_SDK_VERSION := current diff --git a/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java b/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java new file mode 100644 index 0000000000..545541d68b --- /dev/null +++ b/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2011 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.http.cts; + +import com.google.mockwebserver.MockResponse; +import com.google.mockwebserver.MockWebServer; + +import junit.framework.TestCase; + +import android.cts.util.FileUtils; +import android.net.http.HttpResponseCache; + +import java.io.File; +import java.io.InputStream; +import java.net.CacheRequest; +import java.net.CacheResponse; +import java.net.ResponseCache; +import java.net.URI; +import java.net.URLConnection; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +public final class HttpResponseCacheTest extends TestCase { + + private File cacheDir; + private MockWebServer server = new MockWebServer(); + + @Override public void setUp() throws Exception { + super.setUp(); + String tmp = System.getProperty("java.io.tmpdir"); + cacheDir = new File(tmp, "HttpCache-" + UUID.randomUUID()); + cacheDir.mkdirs(); + // Make the cache directory read / writable. + FileUtils.setPermissions(cacheDir.getPath(), 0777); + } + + @Override protected void tearDown() throws Exception { + ResponseCache.setDefault(null); + server.shutdown(); + super.tearDown(); + } + + public void testInstall() throws Exception { + HttpResponseCache installed = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024); + assertNotNull(installed); + assertSame(installed, ResponseCache.getDefault()); + assertSame(installed, HttpResponseCache.getDefault()); + } + + public void testSecondEquivalentInstallDoesNothing() throws Exception { + HttpResponseCache first = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024); + HttpResponseCache another = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024); + assertSame(first, another); + } + + public void testInstallClosesPreviouslyInstalled() throws Exception { + HttpResponseCache first = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024); + initializeCache(first); + + HttpResponseCache another = HttpResponseCache.install(cacheDir, 8 * 1024 * 1024); + initializeCache(first); + + assertNotSame(first, another); + try { + first.flush(); + fail(); + } catch (IllegalStateException expected) { + } + } + + public void testGetInstalledWithWrongTypeInstalled() { + ResponseCache.setDefault(new ResponseCache() { + @Override public CacheResponse get(URI uri, String requestMethod, + Map> requestHeaders) { + return null; + } + @Override public CacheRequest put(URI uri, URLConnection connection) { + return null; + } + }); + assertNull(HttpResponseCache.getInstalled()); + } + + public void testCloseCloses() throws Exception { + HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024); + initializeCache(cache); + + cache.close(); + try { + cache.flush(); + fail(); + } catch (IllegalStateException expected) { + } + } + + public void testCloseUninstalls() throws Exception { + HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024); + cache.close(); + assertNull(ResponseCache.getDefault()); + } + + public void testDeleteUninstalls() throws Exception { + HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024); + cache.delete(); + assertNull(ResponseCache.getDefault()); + } + + /** + * Make sure that statistics tracking are wired all the way through the + * wrapper class. http://code.google.com/p/android/issues/detail?id=25418 + */ + public void testStatisticsTracking() throws Exception { + HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024); + + server.enqueue(new MockResponse() + .addHeader("Cache-Control: max-age=60") + .setBody("A")); + server.play(); + + URLConnection c1 = server.getUrl("/").openConnection(); + InputStream inputStream1 = c1.getInputStream(); + assertEquals('A', inputStream1.read()); + inputStream1.close(); + + assertEquals(1, cache.getRequestCount()); + assertEquals(1, cache.getNetworkCount()); + assertEquals(0, cache.getHitCount()); + + URLConnection c2 = server.getUrl("/").openConnection(); + assertEquals('A', c2.getInputStream().read()); + + URLConnection c3 = server.getUrl("/").openConnection(); + assertEquals('A', c3.getInputStream().read()); + assertEquals(3, cache.getRequestCount()); + assertEquals(1, cache.getNetworkCount()); + assertEquals(2, cache.getHitCount()); + } + + private void initializeCache(HttpResponseCache cache) { + // Ensure the cache is initialized, otherwise various methods are no-ops. + cache.size(); + } +} From 970cbe09b59d9d8f2cd3207b432f2eb07741d454 Mon Sep 17 00:00:00 2001 From: Filip Matusiak Date: Thu, 15 Jan 2015 17:48:07 +0100 Subject: [PATCH 0152/1109] Accept more than one SD in NsdManagerTest In current implementation it's been assumed that there will be only one interface registered for service discovery in mdnsresponder. In reality there's possibility that some real but currently unused interfaces will have link-local address assigned prior to registration, which will cause mdnsresponder to register these interfaces for service discovery. This will result in SERVICE_LOST and SERVICE_FOUND events to be received more than one time. Current test implementation is not 100% prone for this situation - depending upon time gap between both events it can PASS or FAIL. Fix by removing an assert on number of received events. Change-Id: I147dc4d600f41f6d63d2b9e4bcb10efe90d5b3ec --- tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java index d1e4c447c3..95e0495746 100644 --- a/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java @@ -372,8 +372,6 @@ public class NsdManagerTest extends AndroidTestCase { assertTrue(lastEvent != null); assertTrue(lastEvent.mInfo.getServiceName().equals(registeredName)); - assertTrue(eventCacheSize() == 2); - // Register service again to see if we discover it checkForAdditionalEvents(); clearEventCache(); @@ -405,7 +403,6 @@ public class NsdManagerTest extends AndroidTestCase { lastEvent.mInfo.getServiceName()); assertTrue(lastEvent.mInfo.getServiceName().equals(registeredName)); - assertTrue(checkCacheSize(2)); checkForAdditionalEvents(); clearEventCache(); From 013161a64ab996e0b7cc18251e6af19de8cedbbf Mon Sep 17 00:00:00 2001 From: Takayuki Hoshi Date: Tue, 20 Jan 2015 14:40:11 +0900 Subject: [PATCH 0153/1109] Normalize ipv6.cts.PingTest#testLoopbackPing's packet size Bug: 19063377 Change-Id: I8c7b2253cfa5c81afbc6c4de05f2965f4184b683 --- tests/cts/net/src/android/net/ipv6/cts/PingTest.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/ipv6/cts/PingTest.java b/tests/cts/net/src/android/net/ipv6/cts/PingTest.java index 49fc59c716..582b81ae6a 100644 --- a/tests/cts/net/src/android/net/ipv6/cts/PingTest.java +++ b/tests/cts/net/src/android/net/ipv6/cts/PingTest.java @@ -53,6 +53,9 @@ public class PingTest extends AndroidTestCase { /** Maximum size of the packets we're using to test. */ private static final int MAX_SIZE = 4096; + /** Size of the ICMPv6 header. */ + private static final int ICMP_HEADER_SIZE = 8; + /** Number of packets to test. */ private static final int NUM_PACKETS = 10; @@ -65,7 +68,7 @@ public class PingTest extends AndroidTestCase { * Returns a byte array containing an ICMPv6 echo request with the specified payload length. */ private byte[] pingPacket(int payloadLength) { - byte[] packet = new byte[payloadLength + 8]; + byte[] packet = new byte[payloadLength + ICMP_HEADER_SIZE]; new Random().nextBytes(packet); System.arraycopy(PING_HEADER, 0, packet, 0, PING_HEADER.length); return packet; @@ -154,7 +157,7 @@ public class PingTest extends AndroidTestCase { assertEquals("localhost/::1", ipv6Loopback.toString()); for (int i = 0; i < NUM_PACKETS; i++) { - byte[] packet = pingPacket((int) (Math.random() * MAX_SIZE)); + byte[] packet = pingPacket((int) (Math.random() * (MAX_SIZE - ICMP_HEADER_SIZE))); FileDescriptor s = createPingSocket(); // Use both recvfrom and read(). sendPing(s, ipv6Loopback, packet); From 17e2c23ad30c5ec6f911bf53939f2a6e66776bf8 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Thu, 29 Jan 2015 23:02:17 -0800 Subject: [PATCH 0154/1109] Add missing include. Change-Id: I2a52d050a39e2c6dd38af868ea444278d9b6d54d --- tests/cts/net/jni/NativeDnsJni.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/cts/net/jni/NativeDnsJni.c b/tests/cts/net/jni/NativeDnsJni.c index b975594b26..4eb3c7aebc 100644 --- a/tests/cts/net/jni/NativeDnsJni.c +++ b/tests/cts/net/jni/NativeDnsJni.c @@ -18,6 +18,7 @@ #include #include #include +#include #include const char *GoogleDNSIpV4Address="8.8.8.8"; From 505728b35af4617c647fec742b8eaeadd4009894 Mon Sep 17 00:00:00 2001 From: Narayan Kamath Date: Fri, 12 Dec 2014 10:55:51 +0000 Subject: [PATCH 0155/1109] Add explicit dependencies on org.apache.http.legacy Test modules that depend on the CTS testserver must declare explicit dependencies on org.apache.http.legacy. Also fix some bizarre build rules; ctstestserver builds directly against the framework but compiled into apps that target SDK 16. bug: 18027885 Change-Id: I905942d8ed71812499df94e3e5970c0b08716528 --- tests/cts/net/Android.mk | 2 +- tests/cts/net/AndroidManifest.xml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index f6e5c90951..a35e145e5f 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -24,7 +24,7 @@ LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) # Include both the 32 and 64 bit versions LOCAL_MULTILIB := both -LOCAL_JAVA_LIBRARIES := voip-common conscrypt +LOCAL_JAVA_LIBRARIES := voip-common conscrypt org.apache.http.legacy LOCAL_JNI_SHARED_LIBRARIES := libcts_jni libnativedns_jni diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index 652262d491..bca2d2c1ba 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -30,6 +30,7 @@ + Date: Wed, 4 Feb 2015 10:37:07 -0800 Subject: [PATCH 0156/1109] Split the build of the CTS infrastructure from the tests. This allows developers to build the test packages individually without needing to build the entire CTS release. Add new build target for support packages bug: 18945639 Change-Id: I60b79797b2d254b96aa98f88cfd5b19d195ea982 --- tests/cts/hostside/app/Android.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/hostside/app/Android.mk b/tests/cts/hostside/app/Android.mk index 29b620d2c3..055287a733 100644 --- a/tests/cts/hostside/app/Android.mk +++ b/tests/cts/hostside/app/Android.mk @@ -29,4 +29,4 @@ LOCAL_PACKAGE_NAME := CtsHostsideNetworkTestsApp LOCAL_PROGUARD_ENABLED := disabled LOCAL_DEX_PREOPT := false -include $(BUILD_PACKAGE) +include $(BUILD_CTS_SUPPORT_PACKAGE) From cbdec383f28a9b11795b0fceab58c72cfac769ff Mon Sep 17 00:00:00 2001 From: Qiwen Zhao Date: Mon, 30 Mar 2015 10:51:01 -0700 Subject: [PATCH 0157/1109] DO NOT MERGE ANYWHERE. Revert "DO NOT MERGE ANYWHERE." This reverts commit b7c798f9b84c7c100aa37e6aa77e7f31460c7bd7, reversing changes made to 4e8ecc32db5d3a17ccec099681425c34b630d23b. --- tests/cts/net/Android.mk | 6 +- tests/cts/net/jni/NativeDnsJni.c | 1 - .../src/android/net/cts/LocalSocketTest.java | 4 +- .../cts/SSLCertificateSocketFactoryTest.java | 4 +- .../net/http/cts/HttpResponseCacheTest.java | 158 ------------------ .../android/net/wifi/cts/NsdManagerTest.java | 3 + 6 files changed, 10 insertions(+), 166 deletions(-) delete mode 100644 tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index f6e5c90951..46d4d819ac 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -26,15 +26,15 @@ LOCAL_MULTILIB := both LOCAL_JAVA_LIBRARIES := voip-common conscrypt -LOCAL_JNI_SHARED_LIBRARIES := libcts_jni libnativedns_jni +LOCAL_JNI_SHARED_LIBRARIES := libnativedns_jni # include CtsTestServer as a temporary hack to free net.cts from cts.stub. LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := CtsNetTestCases -LOCAL_STATIC_JAVA_LIBRARIES := core-tests-support ctsdeviceutil \ - ctstestrunner ctstestserver mockwebserver +LOCAL_STATIC_JAVA_LIBRARIES := ctstestserver ctsdeviceutil ctstestrunner \ + core-tests-support # uncomment when b/13249961 is fixed #LOCAL_SDK_VERSION := current diff --git a/tests/cts/net/jni/NativeDnsJni.c b/tests/cts/net/jni/NativeDnsJni.c index 4eb3c7aebc..b975594b26 100644 --- a/tests/cts/net/jni/NativeDnsJni.c +++ b/tests/cts/net/jni/NativeDnsJni.c @@ -18,7 +18,6 @@ #include #include #include -#include #include const char *GoogleDNSIpV4Address="8.8.8.8"; diff --git a/tests/cts/net/src/android/net/cts/LocalSocketTest.java b/tests/cts/net/src/android/net/cts/LocalSocketTest.java index 865ec21da3..0a4bc0d4f2 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketTest.java @@ -126,8 +126,8 @@ public class LocalSocketTest extends AndroidTestCase{ socket.setReceiveBufferSize(1999); assertEquals(1999 << 1, socket.getReceiveBufferSize()); - socket.setSendBufferSize(3998); - assertEquals(3998 << 1, socket.getSendBufferSize()); + socket.setSendBufferSize(1998); + assertEquals(1998 << 1, socket.getSendBufferSize()); // Timeout is not support at present, so set is ignored socket.setSoTimeout(1996); diff --git a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java index 60ac226440..6175923e46 100644 --- a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java +++ b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java @@ -26,7 +26,7 @@ import javax.net.ssl.SSLPeerUnverifiedException; import android.net.SSLCertificateSocketFactory; import android.test.AndroidTestCase; -import libcore.javax.net.ssl.SSLConfigurationAsserts; +import libcore.javax.net.ssl.SSLDefaultConfigurationAsserts; public class SSLCertificateSocketFactoryTest extends AndroidTestCase { private SSLCertificateSocketFactory mFactory; @@ -40,7 +40,7 @@ public class SSLCertificateSocketFactoryTest extends AndroidTestCase { } public void testDefaultConfiguration() throws Exception { - SSLConfigurationAsserts.assertSSLSocketFactoryDefaultConfiguration(mFactory); + SSLDefaultConfigurationAsserts.assertSSLSocketFactory(mFactory); } public void testAccessProperties() throws Exception { diff --git a/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java b/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java deleted file mode 100644 index 545541d68b..0000000000 --- a/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2011 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.http.cts; - -import com.google.mockwebserver.MockResponse; -import com.google.mockwebserver.MockWebServer; - -import junit.framework.TestCase; - -import android.cts.util.FileUtils; -import android.net.http.HttpResponseCache; - -import java.io.File; -import java.io.InputStream; -import java.net.CacheRequest; -import java.net.CacheResponse; -import java.net.ResponseCache; -import java.net.URI; -import java.net.URLConnection; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -public final class HttpResponseCacheTest extends TestCase { - - private File cacheDir; - private MockWebServer server = new MockWebServer(); - - @Override public void setUp() throws Exception { - super.setUp(); - String tmp = System.getProperty("java.io.tmpdir"); - cacheDir = new File(tmp, "HttpCache-" + UUID.randomUUID()); - cacheDir.mkdirs(); - // Make the cache directory read / writable. - FileUtils.setPermissions(cacheDir.getPath(), 0777); - } - - @Override protected void tearDown() throws Exception { - ResponseCache.setDefault(null); - server.shutdown(); - super.tearDown(); - } - - public void testInstall() throws Exception { - HttpResponseCache installed = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024); - assertNotNull(installed); - assertSame(installed, ResponseCache.getDefault()); - assertSame(installed, HttpResponseCache.getDefault()); - } - - public void testSecondEquivalentInstallDoesNothing() throws Exception { - HttpResponseCache first = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024); - HttpResponseCache another = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024); - assertSame(first, another); - } - - public void testInstallClosesPreviouslyInstalled() throws Exception { - HttpResponseCache first = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024); - initializeCache(first); - - HttpResponseCache another = HttpResponseCache.install(cacheDir, 8 * 1024 * 1024); - initializeCache(first); - - assertNotSame(first, another); - try { - first.flush(); - fail(); - } catch (IllegalStateException expected) { - } - } - - public void testGetInstalledWithWrongTypeInstalled() { - ResponseCache.setDefault(new ResponseCache() { - @Override public CacheResponse get(URI uri, String requestMethod, - Map> requestHeaders) { - return null; - } - @Override public CacheRequest put(URI uri, URLConnection connection) { - return null; - } - }); - assertNull(HttpResponseCache.getInstalled()); - } - - public void testCloseCloses() throws Exception { - HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024); - initializeCache(cache); - - cache.close(); - try { - cache.flush(); - fail(); - } catch (IllegalStateException expected) { - } - } - - public void testCloseUninstalls() throws Exception { - HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024); - cache.close(); - assertNull(ResponseCache.getDefault()); - } - - public void testDeleteUninstalls() throws Exception { - HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024); - cache.delete(); - assertNull(ResponseCache.getDefault()); - } - - /** - * Make sure that statistics tracking are wired all the way through the - * wrapper class. http://code.google.com/p/android/issues/detail?id=25418 - */ - public void testStatisticsTracking() throws Exception { - HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024); - - server.enqueue(new MockResponse() - .addHeader("Cache-Control: max-age=60") - .setBody("A")); - server.play(); - - URLConnection c1 = server.getUrl("/").openConnection(); - InputStream inputStream1 = c1.getInputStream(); - assertEquals('A', inputStream1.read()); - inputStream1.close(); - - assertEquals(1, cache.getRequestCount()); - assertEquals(1, cache.getNetworkCount()); - assertEquals(0, cache.getHitCount()); - - URLConnection c2 = server.getUrl("/").openConnection(); - assertEquals('A', c2.getInputStream().read()); - - URLConnection c3 = server.getUrl("/").openConnection(); - assertEquals('A', c3.getInputStream().read()); - assertEquals(3, cache.getRequestCount()); - assertEquals(1, cache.getNetworkCount()); - assertEquals(2, cache.getHitCount()); - } - - private void initializeCache(HttpResponseCache cache) { - // Ensure the cache is initialized, otherwise various methods are no-ops. - cache.size(); - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java index e132cce25f..d43472805b 100644 --- a/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java @@ -372,6 +372,8 @@ public class NsdManagerTest extends AndroidTestCase { assertTrue(lastEvent != null); assertTrue(lastEvent.mInfo.getServiceName().equals(registeredName)); + assertTrue(eventCacheSize() == 2); + // Register service again to see if we discover it checkForAdditionalEvents(); clearEventCache(); @@ -403,6 +405,7 @@ public class NsdManagerTest extends AndroidTestCase { lastEvent.mInfo.getServiceName()); assertTrue(lastEvent.mInfo.getServiceName().equals(registeredName)); + assertTrue(checkCacheSize(2)); checkForAdditionalEvents(); clearEventCache(); From b1f33d49d0cb0601ff633a5237b3ac4e23355e67 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Mon, 18 May 2015 11:56:32 +0900 Subject: [PATCH 0158/1109] Unbreak PingTest. The test is failing because it expects ::1" to resolve to "localhost", but it now resolves to "ip6-localhost". Bug: 18791191 Bug: 19953381 Change-Id: I62279b6219c32e817253c686bf408f0a2fc1fa6b --- tests/cts/net/src/android/net/ipv6/cts/PingTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/ipv6/cts/PingTest.java b/tests/cts/net/src/android/net/ipv6/cts/PingTest.java index eddb416972..c23ad30f05 100644 --- a/tests/cts/net/src/android/net/ipv6/cts/PingTest.java +++ b/tests/cts/net/src/android/net/ipv6/cts/PingTest.java @@ -155,7 +155,7 @@ public class PingTest extends AndroidTestCase { public void testLoopbackPing() throws ErrnoException, IOException { // Generate a random ping packet and send it to localhost. InetAddress ipv6Loopback = InetAddress.getByName(null); - assertEquals("localhost/::1", ipv6Loopback.toString()); + assertEquals("::1", ipv6Loopback.getHostAddress()); for (int i = 0; i < NUM_PACKETS; i++) { byte[] packet = pingPacket((int) (Math.random() * (MAX_SIZE - ICMP_HEADER_SIZE))); From 9288414c301d559df739a635453b2ef9db740d22 Mon Sep 17 00:00:00 2001 From: Constantin Musca Date: Fri, 23 May 2014 14:20:29 +0300 Subject: [PATCH 0159/1109] LocalSocketTest.testAccessors: fix the *SendBufferSize* test If one sets a *SendBufferSize* value which is less than (2048 + SKB_DATA_ALIGN(sizeof(struct sk_buff))) then the value retrieved will be (2 * (2048 + SKB_DATA_ALIGN(sizeof(struct sk_buff)))). Otherwise, the value will be doubled. Modify the test to consider both cases. Change-Id: I2d89393b1ad441783c8a082b072a806b8901830c Signed-off-by: Constantin Musca --- .../cts/net/src/android/net/cts/LocalSocketTest.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/LocalSocketTest.java b/tests/cts/net/src/android/net/cts/LocalSocketTest.java index 0a4bc0d4f2..70d69c8aa3 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketTest.java @@ -112,6 +112,7 @@ public class LocalSocketTest extends AndroidTestCase{ } public void testAccessors() throws IOException{ + final int INITIAL_SEND_BUFFER_SIZE = 1998; LocalSocket socket = new LocalSocket(); LocalSocketAddress addr = new LocalSocketAddress("secondary"); @@ -126,8 +127,14 @@ public class LocalSocketTest extends AndroidTestCase{ socket.setReceiveBufferSize(1999); assertEquals(1999 << 1, socket.getReceiveBufferSize()); - socket.setSendBufferSize(1998); - assertEquals(1998 << 1, socket.getSendBufferSize()); + socket.setSendBufferSize(INITIAL_SEND_BUFFER_SIZE); + int sendBufferSize = socket.getSendBufferSize(); + if ((INITIAL_SEND_BUFFER_SIZE << 1) < sendBufferSize) { + socket.setSendBufferSize(sendBufferSize / 2); + assertEquals(sendBufferSize, socket.getSendBufferSize()); + } else { + assertEquals(INITIAL_SEND_BUFFER_SIZE << 1, sendBufferSize); + } // Timeout is not support at present, so set is ignored socket.setSoTimeout(1996); From 5aae92d233392c8a710f2a3a39baead3c7b909b8 Mon Sep 17 00:00:00 2001 From: Filip Matusiak Date: Thu, 15 Jan 2015 17:48:07 +0100 Subject: [PATCH 0160/1109] Accept more than one SD in NsdManagerTest In current implementation it's been assumed that there will be only one interface registered for service discovery in mdnsresponder. In reality there's possibility that some real but currently unused interfaces will have link-local address assigned prior to registration, which will cause mdnsresponder to register these interfaces for service discovery. This will result in SERVICE_LOST and SERVICE_FOUND events to be received more than one time. Current test implementation is not 100% prone for this situation - depending upon time gap between both events it can PASS or FAIL. Fix by removing an assert on number of received events. Change-Id: I147dc4d600f41f6d63d2b9e4bcb10efe90d5b3ec (cherry picked from commit 970cbe09b59d9d8f2cd3207b432f2eb07741d454) --- tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java index d43472805b..e132cce25f 100644 --- a/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java @@ -372,8 +372,6 @@ public class NsdManagerTest extends AndroidTestCase { assertTrue(lastEvent != null); assertTrue(lastEvent.mInfo.getServiceName().equals(registeredName)); - assertTrue(eventCacheSize() == 2); - // Register service again to see if we discover it checkForAdditionalEvents(); clearEventCache(); @@ -405,7 +403,6 @@ public class NsdManagerTest extends AndroidTestCase { lastEvent.mInfo.getServiceName()); assertTrue(lastEvent.mInfo.getServiceName().equals(registeredName)); - assertTrue(checkCacheSize(2)); checkForAdditionalEvents(); clearEventCache(); From fe5e165d399946ac7da71767abffa1b7e7456698 Mon Sep 17 00:00:00 2001 From: Junjie Hu Date: Thu, 23 Apr 2015 19:33:01 +0800 Subject: [PATCH 0161/1109] Fix testVpn timing issue for com.android.cts.net.HostsideNetworkTests class It is a issue caused by bad test case. Please ensure the previous vpn connection is disconnected before running next vpn test case, this will affect the test result.And the CTS test case also tries to connect socket before the vpn rule is set in netd. It is the same issue as http://b/18436087 . The delay 300ms is too short, and recommend extend to 1000 or 3000 ms. Since L MR1 is known as supporting some low memory device, we suggest fixing the new CTS test case for some low-end devices. Change-Id: I6051c95c663e867fc66c580ce8bd8d25fce0b8fc Signed-off-by: Junjie Hu --- .../com/android/cts/net/hostside/VpnTest.java | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) mode change 100644 => 100755 tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java old mode 100644 new mode 100755 index 8bb2a2c4c5..5045cc26b4 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java @@ -87,6 +87,7 @@ public class VpnTest extends InstrumentationTestCase { Network mNetwork; NetworkCallback mCallback; final Object mLock = new Object(); + final Object mLockShutdown = new Object(); private boolean supportedHardware() { final PackageManager pm = getInstrumentation().getContext().getPackageManager(); @@ -204,7 +205,9 @@ public class VpnTest extends InstrumentationTestCase { mActivity.startService(intent); synchronized (mLock) { if (mNetwork == null) { + Log.i(TAG, "bf mLock"); mLock.wait(TIMEOUT_MS); + Log.i(TAG, "af mLock"); } } @@ -214,10 +217,27 @@ public class VpnTest extends InstrumentationTestCase { // Unfortunately, when the available callback fires, the VPN UID ranges are not yet // configured. Give the system some time to do so. http://b/18436087 . - try { Thread.sleep(300); } catch(InterruptedException e) {} + try { Thread.sleep(3000); } catch(InterruptedException e) {} } private void stopVpn() { + // Register a callback so we will be notified when our VPN comes up. + final NetworkRequest request = new NetworkRequest.Builder() + .addTransportType(NetworkCapabilities.TRANSPORT_VPN) + .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) + .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + .build(); + mCallback = new NetworkCallback() { + public void onLost(Network network) { + synchronized (mLockShutdown) { + Log.i(TAG, "Got lost callback for network=" + network + ",mNetwork = " + mNetwork); + if( mNetwork == network){ + mLockShutdown.notify(); + } + } + } + }; + mCM.registerNetworkCallback(request, mCallback); // Unregistered in tearDown. // Simply calling mActivity.stopService() won't stop the service, because the system binds // to the service for the purpose of sending it a revoke command if another VPN comes up, // and stopping a bound service has no effect. Instead, "start" the service again with an @@ -225,6 +245,13 @@ public class VpnTest extends InstrumentationTestCase { Intent intent = new Intent(mActivity, MyVpnService.class) .putExtra(mPackageName + ".cmd", "disconnect"); mActivity.startService(intent); + synchronized (mLockShutdown) { + try { + Log.i(TAG, "bf mLockShutdown"); + mLockShutdown.wait(TIMEOUT_MS); + Log.i(TAG, "af mLockShutdown"); + } catch(InterruptedException e) {} + } } private static void closeQuietly(Closeable c) { @@ -433,7 +460,7 @@ public class VpnTest extends InstrumentationTestCase { if (!supportedHardware()) return; startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"}, - new String[] {"192.0.2.0/24", "2001:db8::/32"}, + new String[] {"0.0.0.0/0", "::/0"}, "", ""); checkTrafficOnVpn(); @@ -443,7 +470,7 @@ public class VpnTest extends InstrumentationTestCase { if (!supportedHardware()) return; startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"}, - new String[] {"0.0.0.0/0", "::/0"}, + new String[] {"192.0.2.0/24", "2001:db8::/32"}, mPackageName, ""); checkTrafficOnVpn(); From b38eedcb8f7f3e88563639f693ea35b4c90b7f86 Mon Sep 17 00:00:00 2001 From: Neil Fuller Date: Thu, 18 Jun 2015 13:57:17 +0100 Subject: [PATCH 0162/1109] Remove cell / wifi manipulation from ApacheHttpClientTest The testcase was manipulating the Wifi / Cell networks, presumably in an effort to make data pass over each type of network. The test was sending / receiving data using the loopback interface so it doesn't make much sense. testExecute_withMobile would fail if the device did not have a SIM / mobile data connection *and* if the wifi network was up when the test ran; it would fail waiting for the mobile data network to enter the CONNECTED state. If the wifi connection was down at the start it would assume the mobile data connection was up already and proceed with the test (which passed, because it didn't actually use the network). This change chops out parts of this test to leave just HttpClient-related code. Bug: 21874093 Change-Id: I8248b840f58f939661eff2345f70a9e786e593f3 --- .../net/http/cts/ApacheHttpClientTest.java | 121 +----------------- 1 file changed, 2 insertions(+), 119 deletions(-) diff --git a/tests/cts/net/src/android/net/http/cts/ApacheHttpClientTest.java b/tests/cts/net/src/android/net/http/cts/ApacheHttpClientTest.java index 7d9189ff33..2e5306df89 100644 --- a/tests/cts/net/src/android/net/http/cts/ApacheHttpClientTest.java +++ b/tests/cts/net/src/android/net/http/cts/ApacheHttpClientTest.java @@ -21,56 +21,27 @@ import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.net.NetworkInfo.State; import android.net.Uri; -import android.net.wifi.WifiManager; import android.test.AndroidTestCase; -import android.util.Log; import android.webkit.cts.CtsTestServer; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; public class ApacheHttpClientTest extends AndroidTestCase { - private static final String TAG = ApacheHttpClientTest.class.getSimpleName(); - private static final int NUM_DOWNLOADS = 20; private static final int SMALL_DOWNLOAD_SIZE = 100 * 1024; private CtsTestServer mWebServer; - private WifiManager mWifiManager; - - private ConnectivityManager mConnectivityManager; - - private boolean mHasTelephony; - - private boolean mHasWifi; - @Override protected void setUp() throws Exception { super.setUp(); mWebServer = new CtsTestServer(mContext); - mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); - mConnectivityManager = (ConnectivityManager) - mContext.getSystemService(Context.CONNECTIVITY_SERVICE); - - PackageManager packageManager = mContext.getPackageManager(); - mHasTelephony = packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY); - mHasWifi = packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI); } @Override @@ -79,25 +50,8 @@ public class ApacheHttpClientTest extends AndroidTestCase { mWebServer.shutdown(); } - public void testExecute_withMobile() throws Exception { - if (mHasTelephony) { - disconnectWifiToConnectToMobile(); - } - + public void testExecute() throws Exception { downloadMultipleFiles(); - - if (mHasWifi) { - connectToWifi(); - } - } - - public void testExecute_withWifi() throws Exception { - if (mHasWifi) { - if (!mWifiManager.isWifiEnabled()) { - connectToWifi(); - } - downloadMultipleFiles(); - } } private void downloadMultipleFiles() throws ClientProtocolException, IOException { @@ -134,77 +88,6 @@ public class ApacheHttpClientTest extends AndroidTestCase { numBytes += bytesRead; } } - assertEquals(message, SMALL_DOWNLOAD_SIZE, numBytes); - } - - private void connectToWifi() throws InterruptedException { - if (!mWifiManager.isWifiEnabled()) { - ConnectivityActionReceiver receiver = - new ConnectivityActionReceiver(ConnectivityManager.TYPE_WIFI, State.CONNECTED); - IntentFilter filter = new IntentFilter(); - filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); - mContext.registerReceiver(receiver, filter); - - assertTrue(mWifiManager.setWifiEnabled(true)); - assertTrue("Wifi must be configured to connect to an access point for this test.", - receiver.waitForStateChange()); - - mContext.unregisterReceiver(receiver); - } - } - - private void disconnectWifiToConnectToMobile() throws InterruptedException { - if (mHasWifi && mWifiManager.isWifiEnabled()) { - ConnectivityActionReceiver connectMobileReceiver = - new ConnectivityActionReceiver(ConnectivityManager.TYPE_MOBILE, - State.CONNECTED); - ConnectivityActionReceiver disconnectWifiReceiver = - new ConnectivityActionReceiver(ConnectivityManager.TYPE_WIFI, - State.DISCONNECTED); - IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); - mContext.registerReceiver(connectMobileReceiver, filter); - mContext.registerReceiver(disconnectWifiReceiver, filter); - - assertTrue(mWifiManager.setWifiEnabled(false)); - assertTrue(disconnectWifiReceiver.waitForStateChange()); - assertTrue(connectMobileReceiver.waitForStateChange()); - - mContext.unregisterReceiver(connectMobileReceiver); - mContext.unregisterReceiver(disconnectWifiReceiver); - } - } - - /** Receiver that captures the last connectivity change's network type and state. */ - private class ConnectivityActionReceiver extends BroadcastReceiver { - - private final CountDownLatch mReceiveLatch = new CountDownLatch(1); - - private final int mNetworkType; - - private final State mExpectedState; - - ConnectivityActionReceiver(int networkType, State expectedState) { - mNetworkType = networkType; - mExpectedState = expectedState; - } - - public void onReceive(Context context, Intent intent) { - NetworkInfo networkInfo = intent.getExtras() - .getParcelable(ConnectivityManager.EXTRA_NETWORK_INFO); - int networkType = networkInfo.getType(); - State networkState = networkInfo.getState(); - Log.i(TAG, "Network type: " + networkType + " State: " + networkInfo.getState()); - if (networkType == mNetworkType && networkInfo.getState() == mExpectedState) { - mReceiveLatch.countDown(); - } - } - - public boolean waitForStateChange() throws InterruptedException { - return mReceiveLatch.await(30, TimeUnit.SECONDS) || hasExpectedState(); - } - - private boolean hasExpectedState() { - return mExpectedState == mConnectivityManager.getNetworkInfo(mNetworkType).getState(); - } + assertEquals(message, expectedNumBytes, numBytes); } } From 1c542daddb748c0f8f913b599a394f3494e774e0 Mon Sep 17 00:00:00 2001 From: Erik Kline Date: Thu, 14 May 2015 17:20:39 +0900 Subject: [PATCH 0163/1109] multinetwork native API CTS test Bug: 19537384 Bug: 21833352 Change-Id: I03df80beca241fe3c952aae65de0cd081751de07 --- tests/cts/net/Android.mk | 3 +- tests/cts/net/jni/Android.mk | 9 + tests/cts/net/jni/NativeMultinetworkJni.c | 216 ++++++++++++++++++ .../android/net/cts/MultinetworkApiTest.java | 155 +++++++++++++ ...kTest.java => MultinetworkSysctlTest.java} | 4 +- 5 files changed, 384 insertions(+), 3 deletions(-) create mode 100644 tests/cts/net/jni/NativeMultinetworkJni.c create mode 100644 tests/cts/net/src/android/net/cts/MultinetworkApiTest.java rename tests/cts/net/src/android/net/cts/{MultinetworkTest.java => MultinetworkSysctlTest.java} (97%) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index a35e145e5f..652487126d 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -26,7 +26,8 @@ LOCAL_MULTILIB := both LOCAL_JAVA_LIBRARIES := voip-common conscrypt org.apache.http.legacy -LOCAL_JNI_SHARED_LIBRARIES := libcts_jni libnativedns_jni +LOCAL_JNI_SHARED_LIBRARIES := libcts_jni libnativedns_jni \ + libnativemultinetwork_jni # include CtsTestServer as a temporary hack to free net.cts from cts.stub. LOCAL_SRC_FILES := $(call all-java-files-under, src) diff --git a/tests/cts/net/jni/Android.mk b/tests/cts/net/jni/Android.mk index 75982de3ed..ca82b30b13 100644 --- a/tests/cts/net/jni/Android.mk +++ b/tests/cts/net/jni/Android.mk @@ -28,3 +28,12 @@ LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) LOCAL_SHARED_LIBRARIES := libnativehelper liblog include $(BUILD_SHARED_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := libnativemultinetwork_jni +# Don't include this package in any configuration by default. +LOCAL_MODULE_TAGS := optional +LOCAL_SRC_FILES := NativeMultinetworkJni.c +LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) +LOCAL_SHARED_LIBRARIES := libandroid libnativehelper liblog +include $(BUILD_SHARED_LIBRARY) diff --git a/tests/cts/net/jni/NativeMultinetworkJni.c b/tests/cts/net/jni/NativeMultinetworkJni.c new file mode 100644 index 0000000000..9a5ab9c422 --- /dev/null +++ b/tests/cts/net/jni/NativeMultinetworkJni.c @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2010 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. + */ + + +#define LOG_TAG "MultinetworkApiTest" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define UNUSED(X) ((void) X) + +static const char kHostname[] = "connectivitycheck.android.com"; + + +JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runGetaddrinfoCheck( + JNIEnv* env, jclass class, jlong nethandle) { + UNUSED(env); + UNUSED(class); + net_handle_t handle = (net_handle_t) nethandle; + struct addrinfo *res = NULL; + + errno = 0; + int rval = android_getaddrinfofornetwork(handle, kHostname, NULL, NULL, &res); + const int saved_errno = errno; + freeaddrinfo(res); + + ALOGD("android_getaddrinfofornetwork(%llu, %s) returned rval=%d errno=%d", + handle, kHostname, rval, saved_errno); + return rval == 0 ? 0 : -saved_errno; +} + +JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runSetprocnetwork( + JNIEnv* env, jclass class, jlong nethandle) { + UNUSED(env); + UNUSED(class); + net_handle_t handle = (net_handle_t) nethandle; + + errno = 0; + int rval = android_setprocnetwork(handle); + const int saved_errno = errno; + ALOGD("android_setprocnetwork(%llu) returned rval=%d errno=%d", + handle, rval, saved_errno); + return rval == 0 ? 0 : -saved_errno; +} + +JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runSetsocknetwork( + JNIEnv* env, jclass class, jlong nethandle) { + UNUSED(env); + UNUSED(class); + net_handle_t handle = (net_handle_t) nethandle; + + errno = 0; + int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); + if (fd < 0) { + ALOGD("socket() failed, errno=%d", errno); + return -errno; + } + + errno = 0; + int rval = android_setsocknetwork(handle, fd); + const int saved_errno = errno; + ALOGD("android_setprocnetwork(%llu, %d) returned rval=%d errno=%d", + handle, fd, rval, saved_errno); + close(fd); + return rval == 0 ? 0 : -saved_errno; +} + +static const int kSockaddrStrLen = INET6_ADDRSTRLEN + strlen("[]:65535"); + +void sockaddr_ntop(const struct sockaddr *sa, socklen_t salen, char *dst, const size_t size) { + char addrstr[INET6_ADDRSTRLEN]; + char portstr[sizeof("65535")]; + char buf[sizeof(addrstr) + sizeof(portstr) + sizeof("[]:")]; + int ret = getnameinfo(sa, salen, + addrstr, sizeof(addrstr), + portstr, sizeof(portstr), + NI_NUMERICHOST | NI_NUMERICSERV); + if (ret == 0) { + snprintf(buf, sizeof(buf), + (sa->sa_family == AF_INET6) ? "[%s]:%s" : "%s:%s", + addrstr, portstr); + } else { + sprintf(buf, "???"); + } + + strlcpy(dst, buf, (strlen(buf) < size - 1) ? strlen(buf) : size - 1); +} + +JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( + JNIEnv* env, jclass class, jlong nethandle) { + UNUSED(env); + UNUSED(class); + const struct addrinfo kHints = { + .ai_flags = AI_ADDRCONFIG, + .ai_family = AF_UNSPEC, + .ai_socktype = SOCK_DGRAM, + .ai_protocol = IPPROTO_UDP, + }; + struct addrinfo *res = NULL; + net_handle_t handle = (net_handle_t) nethandle; + + // Quoth Ian Swett: + // "QUIC always uses 80 and 443, but only 443 is used for secure(HTTPS) traffic." + int rval = android_getaddrinfofornetwork(handle, kHostname, "80", &kHints, &res); + if (rval != 0) { + ALOGD("android_getaddrinfofornetwork(%llu, %s) returned rval=%d errno=%d", + handle, kHostname, rval, errno); + freeaddrinfo(res); + return -errno; + } + + // Rely upon getaddrinfo sorting the best destination to the front. + int fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (fd < 0) { + ALOGD("socket(%d, %d, %d) failed, errno=%d", + res->ai_family, res->ai_socktype, res->ai_protocol, errno); + freeaddrinfo(res); + return -errno; + } + + rval = android_setsocknetwork(handle, fd); + ALOGD("android_setprocnetwork(%llu, %d) returned rval=%d errno=%d", + handle, fd, rval, errno); + if (rval != 0) { + close(fd); + freeaddrinfo(res); + return -errno; + } + + char addrstr[kSockaddrStrLen]; + sockaddr_ntop(res->ai_addr, res->ai_addrlen, addrstr, sizeof(addrstr)); + ALOGD("Attempting connect() to %s...", addrstr); + + rval = connect(fd, res->ai_addr, res->ai_addrlen); + if (rval != 0) { + close(fd); + freeaddrinfo(res); + return -errno; + } + freeaddrinfo(res); + + struct sockaddr_storage src_addr; + socklen_t src_addrlen = sizeof(src_addr); + if (getsockname(fd, (struct sockaddr *)&src_addr, &src_addrlen) != 0) { + close(fd); + return -errno; + } + sockaddr_ntop((const struct sockaddr *)&src_addr, sizeof(src_addr), addrstr, sizeof(addrstr)); + ALOGD("... from %s", addrstr); + + // Don't let reads or writes block indefinitely. + const struct timeval timeo = { 5, 0 }; // 5 seconds + setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo)); + setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeo, sizeof(timeo)); + + uint8_t quic_packet[] = { + 0x0c, // public flags: 64bit conn ID, 8bit sequence number + 0, 0, 0, 0, 0, 0, 0, 0, // 64bit connection ID + 0x01, // sequence number + 0x00, // private flags + 0x07, // type: regular frame type "PING" + }; + + arc4random_buf(quic_packet + 1, 8); // random connection ID + + ssize_t sent = send(fd, quic_packet, sizeof(quic_packet), 0); + if (sent < (ssize_t)sizeof(quic_packet)) { + ALOGD("send(QUIC packet) returned sent=%zd, errno=%d", sent, errno); + close(fd); + return -errno; + } + + uint8_t response[1500]; + ssize_t rcvd = recv(fd, response, sizeof(response), 0); + if (rcvd < sent) { + ALOGD("recv() returned rcvd=%zd, errno=%d", rcvd, errno); + close(fd); + return -errno; + } + + int conn_id_cmp = memcmp(quic_packet + 1, response + 1, 8); + if (conn_id_cmp != 0) { + ALOGD("sent and received connection IDs do not match"); + close(fd); + return -EPROTO; + } + + // TODO: log, and compare to the IP address encoded in the + // response, since this should be a public reset packet. + + close(fd); + return 0; +} diff --git a/tests/cts/net/src/android/net/cts/MultinetworkApiTest.java b/tests/cts/net/src/android/net/cts/MultinetworkApiTest.java new file mode 100644 index 0000000000..51ee50ed2a --- /dev/null +++ b/tests/cts/net/src/android/net/cts/MultinetworkApiTest.java @@ -0,0 +1,155 @@ +/* + * 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 android.net.cts; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.NetworkUtils; +import android.system.ErrnoException; +import android.system.OsConstants; +import android.test.AndroidTestCase; + +import java.util.ArrayList; + + +public class MultinetworkApiTest extends AndroidTestCase { + + static { + System.loadLibrary("nativemultinetwork_jni"); + } + + private static final String TAG = "MultinetworkNativeApiTest"; + + /** + * @return 0 on success + */ + private static native int runGetaddrinfoCheck(long networkHandle); + private static native int runSetprocnetwork(long networkHandle); + private static native int runSetsocknetwork(long networkHandle); + private static native int runDatagramCheck(long networkHandle); + + private ConnectivityManager mCM; + + protected void setUp() throws Exception { + super.setUp(); + mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); + } + + private Network[] getTestableNetworks() { + final ArrayList testableNetworks = new ArrayList(); + for (Network network : mCM.getAllNetworks()) { + final NetworkCapabilities nc = mCM.getNetworkCapabilities(network); + if (nc != null + && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) + && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) { + testableNetworks.add(network); + } + } + + assertTrue( + "This test requires that at least one network be connected. " + + "Please ensure that the device is connected to a network.", + testableNetworks.size() >= 1); + return testableNetworks.toArray(new Network[0]); + } + + public void testGetaddrinfo() throws ErrnoException { + for (Network network : getTestableNetworks()) { + int errno = runGetaddrinfoCheck(network.getNetworkHandle()); + if (errno != 0) { + throw new ErrnoException( + "getaddrinfo on " + mCM.getNetworkInfo(network), -errno); + } + } + } + + public void testSetprocnetwork() throws ErrnoException { + // Hopefully no prior test in this process space has set a default network. + assertNull(mCM.getProcessDefaultNetwork()); + assertEquals(0, NetworkUtils.getBoundNetworkForProcess()); + + for (Network network : getTestableNetworks()) { + mCM.setProcessDefaultNetwork(null); + assertNull(mCM.getProcessDefaultNetwork()); + + int errno = runSetprocnetwork(network.getNetworkHandle()); + if (errno != 0) { + throw new ErrnoException( + "setprocnetwork on " + mCM.getNetworkInfo(network), -errno); + } + Network processDefault = mCM.getProcessDefaultNetwork(); + assertNotNull(processDefault); + assertEquals(network, processDefault); + // TODO: open DatagramSockets, connect them to 192.0.2.1 and 2001:db8::, + // and ensure that the source address is in fact on this network as + // determined by mCM.getLinkProperties(network). + + mCM.setProcessDefaultNetwork(null); + } + + for (Network network : getTestableNetworks()) { + NetworkUtils.bindProcessToNetwork(0); + assertNull(mCM.getBoundNetworkForProcess()); + + int errno = runSetprocnetwork(network.getNetworkHandle()); + if (errno != 0) { + throw new ErrnoException( + "setprocnetwork on " + mCM.getNetworkInfo(network), -errno); + } + assertEquals(network, new Network(mCM.getBoundNetworkForProcess())); + // TODO: open DatagramSockets, connect them to 192.0.2.1 and 2001:db8::, + // and ensure that the source address is in fact on this network as + // determined by mCM.getLinkProperties(network). + + NetworkUtils.bindProcessToNetwork(0); + } + } + + public void testSetsocknetwork() throws ErrnoException { + for (Network network : getTestableNetworks()) { + int errno = runSetsocknetwork(network.getNetworkHandle()); + if (errno != 0) { + throw new ErrnoException( + "setsocknetwork on " + mCM.getNetworkInfo(network), -errno); + } + } + } + + public void testNativeDatagramTransmission() throws ErrnoException { + for (Network network : getTestableNetworks()) { + int errno = runDatagramCheck(network.getNetworkHandle()); + if (errno != 0) { + throw new ErrnoException( + "DatagramCheck on " + mCM.getNetworkInfo(network), -errno); + } + } + } + + public void testNoSuchNetwork() { + final Network eNoNet = new Network(54321); + assertNull(mCM.getNetworkInfo(eNoNet)); + + final long eNoNetHandle = eNoNet.getNetworkHandle(); + assertEquals(-OsConstants.ENONET, runSetsocknetwork(eNoNetHandle)); + assertEquals(-OsConstants.ENONET, runSetprocnetwork(eNoNetHandle)); + // TODO: correct test permissions so this call is not silently re-mapped + // to query on the default network. + // assertEquals(-OsConstants.ENONET, runGetaddrinfoCheck(eNoNetHandle)); + } +} diff --git a/tests/cts/net/src/android/net/cts/MultinetworkTest.java b/tests/cts/net/src/android/net/cts/MultinetworkSysctlTest.java similarity index 97% rename from tests/cts/net/src/android/net/cts/MultinetworkTest.java rename to tests/cts/net/src/android/net/cts/MultinetworkSysctlTest.java index 256c03010a..c091a1340c 100644 --- a/tests/cts/net/src/android/net/cts/MultinetworkTest.java +++ b/tests/cts/net/src/android/net/cts/MultinetworkSysctlTest.java @@ -27,9 +27,9 @@ import java.io.FileDescriptor; import java.io.IOException; /** - * Tests for multinetwork functionality. + * Tests for multinetwork sysctl functionality. */ -public class MultinetworkTest extends AndroidTestCase { +public class MultinetworkSysctlTest extends AndroidTestCase { // Global sysctls. Must be present and set to 1. private static final String[] GLOBAL_SYSCTLS = { From dda68d2e2dbf5c689dcaca8f811127f3e8ec84f0 Mon Sep 17 00:00:00 2001 From: Ang Li Date: Mon, 22 Jun 2015 12:46:27 -0700 Subject: [PATCH 0164/1109] Add CTS tests for passpoint APIs in enterprise config. b/22001019 Change-Id: I35f6fa624f4b8fcd722296e12bc5aefc76ea96c6 --- .../net/wifi/cts/WifiEnterpriseConfigTest.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java index 6e395aaa14..6c416ca9f3 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java @@ -32,6 +32,10 @@ public class WifiEnterpriseConfigTest extends AndroidTestCase { private static final String IDENTITY = "identity"; private static final String PASSWORD = "password"; private static final String SUBJECT_MATCH = "subjectmatch"; + private static final String ALT_SUBJECT_MATCH = "altsubjectmatch"; + private static final String DOM_SUBJECT_MATCH = "domsubjectmatch"; + private static final String PLMN = "plmn"; + private static final String REALM = "realm"; private static final String ANON_IDENTITY = "anonidentity"; private static final int ENABLE_DELAY = 10000; @@ -87,6 +91,15 @@ public class WifiEnterpriseConfigTest extends AndroidTestCase { config.setClientKeyEntry(null, null); config.setSubjectMatch(SUBJECT_MATCH); assertTrue(config.getSubjectMatch().equals(SUBJECT_MATCH)); + // Hotspot 2.0 related attributes + config.setPlmn(PLMN); + assertTrue(config.getPlmn().equals(PLMN)); + config.setPlmn(REALM); + assertTrue(config.getRealm().equals(REALM)); + config.setAltSubjectMatch(ALT_SUBJECT_MATCH); + assertTrue(config.getAltSubjectMatch().equals(ALT_SUBJECT_MATCH)); + config.setDomainSuffixMatch(DOM_SUBJECT_MATCH); + assertTrue(config.getDomainSuffixMatch().equals(DOM_SUBJECT_MATCH)); } public void testAddEapNetwork() { From 5e671fabe635f30a9937f42f37bb812216c04597 Mon Sep 17 00:00:00 2001 From: Johan Redestig Date: Wed, 30 Oct 2013 14:14:58 +0100 Subject: [PATCH 0165/1109] Lookup private resources in run-time This fixes the following cases for us: android.net.cts.ConnectivityManagerTest#testGetAllNetworkInfo android.net.cts.ConnectivityManagerTest#testGetNetworkInfo android.net.cts.ConnectivityManagerTest#testIsNetworkSupported android.net.cts.ConnectivityManagerTest#testRequestRouteToHost android.net.cts.ConnectivityManagerTest#testSetNetworkPreference We need to use the prebuilt binary but that has dependency to private resource identities that differs in our environment. With this change the resources are looked up in run-time to avoid the build time dependency. Change-Id: I6579338b591ca7a0da3f03f796136269c7789780 (cherry picked from commit b29370db3447b4115523c03cb5019df601984f23) --- .../src/android/net/cts/ConnectivityManagerTest.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index e769be19ae..5656119d0f 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -66,8 +66,10 @@ public class ConnectivityManagerTest extends AndroidTestCase { mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); mPackageManager = getContext().getPackageManager(); - String[] naStrings = getContext().getResources().getStringArray( - com.android.internal.R.array.networkAttributes); + // Get com.android.internal.R.array.networkAttributes + int resId = getContext().getResources().getIdentifier("networkAttributes", "array", "android"); + String[] naStrings = getContext().getResources().getStringArray(resId); + for (String naString : naStrings) { try { NetworkConfig n = new NetworkConfig(naString); @@ -75,8 +77,9 @@ public class ConnectivityManagerTest extends AndroidTestCase { } catch (Exception e) {} } - int[] protectedNetworks = getContext().getResources().getIntArray( - com.android.internal.R.array.config_protectedNetworks); + // Get com.android.internal.R.array.config_protectedNetworks + resId = getContext().getResources().getIdentifier("config_protectedNetworks", "array", "android"); + int[] protectedNetworks = getContext().getResources().getIntArray(resId); for (int p : protectedNetworks) { mProtectedNetworks.add(p); } From c16f65807b0251fdb0149d0bb1eacba370b585b1 Mon Sep 17 00:00:00 2001 From: Neil Fuller Date: Fri, 3 Jul 2015 11:55:29 +0100 Subject: [PATCH 0166/1109] Modify test now that LocalSocket.getSoTimeout() does something Bug: 3106438 Change-Id: Iac7153607d5da44f21d66da80e2db27b17002d8d --- tests/cts/net/src/android/net/cts/LocalSocketTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/LocalSocketTest.java b/tests/cts/net/src/android/net/cts/LocalSocketTest.java index 865ec21da3..24410d5248 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketTest.java @@ -129,9 +129,9 @@ public class LocalSocketTest extends AndroidTestCase{ socket.setSendBufferSize(3998); assertEquals(3998 << 1, socket.getSendBufferSize()); - // Timeout is not support at present, so set is ignored - socket.setSoTimeout(1996); assertEquals(0, socket.getSoTimeout()); + socket.setSoTimeout(1996); + assertTrue(socket.getSoTimeout() > 0); try { socket.getRemoteSocketAddress(); From 8fbc09bde8c5723d57a3b188e7fc69916cc62cca Mon Sep 17 00:00:00 2001 From: Neil Fuller Date: Fri, 3 Jul 2015 15:04:48 +0100 Subject: [PATCH 0167/1109] More tests for LocalSocket Tests for OutputStream.flush() and InputStream.available(). Bug: 3106438 Change-Id: I024e8fb95cc52678eb4b8df5584d21c9cf4b505a --- .../src/android/net/cts/LocalSocketTest.java | 127 +++++++++++++++++- 1 file changed, 123 insertions(+), 4 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/LocalSocketTest.java b/tests/cts/net/src/android/net/cts/LocalSocketTest.java index 24410d5248..22a2c7a2d9 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketTest.java @@ -16,16 +16,19 @@ package android.net.cts; -import java.io.FileDescriptor; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; import android.net.Credentials; import android.net.LocalServerSocket; import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.test.AndroidTestCase; +import java.io.FileDescriptor; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + public class LocalSocketTest extends AndroidTestCase{ public final static String mSockAddr = "com.android.net.LocalSocketTest"; @@ -168,4 +171,120 @@ public class LocalSocketTest extends AndroidTestCase{ // expected } } + + public void testAvailable() throws Exception { + LocalServerSocket localServerSocket = new LocalServerSocket(mSockAddr); + LocalSocket clientSocket = new LocalSocket(); + + // establish connection between client and server + LocalSocketAddress locSockAddr = new LocalSocketAddress(mSockAddr); + clientSocket.connect(locSockAddr); + assertTrue(clientSocket.isConnected()); + LocalSocket serverSocket = localServerSocket.accept(); + + OutputStream clientOutputStream = clientSocket.getOutputStream(); + InputStream serverInputStream = serverSocket.getInputStream(); + assertEquals(0, serverInputStream.available()); + + byte[] buffer = new byte[50]; + clientOutputStream.write(buffer); + assertEquals(50, serverInputStream.available()); + + InputStream clientInputStream = clientSocket.getInputStream(); + OutputStream serverOutputStream = serverSocket.getOutputStream(); + assertEquals(0, clientInputStream.available()); + serverOutputStream.write(buffer); + assertEquals(50, serverInputStream.available()); + + clientSocket.close(); + serverSocket.close(); + } + + public void testFlush() throws Exception { + LocalServerSocket localServerSocket = new LocalServerSocket(mSockAddr); + LocalSocket clientSocket = new LocalSocket(); + + // establish connection between client and server + LocalSocketAddress locSockAddr = new LocalSocketAddress(mSockAddr); + clientSocket.connect(locSockAddr); + assertTrue(clientSocket.isConnected()); + LocalSocket serverSocket = localServerSocket.accept(); + + OutputStream clientOutputStream = clientSocket.getOutputStream(); + InputStream serverInputStream = serverSocket.getInputStream(); + testFlushWorks(clientOutputStream, serverInputStream); + + OutputStream serverOutputStream = serverSocket.getOutputStream(); + InputStream clientInputStream = clientSocket.getInputStream(); + testFlushWorks(serverOutputStream, clientInputStream); + + clientSocket.close(); + serverSocket.close(); + } + + private void testFlushWorks(OutputStream outputStream, InputStream inputStream) + throws Exception { + final int bytesToTransfer = 50; + StreamReader inputStreamReader = new StreamReader(inputStream, bytesToTransfer); + + byte[] buffer = new byte[bytesToTransfer]; + outputStream.write(buffer); + assertEquals(bytesToTransfer, inputStream.available()); + + // Start consuming the data. + inputStreamReader.start(); + + // This doesn't actually flush any buffers, it just polls until the reader has read all the + // bytes. + outputStream.flush(); + + inputStreamReader.waitForCompletion(5000); + inputStreamReader.assertBytesRead(bytesToTransfer); + assertEquals(0, inputStream.available()); + } + + private static class StreamReader extends Thread { + private final InputStream is; + private final int expectedByteCount; + private final CountDownLatch completeLatch = new CountDownLatch(1); + + private volatile Exception exception; + private int bytesRead; + + private StreamReader(InputStream is, int expectedByteCount) { + this.is = is; + this.expectedByteCount = expectedByteCount; + } + + @Override + public void run() { + try { + byte[] buffer = new byte[10]; + int readCount; + while ((readCount = is.read(buffer)) >= 0) { + bytesRead += readCount; + if (bytesRead >= expectedByteCount) { + break; + } + } + } catch (IOException e) { + exception = e; + } finally { + completeLatch.countDown(); + } + } + + public void waitForCompletion(long waitMillis) throws Exception { + if (!completeLatch.await(waitMillis, TimeUnit.MILLISECONDS)) { + fail("Timeout waiting for completion"); + } + if (exception != null) { + throw new Exception("Read failed", exception); + } + } + + public void assertBytesRead(int expected) { + assertEquals(expected, bytesRead); + } + } } From cb57c86657f230c34480ceb72cdbce43fe62302f Mon Sep 17 00:00:00 2001 From: Neil Fuller Date: Fri, 3 Jul 2015 17:38:43 +0100 Subject: [PATCH 0168/1109] Fix missing socket closure in LocalSocketTest Noticed as a result of 8fbc09bde8c5723d57a3b188e7fc69916cc62cca. One of the AF_UNIX sockets being created in three tests was not being closed (until GC/finalization). Because the name is now used in multiple tests some of the tests would fail in the CTS test runner ("Address already in use") if no GC had occurred. Bug: 3106438 Change-Id: I7debe5ed26d9d09e71a3d8a1b5b7d85b13e6e069 --- tests/cts/net/src/android/net/cts/LocalSocketTest.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/LocalSocketTest.java b/tests/cts/net/src/android/net/cts/LocalSocketTest.java index 22a2c7a2d9..9da8fbe272 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketTest.java @@ -116,7 +116,7 @@ public class LocalSocketTest extends AndroidTestCase{ public void testAccessors() throws IOException{ LocalSocket socket = new LocalSocket(); - LocalSocketAddress addr = new LocalSocketAddress("secondary"); + LocalSocketAddress addr = new LocalSocketAddress(mSockAddr); assertFalse(socket.isBound()); socket.bind(addr); @@ -170,6 +170,8 @@ public class LocalSocketTest extends AndroidTestCase{ } catch (UnsupportedOperationException e) { // expected } + + socket.close(); } public void testAvailable() throws Exception { @@ -198,6 +200,7 @@ public class LocalSocketTest extends AndroidTestCase{ clientSocket.close(); serverSocket.close(); + localServerSocket.close(); } public void testFlush() throws Exception { @@ -220,6 +223,7 @@ public class LocalSocketTest extends AndroidTestCase{ clientSocket.close(); serverSocket.close(); + localServerSocket.close(); } private void testFlushWorks(OutputStream outputStream, InputStream inputStream) From 2ee5bd54a5c8901a9d8bd3508dc7ed82898b7d2c Mon Sep 17 00:00:00 2001 From: Ang Li Date: Wed, 8 Jul 2015 13:39:48 -0700 Subject: [PATCH 0169/1109] Fix a naming error in WifiEnterpriseConfigTest.java b/22349111 Change-Id: Ic9c847dfb1d58f274e91e22042c07995c72daa12 --- .../net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java index 6c416ca9f3..2cc59511dd 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java @@ -94,7 +94,7 @@ public class WifiEnterpriseConfigTest extends AndroidTestCase { // Hotspot 2.0 related attributes config.setPlmn(PLMN); assertTrue(config.getPlmn().equals(PLMN)); - config.setPlmn(REALM); + config.setRealm(REALM); assertTrue(config.getRealm().equals(REALM)); config.setAltSubjectMatch(ALT_SUBJECT_MATCH); assertTrue(config.getAltSubjectMatch().equals(ALT_SUBJECT_MATCH)); From 20b7b91edf3f6ae736e8362e2c58eab324f39b8f Mon Sep 17 00:00:00 2001 From: Junjie Hu Date: Fri, 10 Jul 2015 19:28:31 -0700 Subject: [PATCH 0170/1109] Fix CTS android.net package testTrafficStatsForLocalhost seldom fail issue (cherry-picked from master: 0d4434d998a9fc7c314523503b0a09a8422acc71 conflict + added Log) For testTrafficStatsForLocalhost's UID testing, it will also calcuate the wlan0 interface. There are some TCP re-tranmission in SSLCertificateSocketFactoryTest and it is the same UID as this test case. Need to consider those extra pacetks. For example, Before testTrafficStatsForLocalhost test casae: 01-08 15:49:11.316 7826 7839 D TrafficStats: parseUidStats, buffer: 14 wlan0 0x0 10067 0 31857 67 4582 55 31857 67 0 0 0 0 4582 55 0 0 0 0 01-08 15:49:11.335 7826 7839 D TrafficStats: parseUidStats, buffer: 24 lo 0x0 10067 0 40 1 60 1 40 1 0 0 0 0 60 1 0 0 0 0 After testTrafficStatsForLocalhost test casae: 01-08 15:49:19.210 7826 7839 D TrafficStats: parseUidStats, buffer: 14 wlan0 0x0 10067 0 31857 67 4738 58 31857 67 0 0 0 0 4738 58 0 0 0 0 01-08 15:49:19.212 7826 7839 D TrafficStats: parseUidStats, buffer: 24 lo 0x0 10067 0 1155336 2053 1155408 2054 1155336 2053 0 0 0 0 1155408 2054 0 0 0 0 => There are three extra IP packets after testing due to TCP FIN retreamsisions in previous test case Suggest to add some extra IP packets for consider the extra traffic in wlan0 interface. Signed-off-by: Junjie Hu Change-Id: I981f98fc8647469fb105361516b6a59c53530c70 --- .../src/android/net/cts/TrafficStatsTest.java | 48 ++++++++++++++----- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java index 180d259bbc..0d02df7c17 100644 --- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java +++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java @@ -19,6 +19,7 @@ package android.net.cts; import android.net.TrafficStats; import android.os.Process; import android.test.AndroidTestCase; +import android.util.Log; import java.io.IOException; import java.io.InputStream; @@ -29,6 +30,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; public class TrafficStatsTest extends AndroidTestCase { + private static final String LOG_TAG = "TrafficStatsTest"; public void testValidMobileStats() { // We can't assume a mobile network is even present in this test, so // we simply assert that a valid value is returned. @@ -163,18 +165,40 @@ public class TrafficStatsTest extends AndroidTestCase { * + 7 approx.: syn, syn-ack, ack, fin-ack, ack, fin-ack, ack; * but sometimes the last find-acks just vanish, so we set a lower limit of +5. */ - assertTrue("uidtxp: " + uidTxPacketsBefore + " -> " + uidTxPacketsAfter + " delta=" + uidTxDeltaPackets, - uidTxDeltaPackets >= packetCount + 5 && - uidTxDeltaPackets <= packetCount + packetCount + 7); - assertTrue("uidrxp: " + uidRxPacketsBefore + " -> " + uidRxPacketsAfter + " delta=" + uidRxDeltaPackets, - uidRxDeltaPackets >= packetCount + 5 && - uidRxDeltaPackets <= packetCount + packetCount + 7); - assertTrue("uidtxb: " + uidTxBytesBefore + " -> " + uidTxBytesAfter + " delta=" + uidTxDeltaBytes, - uidTxDeltaBytes >= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(5, 0) && - uidTxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + 7, 0)); - assertTrue("uidrxb: " + uidRxBytesBefore + " -> " + uidRxBytesAfter + " delta=" + uidRxDeltaBytes, - uidRxDeltaBytes >= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(5, 0) && - uidRxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + 7, 0)); + final int maxExpectedExtraPackets = 7; + final int minExpectedExtraPackets = 5; + + // Some other tests don't cleanup connections correctly. + // They have the same UID, so we discount their lingering traffic + // which happens only on non-localhost, such as TCP FIN retranmission packets + long deltaTxOtherPackets = (totalTxPacketsAfter - totalTxPacketsBefore) - uidTxDeltaPackets; + long deltaRxOtherPackets = (totalRxPacketsAfter - totalRxPacketsBefore) - uidRxDeltaPackets; + if (deltaTxOtherPackets > 0 || deltaRxOtherPackets > 0) { + Log.i(LOG_TAG, "lingering traffic data: " + deltaTxOtherPackets + "/" + deltaRxOtherPackets); + // Make sure that not too many non-localhost packets are accounted for + assertTrue("too many non-localhost packets on the sam UID", deltaTxOtherPackets + deltaTxOtherPackets < 20); + } + + assertTrue("uidtxp: " + uidTxPacketsBefore + " -> " + uidTxPacketsAfter + " delta=" + uidTxDeltaPackets + + " Wanted: " + uidTxDeltaPackets + ">=" + packetCount + "+" + minExpectedExtraPackets + " && " + + uidTxDeltaPackets + "<=" + packetCount + "+" + packetCount + "+" + maxExpectedExtraPackets + "+" + deltaTxOtherPackets, + uidTxDeltaPackets >= packetCount + minExpectedExtraPackets && + uidTxDeltaPackets <= packetCount + packetCount + maxExpectedExtraPackets + deltaTxOtherPackets); + assertTrue("uidrxp: " + uidRxPacketsBefore + " -> " + uidRxPacketsAfter + " delta=" + uidRxDeltaPackets + + " Wanted: " + uidRxDeltaPackets + ">=" + packetCount + "+" + minExpectedExtraPackets + " && " + + uidRxDeltaPackets + "<=" + packetCount + "+" + packetCount + "+" + maxExpectedExtraPackets, + uidRxDeltaPackets >= packetCount + minExpectedExtraPackets && + uidRxDeltaPackets <= packetCount + packetCount + maxExpectedExtraPackets + deltaRxOtherPackets); + assertTrue("uidtxb: " + uidTxBytesBefore + " -> " + uidTxBytesAfter + " delta=" + uidTxDeltaBytes + + " Wanted: " + uidTxDeltaBytes + ">=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(minExpectedExtraPackets, 0) + " && " + + uidTxDeltaBytes + "<=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets, 0), + uidTxDeltaBytes >= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(minExpectedExtraPackets, 0) && + uidTxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets + deltaTxOtherPackets, 0)); + assertTrue("uidrxb: " + uidRxBytesBefore + " -> " + uidRxBytesAfter + " delta=" + uidRxDeltaBytes + + " Wanted: " + uidRxDeltaBytes + ">=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(minExpectedExtraPackets, 0) + " && " + + uidRxDeltaBytes + "<=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets, 0), + uidRxDeltaBytes >= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(minExpectedExtraPackets, 0) && + uidRxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets + deltaRxOtherPackets, 0)); // Localhost traffic *does* count against total stats. // Fudge by 132 packets of 1500 bytes not related to the test. From 810a62236ca892be3001bc24c325f41fe754efff Mon Sep 17 00:00:00 2001 From: JP Abgrall Date: Tue, 14 Jul 2015 18:59:40 -0700 Subject: [PATCH 0171/1109] Fix CTS build Revert "Merge "resolve merge conflicts of a97c792 to kitkat-cts-dev" into kitkat-cts-dev" This reverts commit 9feaaaf44682c72dc5c771c93ef01ec793b6a7e3, reversing changes made to 65fbe1fcd153c5647f8d1e1a7443b3f04b7b25fd. --- .../net/src/android/net/cts/TrafficStatsTest.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java index 74cd7718ea..5b93beead5 100755 --- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java +++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java @@ -34,6 +34,7 @@ import java.util.concurrent.TimeUnit; public class TrafficStatsTest extends AndroidTestCase { private static final String LOG_TAG = "TrafficStatsTest"; + public void testValidMobileStats() { // We can't assume a mobile network is even present in this test, so // we simply assert that a valid value is returned. @@ -217,17 +218,6 @@ public class TrafficStatsTest extends AndroidTestCase { assertTrue("too many non-localhost packets on the sam UID", deltaTxOtherPackets + deltaTxOtherPackets < 20); } - // Some other tests don't cleanup connections correctly. - // They have the same UID, so we discount their lingering traffic - // which happens only on non-localhost, such as TCP FIN retranmission packets - long deltaTxOtherPackets = (totalTxPacketsAfter - totalTxPacketsBefore) - uidTxDeltaPackets; - long deltaRxOtherPackets = (totalRxPacketsAfter - totalRxPacketsBefore) - uidRxDeltaPackets; - if (deltaTxOtherPackets > 0 || deltaRxOtherPackets > 0) { - Log.i(LOG_TAG, "lingering traffic data: " + deltaTxOtherPackets + "/" + deltaRxOtherPackets); - // Make sure that not too many non-localhost packets are accounted for - assertTrue("too many non-localhost packets on the sam UID", deltaTxOtherPackets + deltaTxOtherPackets < 20); - } - assertTrue("uidtxp: " + uidTxPacketsBefore + " -> " + uidTxPacketsAfter + " delta=" + uidTxDeltaPackets + " Wanted: " + uidTxDeltaPackets + ">=" + packetCount + "+" + minExpectedExtraPackets + " && " + uidTxDeltaPackets + "<=" + packetCount + "+" + packetCount + "+" + maxExpectedExtraPackets + "+" + deltaTxOtherPackets, From 0852bee4a9b363de1c361b1a12564dc59ded1771 Mon Sep 17 00:00:00 2001 From: JP Abgrall Date: Tue, 14 Jul 2015 18:59:40 -0700 Subject: [PATCH 0172/1109] Fix CTS build Revert "Merge "resolve merge conflicts of a97c792 to kitkat-cts-dev" into kitkat-cts-dev" This reverts commit 9feaaaf44682c72dc5c771c93ef01ec793b6a7e3, reversing changes made to 65fbe1fcd153c5647f8d1e1a7443b3f04b7b25fd. --- .../net/src/android/net/cts/TrafficStatsTest.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java index 74cd7718ea..5b93beead5 100755 --- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java +++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java @@ -34,6 +34,7 @@ import java.util.concurrent.TimeUnit; public class TrafficStatsTest extends AndroidTestCase { private static final String LOG_TAG = "TrafficStatsTest"; + public void testValidMobileStats() { // We can't assume a mobile network is even present in this test, so // we simply assert that a valid value is returned. @@ -217,17 +218,6 @@ public class TrafficStatsTest extends AndroidTestCase { assertTrue("too many non-localhost packets on the sam UID", deltaTxOtherPackets + deltaTxOtherPackets < 20); } - // Some other tests don't cleanup connections correctly. - // They have the same UID, so we discount their lingering traffic - // which happens only on non-localhost, such as TCP FIN retranmission packets - long deltaTxOtherPackets = (totalTxPacketsAfter - totalTxPacketsBefore) - uidTxDeltaPackets; - long deltaRxOtherPackets = (totalRxPacketsAfter - totalRxPacketsBefore) - uidRxDeltaPackets; - if (deltaTxOtherPackets > 0 || deltaRxOtherPackets > 0) { - Log.i(LOG_TAG, "lingering traffic data: " + deltaTxOtherPackets + "/" + deltaRxOtherPackets); - // Make sure that not too many non-localhost packets are accounted for - assertTrue("too many non-localhost packets on the sam UID", deltaTxOtherPackets + deltaTxOtherPackets < 20); - } - assertTrue("uidtxp: " + uidTxPacketsBefore + " -> " + uidTxPacketsAfter + " delta=" + uidTxDeltaPackets + " Wanted: " + uidTxDeltaPackets + ">=" + packetCount + "+" + minExpectedExtraPackets + " && " + uidTxDeltaPackets + "<=" + packetCount + "+" + packetCount + "+" + maxExpectedExtraPackets + "+" + deltaTxOtherPackets, From 708349cba6559e81564481844b3e69ae3de4ec02 Mon Sep 17 00:00:00 2001 From: Jim Guggemos Date: Tue, 14 Jul 2015 15:15:04 -0600 Subject: [PATCH 0173/1109] New CTS test for ConnectivityManager.getActiveNetwork. Bug: 21833352 Change-Id: I970a114e3c94c9885186bd55c608bbc4bcb9a7fa --- .../src/android/net/cts/ConnectivityManagerTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 15d368f515..7c70293846 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -22,6 +22,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.net.ConnectivityManager; +import android.net.Network; import android.net.NetworkConfig; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; @@ -129,6 +130,17 @@ public class ConnectivityManagerTest extends AndroidTestCase { assertTrue(ni.getState() == State.CONNECTED); } + public void testGetActiveNetwork() { + Network network = mCm.getActiveNetwork(); + assertTrue("You must have an active network connection to complete CTS", network != null); + + NetworkInfo ni = mCm.getNetworkInfo(network); + assertTrue("Network returned from getActiveNetwork was invalid", ni != null); + // Similar to testGetActiveNetworkInfo above. + assertTrue(ConnectivityManager.isNetworkTypeValid(ni.getType())); + assertTrue(ni.getState() == State.CONNECTED); + } + public void testGetNetworkInfo() { for (int type = -1; type <= ConnectivityManager.MAX_NETWORK_TYPE+1; type++) { if (isSupported(type)) { From 7443acfd8f25c05270a7a5482e4a9cd2c0073308 Mon Sep 17 00:00:00 2001 From: Jim Guggemos Date: Tue, 14 Jul 2015 12:03:12 -0600 Subject: [PATCH 0174/1109] New CTS test for ConnectivityManager.(un)registerNetworkCallback. Tested on device with wifi enabled and disabled before executing the test. Bug: 21833352 Change-Id: I42222bd229a370f780f08fa056d331ff1431b87a --- .../net/cts/ConnectivityManagerTest.java | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 7c70293846..34baac9819 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -23,10 +23,12 @@ import android.content.IntentFilter; import android.content.pm.PackageManager; import android.net.ConnectivityManager; import android.net.Network; +import android.net.NetworkCapabilities; import android.net.NetworkConfig; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; +import android.net.NetworkRequest; import android.net.wifi.WifiManager; import android.test.AndroidTestCase; import android.util.Log; @@ -310,6 +312,51 @@ public class ConnectivityManagerTest extends AndroidTestCase { } } + /** + * Exercises both registerNetworkCallback and unregisterNetworkCallback. This checks to + * see if we get a callback for the TRANSPORT_WIFI transport type being available. + * + *

In order to test that a NetworkCallback occurs, we need some change in the network + * state (either a transport or capability is now available). The most straightforward is + * WiFi. We could add a version that uses the telephony data connection but it's not clear + * that it would increase test coverage by much (how many devices have 3G radio but not Wifi?). + */ + public void testRegisterNetworkCallback() { + if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) { + Log.i(TAG, "testRegisterNetworkCallback cannot execute unless devices supports WiFi"); + return; + } + + // We will register for a WIFI network being available or lost. + NetworkRequest request = new NetworkRequest.Builder() + .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) + .build(); + TestNetworkCallback callback = new TestNetworkCallback(); + mCm.registerNetworkCallback(request, callback); + + boolean previousWifiEnabledState = mWifiManager.isWifiEnabled(); + + try { + // Make sure WiFi is connected to an access point to start with. + if (!previousWifiEnabledState) { + connectToWifi(); + } + + // Now we should expect to get a network callback about availability of the wifi + // network even if it was already connected as a state-based action when the callback + // is registered. + assertTrue("Did not receive NetworkCallback.onAvailable for TRANSPORT_WIFI", + callback.waitForAvailable()); + } catch (InterruptedException e) { + fail("Broadcast receiver or NetworkCallback wait was interrupted."); + } finally { + mCm.unregisterNetworkCallback(callback); + + // Return WiFI to its original enabled/disabled state. + mWifiManager.setWifiEnabled(previousWifiEnabledState); + } + } + private void connectToWifi() throws InterruptedException { ConnectivityActionReceiver receiver = new ConnectivityActionReceiver(ConnectivityManager.TYPE_WIFI); @@ -350,4 +397,21 @@ public class ConnectivityManagerTest extends AndroidTestCase { return mReceiveLatch.await(30, TimeUnit.SECONDS); } } + + /** + * Callback used in testRegisterNetworkCallback that allows caller to block on + * {@code onAvailable}. + */ + private class TestNetworkCallback extends ConnectivityManager.NetworkCallback { + private final CountDownLatch mAvailableLatch = new CountDownLatch(1); + + public boolean waitForAvailable() throws InterruptedException { + return mAvailableLatch.await(30, TimeUnit.SECONDS); + } + + @Override + public void onAvailable(Network network) { + mAvailableLatch.countDown(); + } + } } From adbcf224267a1df7362dad13b0862b50f57b3c68 Mon Sep 17 00:00:00 2001 From: Liangcai Li Date: Fri, 10 Jan 2014 16:01:46 +0800 Subject: [PATCH 0175/1109] Support WiFi only device at runtime. As what is done in ConnectivityService to fix bug: 8562845. Otherwise some related tests like 'testGetAllNetworkInfo' would fail with runtime detection on WiFi only device. Change-Id: I94922729c11826b3711abf42f594dcdd994324b6 Signed-off-by: Liangcai Li --- .../net/src/android/net/cts/ConnectivityManagerTest.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 5656119d0f..ab4bc7ec55 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -30,6 +30,7 @@ import android.net.NetworkInfo.State; import android.net.wifi.WifiManager; import android.test.AndroidTestCase; import android.util.Log; +import android.os.SystemProperties; import java.util.ArrayList; import java.util.HashMap; @@ -69,10 +70,14 @@ public class ConnectivityManagerTest extends AndroidTestCase { // Get com.android.internal.R.array.networkAttributes int resId = getContext().getResources().getIdentifier("networkAttributes", "array", "android"); String[] naStrings = getContext().getResources().getStringArray(resId); - + //TODO: What is the "correct" way to determine if this is a wifi only device? + boolean wifiOnly = SystemProperties.getBoolean("ro.radio.noril", false); for (String naString : naStrings) { try { NetworkConfig n = new NetworkConfig(naString); + if (wifiOnly && ConnectivityManager.isNetworkTypeMobile(n.type)) { + continue; + } mNetworks.put(n.type, n); } catch (Exception e) {} } From e2815d360a9e4cd05c01c666183445f6b6294779 Mon Sep 17 00:00:00 2001 From: Erik Kline Date: Fri, 24 Jul 2015 02:23:15 +0900 Subject: [PATCH 0176/1109] QUIC port 80 support is going away Change-Id: I29a81e67d121b2e7e832e9e0d5e798d70b4c594a --- tests/cts/net/jni/NativeMultinetworkJni.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/cts/net/jni/NativeMultinetworkJni.c b/tests/cts/net/jni/NativeMultinetworkJni.c index 9a5ab9c422..4da0c1c4a3 100644 --- a/tests/cts/net/jni/NativeMultinetworkJni.c +++ b/tests/cts/net/jni/NativeMultinetworkJni.c @@ -122,9 +122,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( struct addrinfo *res = NULL; net_handle_t handle = (net_handle_t) nethandle; - // Quoth Ian Swett: - // "QUIC always uses 80 and 443, but only 443 is used for secure(HTTPS) traffic." - int rval = android_getaddrinfofornetwork(handle, kHostname, "80", &kHints, &res); + int rval = android_getaddrinfofornetwork(handle, kHostname, "443", &kHints, &res); if (rval != 0) { ALOGD("android_getaddrinfofornetwork(%llu, %s) returned rval=%d errno=%d", handle, kHostname, rval, errno); From 9030d1aceb09288418731435aa7fade736b21383 Mon Sep 17 00:00:00 2001 From: Jim Guggemos Date: Tue, 21 Jul 2015 20:08:24 -0600 Subject: [PATCH 0177/1109] New tests for (un)registerNetworkCallback with PendingIntent. Fixed up flakiness if WiFi was disabled before executing the test. Bug: 21833352 Change-Id: Ief7e12c4a7151722ec926ac38ced9f8903cdb607 --- .../net/cts/ConnectivityManagerTest.java | 172 +++++++++++++++--- 1 file changed, 149 insertions(+), 23 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 34baac9819..1895dccb7a 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -16,6 +16,7 @@ package android.net.cts; +import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -53,6 +54,10 @@ public class ConnectivityManagerTest extends AndroidTestCase { public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI; private static final int HOST_ADDRESS = 0x7f000001;// represent ip 127.0.0.1 + // Action sent to ConnectivityActionReceiver when a network callback is sent via PendingIntent. + private static final String NETWORK_CALLBACK_ACTION = + "ConnectivityManagerTest.NetworkCallbackAction"; + // device could have only one interface: data, wifi. private static final int MIN_NUM_NETWORK_TYPES = 1; @@ -127,17 +132,18 @@ public class ConnectivityManagerTest extends AndroidTestCase { public void testGetActiveNetworkInfo() { NetworkInfo ni = mCm.getActiveNetworkInfo(); - assertTrue("You must have an active network connection to complete CTS", ni != null); + assertNotNull("You must have an active network connection to complete CTS", ni); assertTrue(ConnectivityManager.isNetworkTypeValid(ni.getType())); assertTrue(ni.getState() == State.CONNECTED); } public void testGetActiveNetwork() { Network network = mCm.getActiveNetwork(); - assertTrue("You must have an active network connection to complete CTS", network != null); + assertNotNull("You must have an active network connection to complete CTS", network); NetworkInfo ni = mCm.getNetworkInfo(network); - assertTrue("Network returned from getActiveNetwork was invalid", ni != null); + assertNotNull("Network returned from getActiveNetwork was invalid", ni); + // Similar to testGetActiveNetworkInfo above. assertTrue(ConnectivityManager.isNetworkTypeValid(ni.getType())); assertTrue(ni.getState() == State.CONNECTED); @@ -280,8 +286,8 @@ public class ConnectivityManagerTest extends AndroidTestCase { } // Register a receiver that will capture the connectivity change for hipri. - ConnectivityActionReceiver receiver = - new ConnectivityActionReceiver(ConnectivityManager.TYPE_MOBILE_HIPRI); + ConnectivityActionReceiver receiver = new ConnectivityActionReceiver( + ConnectivityManager.TYPE_MOBILE_HIPRI, NetworkInfo.State.CONNECTED); IntentFilter filter = new IntentFilter(); filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); mContext.registerReceiver(receiver, filter); @@ -292,7 +298,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { assertTrue("Couldn't start using the HIPRI feature.", result != -1); // Check that the ConnectivityManager reported that it connected using hipri... - assertTrue("Couldn't connect using hipri...", receiver.waitForConnection()); + assertTrue("Couldn't connect using hipri...", receiver.waitForState()); assertTrue("Couldn't requestRouteToHost using HIPRI.", mCm.requestRouteToHost(ConnectivityManager.TYPE_MOBILE_HIPRI, HOST_ADDRESS)); @@ -307,7 +313,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { // TODO check dns selection // TODO check routes if (!isWifiEnabled) { - mWifiManager.setWifiEnabled(false); + disconnectFromWifi(); } } } @@ -323,7 +329,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { */ public void testRegisterNetworkCallback() { if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) { - Log.i(TAG, "testRegisterNetworkCallback cannot execute unless devices supports WiFi"); + Log.i(TAG, "testRegisterNetworkCallback cannot execute unless device supports WiFi"); return; } @@ -353,47 +359,167 @@ public class ConnectivityManagerTest extends AndroidTestCase { mCm.unregisterNetworkCallback(callback); // Return WiFI to its original enabled/disabled state. - mWifiManager.setWifiEnabled(previousWifiEnabledState); + if (!previousWifiEnabledState) { + disconnectFromWifi(); + } } } - private void connectToWifi() throws InterruptedException { - ConnectivityActionReceiver receiver = - new ConnectivityActionReceiver(ConnectivityManager.TYPE_WIFI); + /** + * Tests both registerNetworkCallback and unregisterNetworkCallback similarly to + * {@link #testRegisterNetworkCallback} except that a {@code PendingIntent} is used instead + * of a {@code NetworkCallback}. + */ + public void testRegisterNetworkCallback_withPendingIntent() { + if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) { + Log.i(TAG, "testRegisterNetworkCallback cannot execute unless device supports WiFi"); + return; + } + + // Create a ConnectivityActionReceiver that has an IntentFilter for our locally defined + // action, NETWORK_CALLBACK_ACTION. + IntentFilter filter = new IntentFilter(); + filter.addAction(NETWORK_CALLBACK_ACTION); + + ConnectivityActionReceiver receiver = new ConnectivityActionReceiver( + ConnectivityManager.TYPE_WIFI, NetworkInfo.State.CONNECTED); + mContext.registerReceiver(receiver, filter); + + // Create a broadcast PendingIntent for NETWORK_CALLBACK_ACTION. + Intent intent = new Intent(NETWORK_CALLBACK_ACTION); + PendingIntent pendingIntent = PendingIntent.getBroadcast( + mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); + + // We will register for a WIFI network being available or lost. + NetworkRequest request = new NetworkRequest.Builder() + .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) + .build(); + mCm.registerNetworkCallback(request, pendingIntent); + + boolean previousWifiEnabledState = mWifiManager.isWifiEnabled(); + + try { + // Make sure WiFi is connected to an access point to start with. + if (!previousWifiEnabledState) { + connectToWifi(); + } + + // Now we expect to get the Intent delivered notifying of the availability of the wifi + // network even if it was already connected as a state-based action when the callback + // is registered. + assertTrue("Did not receive expected Intent " + intent + " for TRANSPORT_WIFI", + receiver.waitForState()); + } catch (InterruptedException e) { + fail("Broadcast receiver or NetworkCallback wait was interrupted."); + } finally { + mCm.unregisterNetworkCallback(pendingIntent); + pendingIntent.cancel(); + mContext.unregisterReceiver(receiver); + + // Return WiFI to its original enabled/disabled state. + if (!previousWifiEnabledState) { + disconnectFromWifi(); + } + } + } + + /** Enable WiFi and wait for it to become connected to a network. */ + private void connectToWifi() { + ConnectivityActionReceiver receiver = new ConnectivityActionReceiver( + ConnectivityManager.TYPE_WIFI, NetworkInfo.State.CONNECTED); IntentFilter filter = new IntentFilter(); filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); mContext.registerReceiver(receiver, filter); - assertTrue(mWifiManager.setWifiEnabled(true)); - assertTrue("Wifi must be configured to connect to an access point for this test.", - receiver.waitForConnection()); + boolean connected = false; + try { + assertTrue(mWifiManager.setWifiEnabled(true)); + connected = receiver.waitForState(); + } catch (InterruptedException ex) { + fail("connectToWifi was interrupted"); + } finally { + mContext.unregisterReceiver(receiver); + } - mContext.unregisterReceiver(receiver); + assertTrue("Wifi must be configured to connect to an access point for this test.", + connected); } - /** Receiver that captures the last connectivity change's network type and state. */ + /** Disable WiFi and wait for it to become disconnected from the network. */ + private void disconnectFromWifi() { + ConnectivityActionReceiver receiver = new ConnectivityActionReceiver( + ConnectivityManager.TYPE_WIFI, NetworkInfo.State.DISCONNECTED); + IntentFilter filter = new IntentFilter(); + filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); + mContext.registerReceiver(receiver, filter); + + boolean disconnected = false; + try { + assertTrue(mWifiManager.setWifiEnabled(false)); + disconnected = receiver.waitForState(); + } catch (InterruptedException ex) { + fail("disconnectFromWifi was interrupted"); + } finally { + mContext.unregisterReceiver(receiver); + } + + assertTrue("Wifi failed to reach DISCONNECTED state.", disconnected); + } + + /** + * Receiver that captures the last connectivity change's network type and state. Recognizes + * both {@code CONNECTIVITY_ACTION} and {@code NETWORK_CALLBACK_ACTION} intents. + */ private class ConnectivityActionReceiver extends BroadcastReceiver { private final CountDownLatch mReceiveLatch = new CountDownLatch(1); private final int mNetworkType; + private final NetworkInfo.State mNetState; - ConnectivityActionReceiver(int networkType) { + ConnectivityActionReceiver(int networkType, NetworkInfo.State netState) { mNetworkType = networkType; + mNetState = netState; } public void onReceive(Context context, Intent intent) { - NetworkInfo networkInfo = intent.getExtras() - .getParcelable(ConnectivityManager.EXTRA_NETWORK_INFO); + String action = intent.getAction(); + NetworkInfo networkInfo = null; + + // When receiving ConnectivityManager.CONNECTIVITY_ACTION, the NetworkInfo parcelable + // is stored in EXTRA_NETWORK_INFO. With a NETWORK_CALLBACK_ACTION, the Network is + // sent in EXTRA_NETWORK and we need to ask the ConnectivityManager for the NetworkInfo. + if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) { + networkInfo = intent.getExtras() + .getParcelable(ConnectivityManager.EXTRA_NETWORK_INFO); + assertNotNull("ConnectivityActionReceiver expected EXTRA_NETWORK_INFO", networkInfo); + } else if (NETWORK_CALLBACK_ACTION.equals(action)) { + Network network = intent.getExtras() + .getParcelable(ConnectivityManager.EXTRA_NETWORK); + assertNotNull("ConnectivityActionReceiver expected EXTRA_NETWORK", network); + networkInfo = mCm.getNetworkInfo(network); + if (networkInfo == null) { + // When disconnecting, it seems like we get an intent sent with an invalid + // Network; that is, by the time we call ConnectivityManager.getNetworkInfo(), + // it is invalid. Ignore these. + Log.i(TAG, "ConnectivityActionReceiver NETWORK_CALLBACK_ACTION ignoring " + + "invalid network"); + return; + } + } else { + fail("ConnectivityActionReceiver received unxpected intent action: " + action); + } + + assertNotNull("ConnectivityActionReceiver didn't find NetworkInfo", networkInfo); int networkType = networkInfo.getType(); State networkState = networkInfo.getState(); Log.i(TAG, "Network type: " + networkType + " state: " + networkState); - if (networkType == mNetworkType && networkInfo.getState() == State.CONNECTED) { + if (networkType == mNetworkType && networkInfo.getState() == mNetState) { mReceiveLatch.countDown(); } } - public boolean waitForConnection() throws InterruptedException { + public boolean waitForState() throws InterruptedException { return mReceiveLatch.await(30, TimeUnit.SECONDS); } } @@ -402,7 +528,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { * Callback used in testRegisterNetworkCallback that allows caller to block on * {@code onAvailable}. */ - private class TestNetworkCallback extends ConnectivityManager.NetworkCallback { + private static class TestNetworkCallback extends ConnectivityManager.NetworkCallback { private final CountDownLatch mAvailableLatch = new CountDownLatch(1); public boolean waitForAvailable() throws InterruptedException { From e57e9bcb96cb61cfa9306431089300fd28f44675 Mon Sep 17 00:00:00 2001 From: Fyodor Kupolov Date: Wed, 29 Jul 2015 11:24:34 -0700 Subject: [PATCH 0178/1109] Fix for ScanResultTest and WifiManagerTest Added ACCESS_COARSE_LOCATION permission - it is now required to receive Wi-Fi scan results(b/21852542). Bug: 22790182 Change-Id: Idb72c200b08f7e4e95571504ab42c9e706f5c921 --- tests/cts/net/AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index bca2d2c1ba..001e2946b1 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -20,6 +20,7 @@ + From cfc277c7f13f8b9fce9adf538596f4b1ce210f51 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Thu, 6 Aug 2015 16:09:55 +0900 Subject: [PATCH 0179/1109] Update CTS for unsupported legacy ConnectivityManager APIs http://ag/736511 made the deprecated ConnectivityManager routing APIs {start,stop}UsingNetworkFeature and requestRouteToHost throw exceptions for apps whose target SDK version is 23 or above. Move the tests for these APIs to a new APK that targets SDK version 22 and update the current test APK to ensure that they throw an exception. Bug: 22977863 Bug: 23003441 Bug: 23003635 Change-Id: Icf58e928fdc0018d977ce8aa315866659d32debb --- .../net/cts/ConnectivityManagerTest.java | 128 ++++-------------- 1 file changed, 25 insertions(+), 103 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index e4d77b1c77..88dbd7c686 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -67,7 +67,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { private PackageManager mPackageManager; private final HashMap mNetworks = new HashMap(); - private final ListmProtectedNetworks = new ArrayList(); @Override protected void setUp() throws Exception { @@ -90,13 +89,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { mNetworks.put(n.type, n); } catch (Exception e) {} } - - // Get com.android.internal.R.array.config_protectedNetworks - resId = getContext().getResources().getIdentifier("config_protectedNetworks", "array", "android"); - int[] protectedNetworks = getContext().getResources().getIntArray(resId); - for (int p : protectedNetworks) { - mProtectedNetworks.add(p); - } } public void testIsNetworkTypeValid() { @@ -190,6 +182,27 @@ public class ConnectivityManagerTest extends AndroidTestCase { } } + private void assertStartUsingNetworkFeatureUnsupported(int networkType, String feature) { + try { + mCm.startUsingNetworkFeature(networkType, feature); + fail("startUsingNetworkFeature is no longer supported in the current API version"); + } catch (UnsupportedOperationException expected) {} + } + + private void assertStopUsingNetworkFeatureUnsupported(int networkType, String feature) { + try { + mCm.startUsingNetworkFeature(networkType, feature); + fail("stopUsingNetworkFeature is no longer supported in the current API version"); + } catch (UnsupportedOperationException expected) {} + } + + private void assertRequestRouteToHostUnsupported(int networkType, int hostAddress) { + try { + mCm.requestRouteToHost(networkType, hostAddress); + fail("requestRouteToHost is no longer supported in the current API version"); + } catch (UnsupportedOperationException expected) {} + } + public void testStartUsingNetworkFeature() { final String invalidateFeature = "invalidateFeature"; @@ -198,27 +211,9 @@ public class ConnectivityManagerTest extends AndroidTestCase { final int wifiOnlyStartFailureCode = PhoneConstants.APN_REQUEST_FAILED; final int wifiOnlyStopFailureCode = -1; - NetworkInfo ni = mCm.getNetworkInfo(TYPE_MOBILE); - if (ni != null) { - assertEquals(PhoneConstants.APN_REQUEST_FAILED, - mCm.startUsingNetworkFeature(TYPE_MOBILE, invalidateFeature)); - assertEquals(failureCode, mCm.stopUsingNetworkFeature(TYPE_MOBILE, - invalidateFeature)); - } else { - assertEquals(wifiOnlyStartFailureCode, mCm.startUsingNetworkFeature(TYPE_MOBILE, - invalidateFeature)); - assertEquals(wifiOnlyStopFailureCode, mCm.stopUsingNetworkFeature(TYPE_MOBILE, - invalidateFeature)); - } - - ni = mCm.getNetworkInfo(TYPE_WIFI); - if (ni != null) { - // Should return failure because MMS is not supported on WIFI. - assertEquals(PhoneConstants.APN_REQUEST_FAILED, mCm.startUsingNetworkFeature(TYPE_WIFI, - mmsFeature)); - assertEquals(failureCode, mCm.stopUsingNetworkFeature(TYPE_WIFI, - mmsFeature)); - } + assertStartUsingNetworkFeatureUnsupported(TYPE_MOBILE, invalidateFeature); + assertStopUsingNetworkFeatureUnsupported(TYPE_MOBILE, invalidateFeature); + assertStartUsingNetworkFeatureUnsupported(TYPE_WIFI, mmsFeature); } private boolean isSupported(int networkType) { @@ -229,11 +224,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { (networkType == ConnectivityManager.TYPE_VPN); } - // true if only the system can turn it on - private boolean isNetworkProtected(int networkType) { - return mProtectedNetworks.contains(networkType); - } - public void testIsNetworkSupported() { for (int type = -1; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) { boolean supported = mCm.isNetworkSupported(type); @@ -247,82 +237,14 @@ public class ConnectivityManagerTest extends AndroidTestCase { public void testRequestRouteToHost() { for (int type = -1 ; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) { - NetworkInfo ni = mCm.getNetworkInfo(type); - boolean expectToWork = isSupported(type) && !isNetworkProtected(type) && - ni != null && ni.isConnected(); - - try { - assertTrue("Network type " + type, - mCm.requestRouteToHost(type, HOST_ADDRESS) == expectToWork); - } catch (Exception e) { - Log.d(TAG, "got exception in requestRouteToHost for type " + type); - assertFalse("Exception received for type " + type, expectToWork); - } - - //TODO verify route table + assertRequestRouteToHostUnsupported(type, HOST_ADDRESS); } - - assertFalse(mCm.requestRouteToHost(-1, HOST_ADDRESS)); } public void testTest() { mCm.getBackgroundDataSetting(); } - /** Test that hipri can be brought up when Wifi is enabled. */ - public void testStartUsingNetworkFeature_enableHipri() throws Exception { - if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY) - || !mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) { - // This test requires a mobile data connection and WiFi. - return; - } - - boolean isWifiEnabled = mWifiManager.isWifiEnabled(); - boolean isWifiConnected = false; - - NetworkInfo nwInfo = mCm.getNetworkInfo(ConnectivityManager.TYPE_WIFI); - if (nwInfo != null) { - isWifiConnected = nwInfo.isConnected(); - } - try { - // Make sure WiFi is connected to an access point. - if (!isWifiConnected) { - connectToWifi(); - } - - // Register a receiver that will capture the connectivity change for hipri. - ConnectivityActionReceiver receiver = new ConnectivityActionReceiver( - ConnectivityManager.TYPE_MOBILE_HIPRI, NetworkInfo.State.CONNECTED); - IntentFilter filter = new IntentFilter(); - filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); - mContext.registerReceiver(receiver, filter); - - // Try to start using the hipri feature... - int result = mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, - FEATURE_ENABLE_HIPRI); - assertTrue("Couldn't start using the HIPRI feature.", result != -1); - - // Check that the ConnectivityManager reported that it connected using hipri... - assertTrue("Couldn't connect using hipri...", receiver.waitForState()); - - assertTrue("Couldn't requestRouteToHost using HIPRI.", - mCm.requestRouteToHost(ConnectivityManager.TYPE_MOBILE_HIPRI, HOST_ADDRESS)); - // TODO check dns selection - // TODO check routes - } catch (InterruptedException e) { - fail("Broadcast receiver waiting for ConnectivityManager interrupted."); - } finally { - mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, - FEATURE_ENABLE_HIPRI); - // TODO wait for HIPRI to go - // TODO check dns selection - // TODO check routes - if (!isWifiEnabled) { - disconnectFromWifi(); - } - } - } - /** * Exercises both registerNetworkCallback and unregisterNetworkCallback. This checks to * see if we get a callback for the TRANSPORT_WIFI transport type being available. From f19c63e5b169e15f7f6a4bb8cf82d45e81f9a6e1 Mon Sep 17 00:00:00 2001 From: Erik Kline Date: Fri, 7 Aug 2015 12:45:14 +0900 Subject: [PATCH 0180/1109] Add trivial retransmission of QUIC packets Also: - correct use of strlcpy() - add some more logging Bug: 21833352 Bug: 22181260 Change-Id: Id153e17b8d4d32a35d38846599aa51147739e163 --- tests/cts/net/jni/NativeMultinetworkJni.c | 53 ++++++++++++++++------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/tests/cts/net/jni/NativeMultinetworkJni.c b/tests/cts/net/jni/NativeMultinetworkJni.c index 4da0c1c4a3..ad56b510c3 100644 --- a/tests/cts/net/jni/NativeMultinetworkJni.c +++ b/tests/cts/net/jni/NativeMultinetworkJni.c @@ -93,7 +93,8 @@ static const int kSockaddrStrLen = INET6_ADDRSTRLEN + strlen("[]:65535"); void sockaddr_ntop(const struct sockaddr *sa, socklen_t salen, char *dst, const size_t size) { char addrstr[INET6_ADDRSTRLEN]; char portstr[sizeof("65535")]; - char buf[sizeof(addrstr) + sizeof(portstr) + sizeof("[]:")]; + char buf[kSockaddrStrLen+1]; + int ret = getnameinfo(sa, salen, addrstr, sizeof(addrstr), portstr, sizeof(portstr), @@ -106,7 +107,7 @@ void sockaddr_ntop(const struct sockaddr *sa, socklen_t salen, char *dst, const sprintf(buf, "???"); } - strlcpy(dst, buf, (strlen(buf) < size - 1) ? strlen(buf) : size - 1); + strlcpy(dst, buf, size); } JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( @@ -122,7 +123,8 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( struct addrinfo *res = NULL; net_handle_t handle = (net_handle_t) nethandle; - int rval = android_getaddrinfofornetwork(handle, kHostname, "443", &kHints, &res); + static const char kPort[] = "443"; + int rval = android_getaddrinfofornetwork(handle, kHostname, kPort, &kHints, &res); if (rval != 0) { ALOGD("android_getaddrinfofornetwork(%llu, %s) returned rval=%d errno=%d", handle, kHostname, rval, errno); @@ -148,9 +150,9 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( return -errno; } - char addrstr[kSockaddrStrLen]; + char addrstr[kSockaddrStrLen+1]; sockaddr_ntop(res->ai_addr, res->ai_addrlen, addrstr, sizeof(addrstr)); - ALOGD("Attempting connect() to %s...", addrstr); + ALOGD("Attempting connect() to %s ...", addrstr); rval = connect(fd, res->ai_addr, res->ai_addrlen); if (rval != 0) { @@ -170,10 +172,12 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( ALOGD("... from %s", addrstr); // Don't let reads or writes block indefinitely. - const struct timeval timeo = { 5, 0 }; // 5 seconds + const struct timeval timeo = { 2, 0 }; // 2 seconds setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo)); setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeo, sizeof(timeo)); + // For reference see: + // https://tools.ietf.org/html/draft-tsvwg-quic-protocol-01#section-6.1 uint8_t quic_packet[] = { 0x0c, // public flags: 64bit conn ID, 8bit sequence number 0, 0, 0, 0, 0, 0, 0, 0, // 64bit connection ID @@ -184,19 +188,36 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( arc4random_buf(quic_packet + 1, 8); // random connection ID - ssize_t sent = send(fd, quic_packet, sizeof(quic_packet), 0); - if (sent < (ssize_t)sizeof(quic_packet)) { - ALOGD("send(QUIC packet) returned sent=%zd, errno=%d", sent, errno); - close(fd); - return -errno; - } - uint8_t response[1500]; - ssize_t rcvd = recv(fd, response, sizeof(response), 0); + ssize_t sent, rcvd; + static const int MAX_RETRIES = 5; + int i, errnum = 0; + + for (i = 0; i < MAX_RETRIES; i++) { + sent = send(fd, quic_packet, sizeof(quic_packet), 0); + if (sent < (ssize_t)sizeof(quic_packet)) { + errnum = errno; + ALOGD("send(QUIC packet) returned sent=%zd, errno=%d", sent, errnum); + close(fd); + return -errnum; + } + + rcvd = recv(fd, response, sizeof(response), 0); + if (rcvd > 0) { + break; + } else { + errnum = errno; + ALOGD("[%d/%d] recv(QUIC response) returned rcvd=%zd, errno=%d", + i + 1, MAX_RETRIES, rcvd, errnum); + } + } if (rcvd < sent) { - ALOGD("recv() returned rcvd=%zd, errno=%d", rcvd, errno); + ALOGD("QUIC UDP %s: sent=%zd but rcvd=%zd, errno=%d", kPort, sent, rcvd, errnum); + if (rcvd <= 0) { + ALOGD("Does this network block UDP port %s?", kPort); + } close(fd); - return -errno; + return -EPROTO; } int conn_id_cmp = memcmp(quic_packet + 1, response + 1, 8); From de95223f871d9aec9be68dee3afc89d0c36be952 Mon Sep 17 00:00:00 2001 From: Nash Lincoln Date: Thu, 17 Sep 2015 13:46:25 -0700 Subject: [PATCH 0181/1109] migrate net tests to cts_v2 bug:21762834 Change-Id: Ic86dee963720c1412a42ec231c81c97d7f322420 --- tests/cts/net/Android.mk | 3 +++ tests/cts/net/AndroidManifest.xml | 4 ++-- tests/cts/net/AndroidTest.xml | 22 ++++++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 tests/cts/net/AndroidTest.xml diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index 652487126d..716141d5b2 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -40,6 +40,9 @@ LOCAL_STATIC_JAVA_LIBRARIES := core-tests-support ctsdeviceutil \ # uncomment when b/13249961 is fixed #LOCAL_SDK_VERSION := current +# Tag this module as a cts_v2 test artifact +LOCAL_COMPATIBILITY_SUITE := cts_v2 + include $(BUILD_CTS_PACKAGE) include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index 001e2946b1..2bc82164de 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -16,7 +16,7 @@ --> + package="android.net.cts"> @@ -35,7 +35,7 @@ diff --git a/tests/cts/net/AndroidTest.xml b/tests/cts/net/AndroidTest.xml new file mode 100644 index 0000000000..ee0d636939 --- /dev/null +++ b/tests/cts/net/AndroidTest.xml @@ -0,0 +1,22 @@ + + + + From 45984684aa2688924e10ea95c3951ece6c9b3f0b Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Tue, 22 Sep 2015 08:07:46 -0400 Subject: [PATCH 0182/1109] CTS: verify ConnectivityManager.requestNetwork throws for restricted networks Bug:21900139 Change-Id: Ib026bc4e66437f015729bdf7c923145ffa41fbde --- .../net/cts/ConnectivityManagerTest.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index d79ecdddb4..eeae257a26 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -16,16 +16,21 @@ package android.net.cts; +import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS; +import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; + import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.net.ConnectivityManager; +import android.net.ConnectivityManager.NetworkCallback; import android.net.NetworkConfig; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; +import android.net.NetworkRequest; import android.net.wifi.WifiManager; import android.test.AndroidTestCase; import android.util.Log; @@ -334,4 +339,23 @@ public class ConnectivityManagerTest extends AndroidTestCase { return mReceiveLatch.await(30, TimeUnit.SECONDS); } } + + /** Verify restricted networks cannot be requested. */ + public void testRestrictedNetworks() { + // Verify we can request unrestricted networks: + NetworkRequest request = new NetworkRequest.Builder() + .addCapability(NET_CAPABILITY_INTERNET).build(); + NetworkCallback callback = new NetworkCallback(); + mCm.requestNetwork(request, callback); + mCm.unregisterNetworkCallback(callback); + // Verify we cannot request restricted networks: + request = new NetworkRequest.Builder().addCapability(NET_CAPABILITY_IMS).build(); + callback = new NetworkCallback(); + try { + mCm.requestNetwork(request, callback); + fail("No exception thrown when restricted network requested."); + } catch (SecurityException e) { + // Expected. + } + } } From d62c5997f6966ba0e1123eb5badc71917b025f9e Mon Sep 17 00:00:00 2001 From: Aaron Holden Date: Mon, 28 Sep 2015 10:37:27 -0700 Subject: [PATCH 0183/1109] Add WiFi precondition check to 'net' CTS module bug:23939594 Change-Id: I9e625e635fc6942c9eaa95915888f0fe7284a9ea --- tests/cts/net/AndroidTest.xml | 7 ++++ tests/cts/net/preconditions/Android.mk | 39 +++++++++++++++++++ .../cts/net/preconditions/AndroidManifest.xml | 31 +++++++++++++++ .../net/preconditions/PreconditionsTest.java | 39 +++++++++++++++++++ 4 files changed, 116 insertions(+) create mode 100644 tests/cts/net/preconditions/Android.mk create mode 100644 tests/cts/net/preconditions/AndroidManifest.xml create mode 100644 tests/cts/net/preconditions/src/android/net/preconditions/PreconditionsTest.java diff --git a/tests/cts/net/AndroidTest.xml b/tests/cts/net/AndroidTest.xml index ee0d636939..d52214e80a 100644 --- a/tests/cts/net/AndroidTest.xml +++ b/tests/cts/net/AndroidTest.xml @@ -19,4 +19,11 @@

These tests rely on a host-side test to use {@code adb shell cmd netpolicy} to put the device + * in the proper state. In fact, they're more like "assertions" than tests per se - the real test + * logic is done on {@code HostsideNetworkTests}. + */ +public class ConnectivityManagerTest extends InstrumentationTestCase { + private static final String TAG = "ConnectivityManagerTest"; + + private ConnectivityManager mCM; + + @Override + public void setUp() throws Exception { + super.setUp(); + mCM = (ConnectivityManager) getInstrumentation().getContext().getSystemService( + Activity.CONNECTIVITY_SERVICE); + } + + public void testGetRestrictBackgroundStatus_disabled() { + assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + } + + public void testGetRestrictBackgroundStatus_whitelisted() { + assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_WHITELISTED); + } + + public void testGetRestrictBackgroundStatus_enabled() { + assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); + } + + private void assertRestrictBackgroundStatus(int expectedStatus) { + final String expected = toString(expectedStatus); + Log.d(TAG, getName() + " (expecting " + expected + ")"); + final @RestrictBackgroundStatus int actualStatus = mCM.getRestrictBackgroundStatus(); + assertEquals("wrong status", expected, toString(actualStatus)); + } + + private String toString(@RestrictBackgroundStatus int status) { + switch (status) { + case RESTRICT_BACKGROUND_STATUS_DISABLED: + return "DISABLED"; + case RESTRICT_BACKGROUND_STATUS_WHITELISTED: + return "WHITELISTED"; + case RESTRICT_BACKGROUND_STATUS_ENABLED: + return "ENABLED"; + default: + return "UNKNOWN_STATUS_" + status; + } + } +} diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTests.java index f42de0e4aa..dd2424c13a 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTests.java @@ -17,6 +17,7 @@ package com.android.cts.net; import com.android.cts.migration.MigrationHelper; +import com.android.ddmlib.Log; import com.android.ddmlib.testrunner.RemoteAndroidTestRunner; import com.android.ddmlib.testrunner.TestIdentifier; import com.android.ddmlib.testrunner.TestResult; @@ -24,17 +25,20 @@ import com.android.ddmlib.testrunner.TestResult.TestStatus; import com.android.ddmlib.testrunner.TestRunResult; import com.android.tradefed.build.IBuildInfo; import com.android.tradefed.device.DeviceNotAvailableException; +import com.android.tradefed.result.CollectingTestListener; import com.android.tradefed.testtype.DeviceTestCase; import com.android.tradefed.testtype.IAbi; import com.android.tradefed.testtype.IAbiReceiver; import com.android.tradefed.testtype.IBuildReceiver; -import com.android.tradefed.device.DeviceNotAvailableException; -import com.android.tradefed.device.ITestDevice; -import com.android.tradefed.result.CollectingTestListener; +import java.io.FileNotFoundException; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class HostsideNetworkTests extends DeviceTestCase implements IAbiReceiver, IBuildReceiver { + private static final boolean DEBUG = false; + private static final String TAG = "HostsideNetworkTests"; private static final String TEST_PKG = "com.android.cts.net.hostside"; private static final String TEST_APK = "CtsHostsideNetworkTestsApp.apk"; @@ -58,28 +62,130 @@ public class HostsideNetworkTests extends DeviceTestCase implements IAbiReceiver assertNotNull(mAbi); assertNotNull(mCtsBuild); - getDevice().uninstallPackage(TEST_PKG); - - assertNull(getDevice().installPackage( - MigrationHelper.getTestFile(mCtsBuild, TEST_APK), false)); + setRestrictBackground(false); + uninstallTestPackage(false); + installTestPackage(); } @Override protected void tearDown() throws Exception { super.tearDown(); - getDevice().uninstallPackage(TEST_PKG); + uninstallTestPackage(false); + setRestrictBackground(false); } public void testVpn() throws Exception { - runDeviceTests(TEST_PKG, ".VpnTest"); + runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest"); + } + + public void testConnectivityManager_getRestrictBackgroundStatus_disabled() throws Exception { + final int uid = getUid(TEST_PKG); + removeRestrictBackgroundWhitelist(uid); + assertRestrictBackgroundStatusDisabled(); + // Sanity check: make sure status is always disabled, never whitelisted + addRestrictBackgroundWhitelist(uid); + assertRestrictBackgroundStatusDisabled(); + } + + public void testConnectivityManager_getRestrictBackgroundStatus_whitelisted() throws Exception { + final int uid = getUid(TEST_PKG); + setRestrictBackground(true); + addRestrictBackgroundWhitelist(uid); + assertRestrictBackgroundStatusWhitelisted(); + } + + public void testConnectivityManager_getRestrictBackgroundStatus_enabled() throws Exception { + final int uid = getUid(TEST_PKG); + setRestrictBackground(true); + removeRestrictBackgroundWhitelist(uid); + assertRestrictBackgroundStatusEnabled(); + } + + public void testConnectivityManager_getRestrictBackgroundStatus_uninstall() throws Exception { + final int uid = getUid(TEST_PKG); + + addRestrictBackgroundWhitelist(uid); + assertRestrictBackgroundWhitelist(uid, true); + + uninstallTestPackage(true); + assertPackageUninstalled(TEST_PKG); + assertRestrictBackgroundWhitelist(uid, false); + + installTestPackage(); + final int newUid = getUid(TEST_PKG); + assertRestrictBackgroundWhitelist(uid, false); + assertRestrictBackgroundWhitelist(newUid, false); + } + + private void installTestPackage() throws DeviceNotAvailableException, FileNotFoundException { + assertNull(getDevice().installPackage( + MigrationHelper.getTestFile(mCtsBuild, TEST_APK), false)); + } + + private void uninstallTestPackage(boolean shouldSucceed) throws DeviceNotAvailableException { + final String result = getDevice().uninstallPackage(TEST_PKG); + if (shouldSucceed) { + assertNull("uninstallPackage failed: " + result, result); + } + } + + private void assertPackageUninstalled(String packageName) throws DeviceNotAvailableException { + final String command = "cmd package list packages -f " + packageName; + final int max_tries = 5; + for (int i = 1; i <= max_tries; i++) { + final String result = runCommand(command); + if (result.trim().isEmpty()) { + return; + } + i++; + Log.v(TAG, "Package " + packageName + " not uninstalled yet (" + result + + "); sleeping 1s before polling again"); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + fail("Package '" + packageName + "' not uinstalled after " + max_tries + " seconds"); + } + + private void assertRestrictBackgroundStatusDisabled() throws DeviceNotAvailableException { + runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", + "testGetRestrictBackgroundStatus_disabled"); + } + + private void assertRestrictBackgroundStatusWhitelisted() throws DeviceNotAvailableException { + runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", + "testGetRestrictBackgroundStatus_whitelisted"); + } + + private void assertRestrictBackgroundStatusEnabled() throws DeviceNotAvailableException { + runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", + "testGetRestrictBackgroundStatus_enabled"); } public void runDeviceTests(String packageName, String testClassName) - throws DeviceNotAvailableException { + throws DeviceNotAvailableException { + runDeviceTests(packageName, testClassName, null); + } + + public void runDeviceTests(String packageName, String testClassName, String methodName) + throws DeviceNotAvailableException { RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(packageName, "android.support.test.runner.AndroidJUnitRunner", getDevice().getIDevice()); + if (testClassName != null) { + // TODO: figure out why testRunner.setMethodName() / testRunner.setClassName() doesn't + // work + final StringBuilder runOptions = new StringBuilder("-e class ").append(testClassName); + if (methodName != null) { + runOptions.append('#').append(methodName); + } + Log.i(TAG, "Setting runOptions() as " + runOptions); + testRunner.setRunOptions(runOptions.toString()); + } + final CollectingTestListener listener = new CollectingTestListener(); getDevice().runInstrumentationTests(testRunner, listener); @@ -103,4 +209,57 @@ public class HostsideNetworkTests extends DeviceTestCase implements IAbiReceiver throw new AssertionError(errorBuilder.toString()); } } + + private static final Pattern UID_PATTERN = + Pattern.compile(".*userId=([0-9]+)$", Pattern.MULTILINE); + + private int getUid(String packageName) throws DeviceNotAvailableException { + final String output = runCommand("dumpsys package " + packageName); + final Matcher matcher = UID_PATTERN.matcher(output); + while (matcher.find()) { + final String match = matcher.group(1); + return Integer.parseInt(match); + } + throw new RuntimeException("Did not find regexp '" + UID_PATTERN + "' on adb output\n" + + output); + } + + private void addRestrictBackgroundWhitelist(int uid) throws DeviceNotAvailableException { + runCommand("cmd netpolicy add restrict-background-whitelist " + uid); + assertRestrictBackgroundWhitelist(uid, true); + } + + private void removeRestrictBackgroundWhitelist(int uid) throws DeviceNotAvailableException { + runCommand("cmd netpolicy remove restrict-background-whitelist " + uid); + assertRestrictBackgroundWhitelist(uid, false); + } + + private void assertRestrictBackgroundWhitelist(int uid, boolean expected) + throws DeviceNotAvailableException { + final String output = runCommand("cmd netpolicy list restrict-background-whitelist "); + // TODO: use MoreAsserts + if (expected) { + assertTrue("Did not find uid '" + uid + "' on '" + output + "'", + output.contains(Integer.toString(uid))); + } else { + assertFalse("Found uid '" + uid + "' on '" + output + "'", + output.contains(Integer.toString(uid))); + } + } + + private void setRestrictBackground(boolean enabled) throws DeviceNotAvailableException { + runCommand("cmd netpolicy set restrict-background " + enabled); + final String output = runCommand("cmd netpolicy get restrict-background ").trim(); + final String expectedSuffix = enabled ? "enabled" : "disabled"; + // TODO: use MoreAsserts? + assertTrue("output '" + output + "' should end with '" + expectedSuffix + "'", + output.endsWith(expectedSuffix)); + } + + private String runCommand(String command) throws DeviceNotAvailableException { + Log.d(TAG, "Command: '" + command + "'"); + final String output = getDevice().executeShellCommand(command); + if (DEBUG) Log.v(TAG, "Output: " + output.trim()); + return output; + } } From d12935eed8c38baf35189f490e77e1955fbe592c Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Wed, 27 Jan 2016 12:34:06 -0800 Subject: [PATCH 0200/1109] Removed reference to hidden annotation. BUG: 26082535 BUG: 26451391 Change-Id: I267010a49df3212ca96f54b65aa7c8a14982a70c --- .../android/cts/net/hostside/ConnectivityManagerTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java index 42196abe7f..5d3812cffa 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java @@ -21,7 +21,6 @@ import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; import android.app.Activity; import android.net.ConnectivityManager; -import android.net.ConnectivityManager.RestrictBackgroundStatus; import android.test.InstrumentationTestCase; import android.util.Log; @@ -59,11 +58,11 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { private void assertRestrictBackgroundStatus(int expectedStatus) { final String expected = toString(expectedStatus); Log.d(TAG, getName() + " (expecting " + expected + ")"); - final @RestrictBackgroundStatus int actualStatus = mCM.getRestrictBackgroundStatus(); + final int actualStatus = mCM.getRestrictBackgroundStatus(); assertEquals("wrong status", expected, toString(actualStatus)); } - private String toString(@RestrictBackgroundStatus int status) { + private String toString(int status) { switch (status) { case RESTRICT_BACKGROUND_STATUS_DISABLED: return "DISABLED"; From 9980740cb943e22033ec885048de076a1d555866 Mon Sep 17 00:00:00 2001 From: Yi Kong Date: Thu, 21 Jan 2016 20:45:32 +0000 Subject: [PATCH 0201/1109] Wait for network to resume in ConcurrencyTest so that subsequent tests would not fail due to lack of network connection. Bug: 26182816 Change-Id: I6bc89897c9ad8e5966f03db7fc72169d3b973e53 --- .../android/net/wifi/cts/ConcurrencyTest.java | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java b/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java index 343c1e6399..a066ba80de 100644 --- a/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java @@ -20,12 +20,20 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.net.ConnectivityManager; +import android.net.ConnectivityManager.NetworkCallback; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.NetworkRequest; import android.net.wifi.WifiManager; import android.net.wifi.p2p.WifiP2pManager; import static android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_STATE_DISABLED; import static android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_STATE_ENABLED; import android.test.AndroidTestCase; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + public class ConcurrencyTest extends AndroidTestCase { private class MySync { int expectedWifiState; @@ -94,10 +102,7 @@ public class ConcurrencyTest extends AndroidTestCase { } mContext.unregisterReceiver(mReceiver); - if (!mWifiManager.isWifiEnabled()) { - assertTrue(mWifiManager.setWifiEnabled(true)); - Thread.sleep(DURATION); - } + enableWifi(); super.tearDown(); } @@ -114,6 +119,33 @@ public class ConcurrencyTest extends AndroidTestCase { } } + /* + * Enables Wifi and block until connection is established. + */ + private void enableWifi() throws InterruptedException { + if (!mWifiManager.isWifiEnabled()) { + assertTrue(mWifiManager.setWifiEnabled(true)); + } + + ConnectivityManager cm = + (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkRequest request = + new NetworkRequest.Builder().addTransportType(NetworkCapabilities.TRANSPORT_WIFI) + .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + .build(); + final CountDownLatch latch = new CountDownLatch(1); + NetworkCallback networkCallback = new NetworkCallback() { + @Override + public void onAvailable(Network network) { + latch.countDown(); + } + }; + cm.registerNetworkCallback(request, networkCallback); + latch.await(DURATION, TimeUnit.MILLISECONDS); + + cm.unregisterNetworkCallback(networkCallback); + } + public void testConcurrency() { // Cannot support p2p alone if (!WifiFeature.isWifiSupported(getContext())) { From f2b8106f8d8dcdf22b28e62a677048f71c228a0a Mon Sep 17 00:00:00 2001 From: Sergio Giro Date: Thu, 28 Jan 2016 14:40:48 +0000 Subject: [PATCH 0202/1109] AbstractVerifierTest: adapt tests to reflect that tabs are preserved by the DN parser Recently in 53f06c0d1dd4c7b48c965a8c6270d6acb12161ca I changed the tests to reflect the fact that tabs and newlines were discarded. I must have made some mistake verifying the change, as tabs seem preserved. Changing the assertion for tabs. Bug: 26517725 Change-Id: I514a3d670019e3e2911e2c69b434d0f577ff9b7a --- .../src/org/apache/http/conn/ssl/cts/AbstractVerifierTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/org/apache/http/conn/ssl/cts/AbstractVerifierTest.java b/tests/cts/net/src/org/apache/http/conn/ssl/cts/AbstractVerifierTest.java index 16d3ac452c..5e2a55e7ec 100644 --- a/tests/cts/net/src/org/apache/http/conn/ssl/cts/AbstractVerifierTest.java +++ b/tests/cts/net/src/org/apache/http/conn/ssl/cts/AbstractVerifierTest.java @@ -107,7 +107,7 @@ public final class AbstractVerifierTest extends TestCase { public void testGetCns_whitespace() { assertCns("cn= p", "p"); assertCns("cn=\np", "p"); - assertCns("cn=\tp", "p"); + assertCns("cn=\tp", "\tp"); } public void testGetCnsWithOid() { From 5b3513691797f4d7d3e2ed2713a9290b80f868d9 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Wed, 27 Jan 2016 14:49:54 -0800 Subject: [PATCH 0203/1109] Added CTS tests for RESTRICT_BACKGROUND_CHANGED. These tests require a second app (besides the test app) that defines a service; the host-side test then launches the service whose only purpose is to define a broadcast receiver, which in turn will count the number of intents received in a shared preferences file. Then the test app will read the shared preferences and assert the proper number of intents have been received. BUG: 26451391 Change-Id: I4c5d5e57c09a0bd57a7f6581820cc9115318dd47 --- tests/cts/hostside/app/AndroidManifest.xml | 3 +- .../net/hostside/ConnectivityManagerTest.java | 49 ++++++- .../android/cts/net/hostside/MyActivity.java | 4 - .../cts/net/hostside/MyVpnService.java | 1 - tests/cts/hostside/app2/Android.mk | 31 +++++ tests/cts/hostside/app2/AndroidManifest.xml | 37 +++++ .../android/cts/net/hostside/app2/Common.java | 23 ++++ .../hostside/app2/MyBroadcastReceiver.java | 51 +++++++ .../cts/net/hostside/app2/MyService.java | 44 ++++++ .../android/cts/net/HostsideNetworkTests.java | 128 +++++++++++++----- 10 files changed, 329 insertions(+), 42 deletions(-) create mode 100644 tests/cts/hostside/app2/Android.mk create mode 100644 tests/cts/hostside/app2/AndroidManifest.xml create mode 100644 tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java create mode 100644 tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java create mode 100644 tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java diff --git a/tests/cts/hostside/app/AndroidManifest.xml b/tests/cts/hostside/app/AndroidManifest.xml index cdde7dcb34..f44fdd1dfc 100644 --- a/tests/cts/hostside/app/AndroidManifest.xml +++ b/tests/cts/hostside/app/AndroidManifest.xml @@ -15,7 +15,8 @@ --> + package="com.android.cts.net.hostside" + android:sharedUserId="com.android.cts.net.hostside.apps"> diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java index 5d3812cffa..300e39d55e 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java @@ -16,10 +16,14 @@ package com.android.cts.net.hostside; +import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; + import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; import android.net.ConnectivityManager; import android.test.InstrumentationTestCase; import android.util.Log; @@ -34,6 +38,9 @@ import android.util.Log; public class ConnectivityManagerTest extends InstrumentationTestCase { private static final String TAG = "ConnectivityManagerTest"; + static final String MANIFEST_RECEIVER = "ManifestReceiver"; + static final String DYNAMIC_RECEIVER = "DynamicReceiver"; + private ConnectivityManager mCM; @Override @@ -41,7 +48,7 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { super.setUp(); mCM = (ConnectivityManager) getInstrumentation().getContext().getSystemService( Activity.CONNECTIVITY_SERVICE); - } + } public void testGetRestrictBackgroundStatus_disabled() { assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); @@ -55,6 +62,46 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); } + public void testRestrictBackgroundChangedReceivedOnce() throws Exception { + assertRestrictBackgroundChangedReceived(DYNAMIC_RECEIVER, 1); + assertRestrictBackgroundChangedReceived(MANIFEST_RECEIVER, 0); + } + + public void testRestrictBackgroundChangedReceivedTwice() throws Exception { + assertRestrictBackgroundChangedReceived(DYNAMIC_RECEIVER, 2); + assertRestrictBackgroundChangedReceived(MANIFEST_RECEIVER, 0); + } + + private void assertRestrictBackgroundChangedReceived(String receiverName, int expectedCount) + throws Exception { + int attempts = 0; + int count = 0; + final int maxAttempts = 5; + final int sleepTime = 10; + do { + attempts++; + count = getNumberBroadcastsReceived(getInstrumentation().getContext(), receiverName, + ACTION_RESTRICT_BACKGROUND_CHANGED); + if (count == expectedCount) { + break; + } + Log.d(TAG, "Count is " + count + " after " + attempts + " attempts; sleeping " + + sleepTime + " seconds before trying again"); + Thread.sleep(sleepTime * 1000); + } while (attempts <= maxAttempts); + assertEquals("Number of expected broadcasts for " + receiverName + " not reached after " + + maxAttempts * sleepTime + " seconds", expectedCount, count); + } + + static int getNumberBroadcastsReceived(Context context, String receiverName, String action) + throws Exception { + final Context sharedContext = context.createPackageContext( + "com.android.cts.net.hostside.app2", Context.CONTEXT_IGNORE_SECURITY); + final SharedPreferences prefs = sharedContext.getSharedPreferences(receiverName, + Context.MODE_PRIVATE); + return prefs.getInt(action, 0); + } + private void assertRestrictBackgroundStatus(int expectedStatus) { final String expected = toString(expectedStatus); Log.d(TAG, getName() + " (expecting " + expected + ")"); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyActivity.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyActivity.java index 375c8523c8..0d0bc58504 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyActivity.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyActivity.java @@ -18,13 +18,9 @@ package com.android.cts.net.hostside; import android.app.Activity; import android.content.Intent; -import android.net.VpnService; import android.os.Bundle; -import android.os.ParcelFileDescriptor; import android.view.WindowManager; -import java.util.Arrays; -import java.util.ArrayList; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyVpnService.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyVpnService.java index a3f400c388..90a3ce4b49 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyVpnService.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyVpnService.java @@ -26,7 +26,6 @@ import android.util.Log; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; -import java.util.ArrayList; public class MyVpnService extends VpnService { diff --git a/tests/cts/hostside/app2/Android.mk b/tests/cts/hostside/app2/Android.mk new file mode 100644 index 0000000000..e330bf7508 --- /dev/null +++ b/tests/cts/hostside/app2/Android.mk @@ -0,0 +1,31 @@ +# +# Copyright (C) 2016 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. +# + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests +LOCAL_SDK_VERSION := current + +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_PACKAGE_NAME := CtsHostsideNetworkTestsApp2 + +LOCAL_PROGUARD_ENABLED := disabled +LOCAL_DEX_PREOPT := false + +include $(BUILD_CTS_SUPPORT_PACKAGE) diff --git a/tests/cts/hostside/app2/AndroidManifest.xml b/tests/cts/hostside/app2/AndroidManifest.xml new file mode 100644 index 0000000000..d69bf56a1c --- /dev/null +++ b/tests/cts/hostside/app2/AndroidManifest.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java new file mode 100644 index 0000000000..91caeda97d --- /dev/null +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2016 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.cts.net.hostside.app2; + +public final class Common { + + static final String TAG = "CtsNetApp2"; + static final String MANIFEST_RECEIVER = "ManifestReceiver"; + static final String DYNAMIC_RECEIVER = "DynamicReceiver"; +} diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java new file mode 100644 index 0000000000..0cbf360d8f --- /dev/null +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2016 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.cts.net.hostside.app2; + +import static com.android.cts.net.hostside.app2.Common.MANIFEST_RECEIVER; +import static com.android.cts.net.hostside.app2.Common.TAG; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.util.Log; + +/** + * Receiver that stores received broadcasts in a shared preference. + */ +public class MyBroadcastReceiver extends BroadcastReceiver { + + private final String mName; + + public MyBroadcastReceiver() { + this(MANIFEST_RECEIVER); + } + + MyBroadcastReceiver(String name) { + Log.d(TAG, "Constructing MyBroadcastReceiver named " + name); + mName = name; + } + + @Override + public void onReceive(Context context, Intent intent) { + Log.d(TAG, "onReceive() for " + mName + ": " + intent); + final SharedPreferences prefs = context.getSharedPreferences(mName, Context.MODE_PRIVATE); + final String pref = intent.getAction(); + final int value = prefs.getInt(pref, 0) + 1; + Log.d(TAG, "Setting " + pref + " = " + value); + prefs.edit().putInt(pref, value).apply(); + } +} diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java new file mode 100644 index 0000000000..882bb62c2c --- /dev/null +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2016 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.cts.net.hostside.app2; + +import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; +import static com.android.cts.net.hostside.app2.Common.DYNAMIC_RECEIVER; +import static com.android.cts.net.hostside.app2.Common.TAG; +import android.app.Service; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.IBinder; +import android.util.Log; + +/** + * Service used to dynamically register a broadcast receiver. + */ +public class MyService extends Service { + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + Log.d(TAG, "onStartCommand: " + intent); + getApplicationContext().registerReceiver(new MyBroadcastReceiver(DYNAMIC_RECEIVER), + new IntentFilter(ACTION_RESTRICT_BACKGROUND_CHANGED)); + return START_STICKY; + } +} diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTests.java index dd2424c13a..bedfad61b3 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTests.java @@ -42,6 +42,9 @@ public class HostsideNetworkTests extends DeviceTestCase implements IAbiReceiver private static final String TEST_PKG = "com.android.cts.net.hostside"; private static final String TEST_APK = "CtsHostsideNetworkTestsApp.apk"; + private static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2"; + private static final String TEST_APP2_APK = "CtsHostsideNetworkTestsApp2.apk"; + private IAbi mAbi; private IBuildInfo mCtsBuild; @@ -63,15 +66,22 @@ public class HostsideNetworkTests extends DeviceTestCase implements IAbiReceiver assertNotNull(mCtsBuild); setRestrictBackground(false); - uninstallTestPackage(false); - installTestPackage(); + + uninstallPackage(TEST_PKG, false); + installPackage(TEST_APK); + // TODO: split this class into HostsideVpnTests and HostsideConnectivityManagerTests so + // the former don't need to unnecessarily install app2. + uninstallPackage(TEST_APP2_PKG, false); + installPackage(TEST_APP2_APK); } @Override protected void tearDown() throws Exception { super.tearDown(); - uninstallTestPackage(false); + uninstallPackage(TEST_PKG, true); + uninstallPackage(TEST_APP2_PKG, true); + setRestrictBackground(false); } @@ -80,26 +90,41 @@ public class HostsideNetworkTests extends DeviceTestCase implements IAbiReceiver } public void testConnectivityManager_getRestrictBackgroundStatus_disabled() throws Exception { + startBroadcastReceiverService(); final int uid = getUid(TEST_PKG); + removeRestrictBackgroundWhitelist(uid); assertRestrictBackgroundStatusDisabled(); + assertRestrictBackgroundChangedReceivedOnce(); + // Sanity check: make sure status is always disabled, never whitelisted addRestrictBackgroundWhitelist(uid); assertRestrictBackgroundStatusDisabled(); + assertRestrictBackgroundChangedReceivedTwice(); } public void testConnectivityManager_getRestrictBackgroundStatus_whitelisted() throws Exception { + startBroadcastReceiverService(); final int uid = getUid(TEST_PKG); + setRestrictBackground(true); + assertRestrictBackgroundChangedReceivedOnce(); + addRestrictBackgroundWhitelist(uid); assertRestrictBackgroundStatusWhitelisted(); + assertRestrictBackgroundChangedReceivedTwice(); } public void testConnectivityManager_getRestrictBackgroundStatus_enabled() throws Exception { + startBroadcastReceiverService(); final int uid = getUid(TEST_PKG); + setRestrictBackground(true); + assertRestrictBackgroundChangedReceivedOnce(); + removeRestrictBackgroundWhitelist(uid); assertRestrictBackgroundStatusEnabled(); + assertRestrictBackgroundChangedReceivedTwice(); } public void testConnectivityManager_getRestrictBackgroundStatus_uninstall() throws Exception { @@ -108,44 +133,66 @@ public class HostsideNetworkTests extends DeviceTestCase implements IAbiReceiver addRestrictBackgroundWhitelist(uid); assertRestrictBackgroundWhitelist(uid, true); - uninstallTestPackage(true); + uninstallPackage(TEST_PKG, true); assertPackageUninstalled(TEST_PKG); assertRestrictBackgroundWhitelist(uid, false); - installTestPackage(); + installPackage(TEST_APK); final int newUid = getUid(TEST_PKG); assertRestrictBackgroundWhitelist(uid, false); assertRestrictBackgroundWhitelist(newUid, false); } - private void installTestPackage() throws DeviceNotAvailableException, FileNotFoundException { + private void installPackage(String apk) throws DeviceNotAvailableException, + FileNotFoundException { assertNull(getDevice().installPackage( - MigrationHelper.getTestFile(mCtsBuild, TEST_APK), false)); + MigrationHelper.getTestFile(mCtsBuild, apk), false)); } - private void uninstallTestPackage(boolean shouldSucceed) throws DeviceNotAvailableException { - final String result = getDevice().uninstallPackage(TEST_PKG); + private void uninstallPackage(String packageName, boolean shouldSucceed) + throws DeviceNotAvailableException { + final String result = getDevice().uninstallPackage(packageName); if (shouldSucceed) { - assertNull("uninstallPackage failed: " + result, result); + assertNull("uninstallPackage(" + packageName + ") failed: " + result, result); } } - private void assertPackageUninstalled(String packageName) throws DeviceNotAvailableException { - final String command = "cmd package list packages -f " + packageName; + /** + * Starts a service that will register a broadcast receiver to receive + * {@code RESTRICT_BACKGROUND_CHANGE} intents. + *

+ * The service must run in a separate app because otherwise it would be killed every time + * {@link #runDeviceTests(String, String)} is executed. + */ + private void startBroadcastReceiverService() throws DeviceNotAvailableException { + runCommand("am startservice " + TEST_APP2_PKG + "/.MyService"); + } + + private void assertPackageUninstalled(String packageName) throws Exception { + final String command = "cmd package list packages " + packageName; final int max_tries = 5; for (int i = 1; i <= max_tries; i++) { final String result = runCommand(command); if (result.trim().isEmpty()) { return; } + // 'list packages' filters by substring, so we need to iterate with the results + // and check one by one, otherwise 'com.android.cts.net.hostside' could return + // 'com.android.cts.net.hostside.app2' + boolean found = false; + for (String line : result.split("[\\r\\n]+")) { + if (line.endsWith(packageName)) { + found = true; + break; + } + } + if (!found) { + return; + } i++; Log.v(TAG, "Package " + packageName + " not uninstalled yet (" + result + "); sleeping 1s before polling again"); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } + Thread.sleep(1000); } fail("Package '" + packageName + "' not uinstalled after " + max_tries + " seconds"); } @@ -165,6 +212,16 @@ public class HostsideNetworkTests extends DeviceTestCase implements IAbiReceiver "testGetRestrictBackgroundStatus_enabled"); } + private void assertRestrictBackgroundChangedReceivedOnce() throws DeviceNotAvailableException { + runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", + "testRestrictBackgroundChangedReceivedOnce"); + } + + private void assertRestrictBackgroundChangedReceivedTwice() throws DeviceNotAvailableException { + runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", + "testRestrictBackgroundChangedReceivedTwice"); + } + public void runDeviceTests(String packageName, String testClassName) throws DeviceNotAvailableException { runDeviceTests(packageName, testClassName, null); @@ -176,14 +233,11 @@ public class HostsideNetworkTests extends DeviceTestCase implements IAbiReceiver "android.support.test.runner.AndroidJUnitRunner", getDevice().getIDevice()); if (testClassName != null) { - // TODO: figure out why testRunner.setMethodName() / testRunner.setClassName() doesn't - // work - final StringBuilder runOptions = new StringBuilder("-e class ").append(testClassName); if (methodName != null) { - runOptions.append('#').append(methodName); + testRunner.setMethodName(testClassName, methodName); + } else { + testRunner.setClassName(testClassName); } - Log.i(TAG, "Setting runOptions() as " + runOptions); - testRunner.setRunOptions(runOptions.toString()); } final CollectingTestListener listener = new CollectingTestListener(); @@ -224,27 +278,31 @@ public class HostsideNetworkTests extends DeviceTestCase implements IAbiReceiver + output); } - private void addRestrictBackgroundWhitelist(int uid) throws DeviceNotAvailableException { + private void addRestrictBackgroundWhitelist(int uid) throws Exception { runCommand("cmd netpolicy add restrict-background-whitelist " + uid); assertRestrictBackgroundWhitelist(uid, true); } - private void removeRestrictBackgroundWhitelist(int uid) throws DeviceNotAvailableException { + private void removeRestrictBackgroundWhitelist(int uid) throws Exception { runCommand("cmd netpolicy remove restrict-background-whitelist " + uid); assertRestrictBackgroundWhitelist(uid, false); } - private void assertRestrictBackgroundWhitelist(int uid, boolean expected) - throws DeviceNotAvailableException { - final String output = runCommand("cmd netpolicy list restrict-background-whitelist "); - // TODO: use MoreAsserts - if (expected) { - assertTrue("Did not find uid '" + uid + "' on '" + output + "'", - output.contains(Integer.toString(uid))); - } else { - assertFalse("Found uid '" + uid + "' on '" + output + "'", - output.contains(Integer.toString(uid))); + private void assertRestrictBackgroundWhitelist(int uid, boolean expected) throws Exception { + final int max_tries = 5; + boolean actual = false; + for (int i = 1; i <= max_tries; i++) { + final String output = runCommand("cmd netpolicy list restrict-background-whitelist "); + actual = output.contains(Integer.toString(uid)); + if (expected == actual) { + return; + } + Log.v(TAG, "whitelist check for uid " + uid + " doesn't match yet (expected " + + expected + ", got " + actual + "); sleeping 1s before polling again"); + Thread.sleep(1000); } + fail("whitelist check for uid " + uid + " failed: expected " + + expected + ", got " + actual); } private void setRestrictBackground(boolean enabled) throws DeviceNotAvailableException { From 34caa7fc257ac04937a9a356b1190c2190b09a9d Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Thu, 4 Feb 2016 12:42:45 -0800 Subject: [PATCH 0204/1109] Renamed and cloned HostsideNetworkTests.java This is a no-op change that will make it easier to split the HostsideNetworkTestCase.java logic into multiple files. In this change, HostsideNetworkTests.java was renamed to HostsideNetworkTestCase.java and copied as-is to HostsideRestrictBackgroundNetworkTests.java; the next change will split the logic in between these class so they can be properly git-diffed. In fact, the only difference between then is the class declarations: diff HostsideNetworkTestCase.java HostsideRestrictBackgroundNetworkTests.java 39c39 < abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiReceiver, --- > public class HostsideRestrictBackgroundNetworkTests extends DeviceTestCase implements IAbiReceiver, BUG: 26685616 Change-Id: I87dadec528eaeff776d55d3382f356066496429a --- ...ests.java => HostsideNetworkTestCase.java} | 5 +- ...ostsideRestrictBackgroundNetworkTests.java | 324 ++++++++++++++++++ 2 files changed, 327 insertions(+), 2 deletions(-) rename tests/cts/hostside/src/com/android/cts/net/{HostsideNetworkTests.java => HostsideNetworkTestCase.java} (98%) create mode 100644 tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java similarity index 98% rename from tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTests.java rename to tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java index bedfad61b3..7ae842d0ad 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 The Android Open Source Project + * Copyright (C) 2016 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. @@ -36,7 +36,8 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class HostsideNetworkTests extends DeviceTestCase implements IAbiReceiver, IBuildReceiver { +abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiReceiver, + IBuildReceiver { private static final boolean DEBUG = false; private static final String TAG = "HostsideNetworkTests"; private static final String TEST_PKG = "com.android.cts.net.hostside"; diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java new file mode 100644 index 0000000000..038cd132ec --- /dev/null +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java @@ -0,0 +1,324 @@ +/* + * Copyright (C) 2016 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.cts.net; + +import com.android.cts.migration.MigrationHelper; +import com.android.ddmlib.Log; +import com.android.ddmlib.testrunner.RemoteAndroidTestRunner; +import com.android.ddmlib.testrunner.TestIdentifier; +import com.android.ddmlib.testrunner.TestResult; +import com.android.ddmlib.testrunner.TestResult.TestStatus; +import com.android.ddmlib.testrunner.TestRunResult; +import com.android.tradefed.build.IBuildInfo; +import com.android.tradefed.device.DeviceNotAvailableException; +import com.android.tradefed.result.CollectingTestListener; +import com.android.tradefed.testtype.DeviceTestCase; +import com.android.tradefed.testtype.IAbi; +import com.android.tradefed.testtype.IAbiReceiver; +import com.android.tradefed.testtype.IBuildReceiver; + +import java.io.FileNotFoundException; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class HostsideRestrictBackgroundNetworkTests extends DeviceTestCase implements IAbiReceiver, + IBuildReceiver { + private static final boolean DEBUG = false; + private static final String TAG = "HostsideNetworkTests"; + private static final String TEST_PKG = "com.android.cts.net.hostside"; + private static final String TEST_APK = "CtsHostsideNetworkTestsApp.apk"; + + private static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2"; + private static final String TEST_APP2_APK = "CtsHostsideNetworkTestsApp2.apk"; + + private IAbi mAbi; + private IBuildInfo mCtsBuild; + + @Override + public void setAbi(IAbi abi) { + mAbi = abi; + } + + @Override + public void setBuild(IBuildInfo buildInfo) { + mCtsBuild = buildInfo; + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + + assertNotNull(mAbi); + assertNotNull(mCtsBuild); + + setRestrictBackground(false); + + uninstallPackage(TEST_PKG, false); + installPackage(TEST_APK); + // TODO: split this class into HostsideVpnTests and HostsideConnectivityManagerTests so + // the former don't need to unnecessarily install app2. + uninstallPackage(TEST_APP2_PKG, false); + installPackage(TEST_APP2_APK); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + + uninstallPackage(TEST_PKG, true); + uninstallPackage(TEST_APP2_PKG, true); + + setRestrictBackground(false); + } + + public void testVpn() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest"); + } + + public void testConnectivityManager_getRestrictBackgroundStatus_disabled() throws Exception { + startBroadcastReceiverService(); + final int uid = getUid(TEST_PKG); + + removeRestrictBackgroundWhitelist(uid); + assertRestrictBackgroundStatusDisabled(); + assertRestrictBackgroundChangedReceivedOnce(); + + // Sanity check: make sure status is always disabled, never whitelisted + addRestrictBackgroundWhitelist(uid); + assertRestrictBackgroundStatusDisabled(); + assertRestrictBackgroundChangedReceivedTwice(); + } + + public void testConnectivityManager_getRestrictBackgroundStatus_whitelisted() throws Exception { + startBroadcastReceiverService(); + final int uid = getUid(TEST_PKG); + + setRestrictBackground(true); + assertRestrictBackgroundChangedReceivedOnce(); + + addRestrictBackgroundWhitelist(uid); + assertRestrictBackgroundStatusWhitelisted(); + assertRestrictBackgroundChangedReceivedTwice(); + } + + public void testConnectivityManager_getRestrictBackgroundStatus_enabled() throws Exception { + startBroadcastReceiverService(); + final int uid = getUid(TEST_PKG); + + setRestrictBackground(true); + assertRestrictBackgroundChangedReceivedOnce(); + + removeRestrictBackgroundWhitelist(uid); + assertRestrictBackgroundStatusEnabled(); + assertRestrictBackgroundChangedReceivedTwice(); + } + + public void testConnectivityManager_getRestrictBackgroundStatus_uninstall() throws Exception { + final int uid = getUid(TEST_PKG); + + addRestrictBackgroundWhitelist(uid); + assertRestrictBackgroundWhitelist(uid, true); + + uninstallPackage(TEST_PKG, true); + assertPackageUninstalled(TEST_PKG); + assertRestrictBackgroundWhitelist(uid, false); + + installPackage(TEST_APK); + final int newUid = getUid(TEST_PKG); + assertRestrictBackgroundWhitelist(uid, false); + assertRestrictBackgroundWhitelist(newUid, false); + } + + private void installPackage(String apk) throws DeviceNotAvailableException, + FileNotFoundException { + assertNull(getDevice().installPackage( + MigrationHelper.getTestFile(mCtsBuild, apk), false)); + } + + private void uninstallPackage(String packageName, boolean shouldSucceed) + throws DeviceNotAvailableException { + final String result = getDevice().uninstallPackage(packageName); + if (shouldSucceed) { + assertNull("uninstallPackage(" + packageName + ") failed: " + result, result); + } + } + + /** + * Starts a service that will register a broadcast receiver to receive + * {@code RESTRICT_BACKGROUND_CHANGE} intents. + *

+ * The service must run in a separate app because otherwise it would be killed every time + * {@link #runDeviceTests(String, String)} is executed. + */ + private void startBroadcastReceiverService() throws DeviceNotAvailableException { + runCommand("am startservice " + TEST_APP2_PKG + "/.MyService"); + } + + private void assertPackageUninstalled(String packageName) throws Exception { + final String command = "cmd package list packages " + packageName; + final int max_tries = 5; + for (int i = 1; i <= max_tries; i++) { + final String result = runCommand(command); + if (result.trim().isEmpty()) { + return; + } + // 'list packages' filters by substring, so we need to iterate with the results + // and check one by one, otherwise 'com.android.cts.net.hostside' could return + // 'com.android.cts.net.hostside.app2' + boolean found = false; + for (String line : result.split("[\\r\\n]+")) { + if (line.endsWith(packageName)) { + found = true; + break; + } + } + if (!found) { + return; + } + i++; + Log.v(TAG, "Package " + packageName + " not uninstalled yet (" + result + + "); sleeping 1s before polling again"); + Thread.sleep(1000); + } + fail("Package '" + packageName + "' not uinstalled after " + max_tries + " seconds"); + } + + private void assertRestrictBackgroundStatusDisabled() throws DeviceNotAvailableException { + runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", + "testGetRestrictBackgroundStatus_disabled"); + } + + private void assertRestrictBackgroundStatusWhitelisted() throws DeviceNotAvailableException { + runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", + "testGetRestrictBackgroundStatus_whitelisted"); + } + + private void assertRestrictBackgroundStatusEnabled() throws DeviceNotAvailableException { + runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", + "testGetRestrictBackgroundStatus_enabled"); + } + + private void assertRestrictBackgroundChangedReceivedOnce() throws DeviceNotAvailableException { + runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", + "testRestrictBackgroundChangedReceivedOnce"); + } + + private void assertRestrictBackgroundChangedReceivedTwice() throws DeviceNotAvailableException { + runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", + "testRestrictBackgroundChangedReceivedTwice"); + } + + public void runDeviceTests(String packageName, String testClassName) + throws DeviceNotAvailableException { + runDeviceTests(packageName, testClassName, null); + } + + public void runDeviceTests(String packageName, String testClassName, String methodName) + throws DeviceNotAvailableException { + RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(packageName, + "android.support.test.runner.AndroidJUnitRunner", getDevice().getIDevice()); + + if (testClassName != null) { + if (methodName != null) { + testRunner.setMethodName(testClassName, methodName); + } else { + testRunner.setClassName(testClassName); + } + } + + final CollectingTestListener listener = new CollectingTestListener(); + getDevice().runInstrumentationTests(testRunner, listener); + + final TestRunResult result = listener.getCurrentRunResults(); + if (result.isRunFailure()) { + throw new AssertionError("Failed to successfully run device tests for " + + result.getName() + ": " + result.getRunFailureMessage()); + } + + if (result.hasFailedTests()) { + // build a meaningful error message + StringBuilder errorBuilder = new StringBuilder("on-device tests failed:\n"); + for (Map.Entry resultEntry : + result.getTestResults().entrySet()) { + if (!resultEntry.getValue().getStatus().equals(TestStatus.PASSED)) { + errorBuilder.append(resultEntry.getKey().toString()); + errorBuilder.append(":\n"); + errorBuilder.append(resultEntry.getValue().getStackTrace()); + } + } + throw new AssertionError(errorBuilder.toString()); + } + } + + private static final Pattern UID_PATTERN = + Pattern.compile(".*userId=([0-9]+)$", Pattern.MULTILINE); + + private int getUid(String packageName) throws DeviceNotAvailableException { + final String output = runCommand("dumpsys package " + packageName); + final Matcher matcher = UID_PATTERN.matcher(output); + while (matcher.find()) { + final String match = matcher.group(1); + return Integer.parseInt(match); + } + throw new RuntimeException("Did not find regexp '" + UID_PATTERN + "' on adb output\n" + + output); + } + + private void addRestrictBackgroundWhitelist(int uid) throws Exception { + runCommand("cmd netpolicy add restrict-background-whitelist " + uid); + assertRestrictBackgroundWhitelist(uid, true); + } + + private void removeRestrictBackgroundWhitelist(int uid) throws Exception { + runCommand("cmd netpolicy remove restrict-background-whitelist " + uid); + assertRestrictBackgroundWhitelist(uid, false); + } + + private void assertRestrictBackgroundWhitelist(int uid, boolean expected) throws Exception { + final int max_tries = 5; + boolean actual = false; + for (int i = 1; i <= max_tries; i++) { + final String output = runCommand("cmd netpolicy list restrict-background-whitelist "); + actual = output.contains(Integer.toString(uid)); + if (expected == actual) { + return; + } + Log.v(TAG, "whitelist check for uid " + uid + " doesn't match yet (expected " + + expected + ", got " + actual + "); sleeping 1s before polling again"); + Thread.sleep(1000); + } + fail("whitelist check for uid " + uid + " failed: expected " + + expected + ", got " + actual); + } + + private void setRestrictBackground(boolean enabled) throws DeviceNotAvailableException { + runCommand("cmd netpolicy set restrict-background " + enabled); + final String output = runCommand("cmd netpolicy get restrict-background ").trim(); + final String expectedSuffix = enabled ? "enabled" : "disabled"; + // TODO: use MoreAsserts? + assertTrue("output '" + output + "' should end with '" + expectedSuffix + "'", + output.endsWith(expectedSuffix)); + } + + private String runCommand(String command) throws DeviceNotAvailableException { + Log.d(TAG, "Command: '" + command + "'"); + final String output = getDevice().executeShellCommand(command); + if (DEBUG) Log.v(TAG, "Output: " + output.trim()); + return output; + } +} From 4fc69f6c25f68bfca83256c3b0a367213a251f5a Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Thu, 4 Feb 2016 12:46:16 -0800 Subject: [PATCH 0205/1109] Split hostside network tests in multiple classes. Initially HostsideNetworkTests.java was used to just launch VpnTest, but it became more complex with the inclusion of ConnectivityManagerTest, which required hostside logic. By splitting these tests not only the VPN tests will run faster (since it doesn't need the setup/clean from ConnectivityManager), but the ConnectivityManager tests will be cleaner (since it can have more logic on setup and teardown). BUG: 26685616 Change-Id: Ie29c4a3e83956b217d90b84c9b4541690cde0344 --- .../cts/net/HostsideNetworkTestCase.java | 170 ++------------- ...ostsideRestrictBackgroundNetworkTests.java | 196 ++---------------- .../com/android/cts/net/HostsideVpnTests.java | 24 +++ 3 files changed, 55 insertions(+), 335 deletions(-) create mode 100644 tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java index 7ae842d0ad..08fb887932 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java @@ -38,13 +38,10 @@ import java.util.regex.Pattern; abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiReceiver, IBuildReceiver { - private static final boolean DEBUG = false; - private static final String TAG = "HostsideNetworkTests"; - private static final String TEST_PKG = "com.android.cts.net.hostside"; - private static final String TEST_APK = "CtsHostsideNetworkTestsApp.apk"; - - private static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2"; - private static final String TEST_APP2_APK = "CtsHostsideNetworkTestsApp2.apk"; + protected static final boolean DEBUG = false; + protected static final String TAG = "HostsideNetworkTests"; + protected static final String TEST_PKG = "com.android.cts.net.hostside"; + protected static final String TEST_APK = "CtsHostsideNetworkTestsApp.apk"; private IAbi mAbi; private IBuildInfo mCtsBuild; @@ -66,14 +63,8 @@ abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiRec assertNotNull(mAbi); assertNotNull(mCtsBuild); - setRestrictBackground(false); - uninstallPackage(TEST_PKG, false); installPackage(TEST_APK); - // TODO: split this class into HostsideVpnTests and HostsideConnectivityManagerTests so - // the former don't need to unnecessarily install app2. - uninstallPackage(TEST_APP2_PKG, false); - installPackage(TEST_APP2_APK); } @Override @@ -81,76 +72,14 @@ abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiRec super.tearDown(); uninstallPackage(TEST_PKG, true); - uninstallPackage(TEST_APP2_PKG, true); - - setRestrictBackground(false); } - public void testVpn() throws Exception { - runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest"); + protected void installPackage(String apk) throws FileNotFoundException, + DeviceNotAvailableException { + assertNull(getDevice().installPackage(MigrationHelper.getTestFile(mCtsBuild, apk), false)); } - public void testConnectivityManager_getRestrictBackgroundStatus_disabled() throws Exception { - startBroadcastReceiverService(); - final int uid = getUid(TEST_PKG); - - removeRestrictBackgroundWhitelist(uid); - assertRestrictBackgroundStatusDisabled(); - assertRestrictBackgroundChangedReceivedOnce(); - - // Sanity check: make sure status is always disabled, never whitelisted - addRestrictBackgroundWhitelist(uid); - assertRestrictBackgroundStatusDisabled(); - assertRestrictBackgroundChangedReceivedTwice(); - } - - public void testConnectivityManager_getRestrictBackgroundStatus_whitelisted() throws Exception { - startBroadcastReceiverService(); - final int uid = getUid(TEST_PKG); - - setRestrictBackground(true); - assertRestrictBackgroundChangedReceivedOnce(); - - addRestrictBackgroundWhitelist(uid); - assertRestrictBackgroundStatusWhitelisted(); - assertRestrictBackgroundChangedReceivedTwice(); - } - - public void testConnectivityManager_getRestrictBackgroundStatus_enabled() throws Exception { - startBroadcastReceiverService(); - final int uid = getUid(TEST_PKG); - - setRestrictBackground(true); - assertRestrictBackgroundChangedReceivedOnce(); - - removeRestrictBackgroundWhitelist(uid); - assertRestrictBackgroundStatusEnabled(); - assertRestrictBackgroundChangedReceivedTwice(); - } - - public void testConnectivityManager_getRestrictBackgroundStatus_uninstall() throws Exception { - final int uid = getUid(TEST_PKG); - - addRestrictBackgroundWhitelist(uid); - assertRestrictBackgroundWhitelist(uid, true); - - uninstallPackage(TEST_PKG, true); - assertPackageUninstalled(TEST_PKG); - assertRestrictBackgroundWhitelist(uid, false); - - installPackage(TEST_APK); - final int newUid = getUid(TEST_PKG); - assertRestrictBackgroundWhitelist(uid, false); - assertRestrictBackgroundWhitelist(newUid, false); - } - - private void installPackage(String apk) throws DeviceNotAvailableException, - FileNotFoundException { - assertNull(getDevice().installPackage( - MigrationHelper.getTestFile(mCtsBuild, apk), false)); - } - - private void uninstallPackage(String packageName, boolean shouldSucceed) + protected void uninstallPackage(String packageName, boolean shouldSucceed) throws DeviceNotAvailableException { final String result = getDevice().uninstallPackage(packageName); if (shouldSucceed) { @@ -158,18 +87,8 @@ abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiRec } } - /** - * Starts a service that will register a broadcast receiver to receive - * {@code RESTRICT_BACKGROUND_CHANGE} intents. - *

- * The service must run in a separate app because otherwise it would be killed every time - * {@link #runDeviceTests(String, String)} is executed. - */ - private void startBroadcastReceiverService() throws DeviceNotAvailableException { - runCommand("am startservice " + TEST_APP2_PKG + "/.MyService"); - } - - private void assertPackageUninstalled(String packageName) throws Exception { + protected void assertPackageUninstalled(String packageName) throws DeviceNotAvailableException, + InterruptedException { final String command = "cmd package list packages " + packageName; final int max_tries = 5; for (int i = 1; i <= max_tries; i++) { @@ -198,37 +117,12 @@ abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiRec fail("Package '" + packageName + "' not uinstalled after " + max_tries + " seconds"); } - private void assertRestrictBackgroundStatusDisabled() throws DeviceNotAvailableException { - runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", - "testGetRestrictBackgroundStatus_disabled"); - } - - private void assertRestrictBackgroundStatusWhitelisted() throws DeviceNotAvailableException { - runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", - "testGetRestrictBackgroundStatus_whitelisted"); - } - - private void assertRestrictBackgroundStatusEnabled() throws DeviceNotAvailableException { - runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", - "testGetRestrictBackgroundStatus_enabled"); - } - - private void assertRestrictBackgroundChangedReceivedOnce() throws DeviceNotAvailableException { - runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", - "testRestrictBackgroundChangedReceivedOnce"); - } - - private void assertRestrictBackgroundChangedReceivedTwice() throws DeviceNotAvailableException { - runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", - "testRestrictBackgroundChangedReceivedTwice"); - } - - public void runDeviceTests(String packageName, String testClassName) + protected void runDeviceTests(String packageName, String testClassName) throws DeviceNotAvailableException { runDeviceTests(packageName, testClassName, null); } - public void runDeviceTests(String packageName, String testClassName, String methodName) + protected void runDeviceTests(String packageName, String testClassName, String methodName) throws DeviceNotAvailableException { RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(packageName, "android.support.test.runner.AndroidJUnitRunner", getDevice().getIDevice()); @@ -268,7 +162,7 @@ abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiRec private static final Pattern UID_PATTERN = Pattern.compile(".*userId=([0-9]+)$", Pattern.MULTILINE); - private int getUid(String packageName) throws DeviceNotAvailableException { + protected int getUid(String packageName) throws DeviceNotAvailableException { final String output = runCommand("dumpsys package " + packageName); final Matcher matcher = UID_PATTERN.matcher(output); while (matcher.find()) { @@ -279,43 +173,7 @@ abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiRec + output); } - private void addRestrictBackgroundWhitelist(int uid) throws Exception { - runCommand("cmd netpolicy add restrict-background-whitelist " + uid); - assertRestrictBackgroundWhitelist(uid, true); - } - - private void removeRestrictBackgroundWhitelist(int uid) throws Exception { - runCommand("cmd netpolicy remove restrict-background-whitelist " + uid); - assertRestrictBackgroundWhitelist(uid, false); - } - - private void assertRestrictBackgroundWhitelist(int uid, boolean expected) throws Exception { - final int max_tries = 5; - boolean actual = false; - for (int i = 1; i <= max_tries; i++) { - final String output = runCommand("cmd netpolicy list restrict-background-whitelist "); - actual = output.contains(Integer.toString(uid)); - if (expected == actual) { - return; - } - Log.v(TAG, "whitelist check for uid " + uid + " doesn't match yet (expected " - + expected + ", got " + actual + "); sleeping 1s before polling again"); - Thread.sleep(1000); - } - fail("whitelist check for uid " + uid + " failed: expected " - + expected + ", got " + actual); - } - - private void setRestrictBackground(boolean enabled) throws DeviceNotAvailableException { - runCommand("cmd netpolicy set restrict-background " + enabled); - final String output = runCommand("cmd netpolicy get restrict-background ").trim(); - final String expectedSuffix = enabled ? "enabled" : "disabled"; - // TODO: use MoreAsserts? - assertTrue("output '" + output + "' should end with '" + expectedSuffix + "'", - output.endsWith(expectedSuffix)); - } - - private String runCommand(String command) throws DeviceNotAvailableException { + protected String runCommand(String command) throws DeviceNotAvailableException { Log.d(TAG, "Command: '" + command + "'"); final String output = getDevice().executeShellCommand(command); if (DEBUG) Log.v(TAG, "Output: " + output.trim()); diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java index 038cd132ec..9f0bfb8415 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java @@ -16,148 +16,78 @@ package com.android.cts.net; -import com.android.cts.migration.MigrationHelper; import com.android.ddmlib.Log; -import com.android.ddmlib.testrunner.RemoteAndroidTestRunner; -import com.android.ddmlib.testrunner.TestIdentifier; -import com.android.ddmlib.testrunner.TestResult; -import com.android.ddmlib.testrunner.TestResult.TestStatus; -import com.android.ddmlib.testrunner.TestRunResult; -import com.android.tradefed.build.IBuildInfo; import com.android.tradefed.device.DeviceNotAvailableException; -import com.android.tradefed.result.CollectingTestListener; -import com.android.tradefed.testtype.DeviceTestCase; -import com.android.tradefed.testtype.IAbi; -import com.android.tradefed.testtype.IAbiReceiver; -import com.android.tradefed.testtype.IBuildReceiver; - -import java.io.FileNotFoundException; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class HostsideRestrictBackgroundNetworkTests extends DeviceTestCase implements IAbiReceiver, - IBuildReceiver { - private static final boolean DEBUG = false; - private static final String TAG = "HostsideNetworkTests"; - private static final String TEST_PKG = "com.android.cts.net.hostside"; - private static final String TEST_APK = "CtsHostsideNetworkTestsApp.apk"; +public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestCase { private static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2"; private static final String TEST_APP2_APK = "CtsHostsideNetworkTestsApp2.apk"; - private IAbi mAbi; - private IBuildInfo mCtsBuild; - - @Override - public void setAbi(IAbi abi) { - mAbi = abi; - } - - @Override - public void setBuild(IBuildInfo buildInfo) { - mCtsBuild = buildInfo; - } + private int mUid; @Override protected void setUp() throws Exception { super.setUp(); - assertNotNull(mAbi); - assertNotNull(mCtsBuild); - setRestrictBackground(false); - - uninstallPackage(TEST_PKG, false); - installPackage(TEST_APK); - // TODO: split this class into HostsideVpnTests and HostsideConnectivityManagerTests so - // the former don't need to unnecessarily install app2. uninstallPackage(TEST_APP2_PKG, false); installPackage(TEST_APP2_APK); + + startBroadcastReceiverService(); + mUid = getUid(TEST_PKG); } @Override protected void tearDown() throws Exception { super.tearDown(); - uninstallPackage(TEST_PKG, true); uninstallPackage(TEST_APP2_PKG, true); - setRestrictBackground(false); } - public void testVpn() throws Exception { - runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest"); - } - - public void testConnectivityManager_getRestrictBackgroundStatus_disabled() throws Exception { - startBroadcastReceiverService(); - final int uid = getUid(TEST_PKG); - - removeRestrictBackgroundWhitelist(uid); + public void testGetRestrictBackgroundStatus_disabled() throws Exception { + removeRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundStatusDisabled(); assertRestrictBackgroundChangedReceivedOnce(); // Sanity check: make sure status is always disabled, never whitelisted - addRestrictBackgroundWhitelist(uid); + addRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundStatusDisabled(); assertRestrictBackgroundChangedReceivedTwice(); } - public void testConnectivityManager_getRestrictBackgroundStatus_whitelisted() throws Exception { - startBroadcastReceiverService(); - final int uid = getUid(TEST_PKG); - + public void testGetRestrictBackgroundStatus_whitelisted() throws Exception { setRestrictBackground(true); assertRestrictBackgroundChangedReceivedOnce(); - addRestrictBackgroundWhitelist(uid); + addRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundStatusWhitelisted(); assertRestrictBackgroundChangedReceivedTwice(); } - public void testConnectivityManager_getRestrictBackgroundStatus_enabled() throws Exception { - startBroadcastReceiverService(); - final int uid = getUid(TEST_PKG); - + public void testGetRestrictBackgroundStatus_enabled() throws Exception { setRestrictBackground(true); assertRestrictBackgroundChangedReceivedOnce(); - removeRestrictBackgroundWhitelist(uid); + removeRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundStatusEnabled(); assertRestrictBackgroundChangedReceivedTwice(); } - public void testConnectivityManager_getRestrictBackgroundStatus_uninstall() throws Exception { - final int uid = getUid(TEST_PKG); - - addRestrictBackgroundWhitelist(uid); - assertRestrictBackgroundWhitelist(uid, true); + public void testGetRestrictBackgroundStatus_uninstall() throws Exception { + addRestrictBackgroundWhitelist(mUid); + assertRestrictBackgroundWhitelist(mUid, true); uninstallPackage(TEST_PKG, true); assertPackageUninstalled(TEST_PKG); - assertRestrictBackgroundWhitelist(uid, false); + assertRestrictBackgroundWhitelist(mUid, false); installPackage(TEST_APK); final int newUid = getUid(TEST_PKG); - assertRestrictBackgroundWhitelist(uid, false); + assertRestrictBackgroundWhitelist(mUid, false); assertRestrictBackgroundWhitelist(newUid, false); } - private void installPackage(String apk) throws DeviceNotAvailableException, - FileNotFoundException { - assertNull(getDevice().installPackage( - MigrationHelper.getTestFile(mCtsBuild, apk), false)); - } - - private void uninstallPackage(String packageName, boolean shouldSucceed) - throws DeviceNotAvailableException { - final String result = getDevice().uninstallPackage(packageName); - if (shouldSucceed) { - assertNull("uninstallPackage(" + packageName + ") failed: " + result, result); - } - } - /** * Starts a service that will register a broadcast receiver to receive * {@code RESTRICT_BACKGROUND_CHANGE} intents. @@ -169,35 +99,6 @@ public class HostsideRestrictBackgroundNetworkTests extends DeviceTestCase imple runCommand("am startservice " + TEST_APP2_PKG + "/.MyService"); } - private void assertPackageUninstalled(String packageName) throws Exception { - final String command = "cmd package list packages " + packageName; - final int max_tries = 5; - for (int i = 1; i <= max_tries; i++) { - final String result = runCommand(command); - if (result.trim().isEmpty()) { - return; - } - // 'list packages' filters by substring, so we need to iterate with the results - // and check one by one, otherwise 'com.android.cts.net.hostside' could return - // 'com.android.cts.net.hostside.app2' - boolean found = false; - for (String line : result.split("[\\r\\n]+")) { - if (line.endsWith(packageName)) { - found = true; - break; - } - } - if (!found) { - return; - } - i++; - Log.v(TAG, "Package " + packageName + " not uninstalled yet (" + result - + "); sleeping 1s before polling again"); - Thread.sleep(1000); - } - fail("Package '" + packageName + "' not uinstalled after " + max_tries + " seconds"); - } - private void assertRestrictBackgroundStatusDisabled() throws DeviceNotAvailableException { runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", "testGetRestrictBackgroundStatus_disabled"); @@ -223,62 +124,6 @@ public class HostsideRestrictBackgroundNetworkTests extends DeviceTestCase imple "testRestrictBackgroundChangedReceivedTwice"); } - public void runDeviceTests(String packageName, String testClassName) - throws DeviceNotAvailableException { - runDeviceTests(packageName, testClassName, null); - } - - public void runDeviceTests(String packageName, String testClassName, String methodName) - throws DeviceNotAvailableException { - RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(packageName, - "android.support.test.runner.AndroidJUnitRunner", getDevice().getIDevice()); - - if (testClassName != null) { - if (methodName != null) { - testRunner.setMethodName(testClassName, methodName); - } else { - testRunner.setClassName(testClassName); - } - } - - final CollectingTestListener listener = new CollectingTestListener(); - getDevice().runInstrumentationTests(testRunner, listener); - - final TestRunResult result = listener.getCurrentRunResults(); - if (result.isRunFailure()) { - throw new AssertionError("Failed to successfully run device tests for " - + result.getName() + ": " + result.getRunFailureMessage()); - } - - if (result.hasFailedTests()) { - // build a meaningful error message - StringBuilder errorBuilder = new StringBuilder("on-device tests failed:\n"); - for (Map.Entry resultEntry : - result.getTestResults().entrySet()) { - if (!resultEntry.getValue().getStatus().equals(TestStatus.PASSED)) { - errorBuilder.append(resultEntry.getKey().toString()); - errorBuilder.append(":\n"); - errorBuilder.append(resultEntry.getValue().getStackTrace()); - } - } - throw new AssertionError(errorBuilder.toString()); - } - } - - private static final Pattern UID_PATTERN = - Pattern.compile(".*userId=([0-9]+)$", Pattern.MULTILINE); - - private int getUid(String packageName) throws DeviceNotAvailableException { - final String output = runCommand("dumpsys package " + packageName); - final Matcher matcher = UID_PATTERN.matcher(output); - while (matcher.find()) { - final String match = matcher.group(1); - return Integer.parseInt(match); - } - throw new RuntimeException("Did not find regexp '" + UID_PATTERN + "' on adb output\n" - + output); - } - private void addRestrictBackgroundWhitelist(int uid) throws Exception { runCommand("cmd netpolicy add restrict-background-whitelist " + uid); assertRestrictBackgroundWhitelist(uid, true); @@ -314,11 +159,4 @@ public class HostsideRestrictBackgroundNetworkTests extends DeviceTestCase imple assertTrue("output '" + output + "' should end with '" + expectedSuffix + "'", output.endsWith(expectedSuffix)); } - - private String runCommand(String command) throws DeviceNotAvailableException { - Log.d(TAG, "Command: '" + command + "'"); - final String output = getDevice().executeShellCommand(command); - if (DEBUG) Log.v(TAG, "Output: " + output.trim()); - return output; - } } diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java new file mode 100644 index 0000000000..dc965c50f8 --- /dev/null +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2016 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.cts.net; + +public class HostsideVpnTests extends HostsideNetworkTestCase { + + public void testVpn() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest"); + } +} From c50a6c7d4be14764ed08cd467b6b6053d2d4c161 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Mon, 8 Feb 2016 12:16:51 -0800 Subject: [PATCH 0206/1109] Improve CTS tests to really check background network restrictions. BUG: 26685616 Change-Id: If2b1649435b0a4e5b8c383eb3196807a03359d70 --- .../net/hostside/ConnectivityManagerTest.java | 61 +++++++++++++++---- ...ostsideRestrictBackgroundNetworkTests.java | 28 ++++++++- 2 files changed, 76 insertions(+), 13 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java index 300e39d55e..34c8d28f7f 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java @@ -25,9 +25,14 @@ import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkInfo; import android.test.InstrumentationTestCase; import android.util.Log; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + /** * Tests for the {@link ConnectivityManager} API. * @@ -38,27 +43,36 @@ import android.util.Log; public class ConnectivityManagerTest extends InstrumentationTestCase { private static final String TAG = "ConnectivityManagerTest"; - static final String MANIFEST_RECEIVER = "ManifestReceiver"; - static final String DYNAMIC_RECEIVER = "DynamicReceiver"; + private static final String MANIFEST_RECEIVER = "ManifestReceiver"; + private static final String DYNAMIC_RECEIVER = "DynamicReceiver"; - private ConnectivityManager mCM; + private static final String STATUS_NETWORK_UNAVAILABLE_PREFIX = "NetworkUnavailable:"; + private static final String STATUS_NETWORK_AVAILABLE_PREFIX = "NetworkAvailable:"; + + private ConnectivityManager mCm; + private int mUid; @Override public void setUp() throws Exception { super.setUp(); - mCM = (ConnectivityManager) getInstrumentation().getContext().getSystemService( - Activity.CONNECTIVITY_SERVICE); + final Context context = getInstrumentation().getContext(); + mCm = (ConnectivityManager) context.getSystemService(Activity.CONNECTIVITY_SERVICE); + mUid = context.getPackageManager() + .getPackageInfo(context.getPackageName(), 0).applicationInfo.uid; + final boolean metered = mCm.isActiveNetworkMetered(); + Log.i(TAG, getName() + ": uid=" + mUid + ", metered=" + metered); + assertTrue("Active network is not metered", metered); } - public void testGetRestrictBackgroundStatus_disabled() { + public void testGetRestrictBackgroundStatus_disabled() throws Exception { assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); } - public void testGetRestrictBackgroundStatus_whitelisted() { + public void testGetRestrictBackgroundStatus_whitelisted() throws Exception { assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_WHITELISTED); } - public void testGetRestrictBackgroundStatus_enabled() { + public void testGetRestrictBackgroundStatus_enabled() throws Exception { assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); } @@ -102,11 +116,34 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { return prefs.getInt(action, 0); } - private void assertRestrictBackgroundStatus(int expectedStatus) { - final String expected = toString(expectedStatus); + private void assertRestrictBackgroundStatus(int expectedApiStatus) throws InterruptedException { + // First asserts the API returns the proper value... + final String expected = toString(expectedApiStatus); Log.d(TAG, getName() + " (expecting " + expected + ")"); - final int actualStatus = mCM.getRestrictBackgroundStatus(); - assertEquals("wrong status", expected, toString(actualStatus)); + final int apiStatus = mCm.getRestrictBackgroundStatus(); + String actualApiStatus = toString(apiStatus); + assertEquals("wrong status", expected, actualApiStatus); + + //...then use a background thread to verify the actual network status. + final LinkedBlockingQueue result = new LinkedBlockingQueue<>(1); + new Thread(new Runnable() { + @Override + public void run() { + Log.d(TAG, "Running on thread " + Thread.currentThread().getName()); + final Network network = mCm.getActiveNetwork(); + final NetworkInfo networkInfo = mCm.getActiveNetworkInfo(); + Log.d(TAG, "activeNetwork: " + network + " activeNetworkInfo: " + networkInfo); + final String prefix = network == null ? + STATUS_NETWORK_UNAVAILABLE_PREFIX : STATUS_NETWORK_AVAILABLE_PREFIX; + result.offer(prefix + networkInfo); + } + }, "CheckNetworkThread").start(); + final String actualNetworkStatus = result.poll(10, TimeUnit.SECONDS); + assertNotNull("timeout waiting for background thread", actualNetworkStatus); + final String expectedPrefix = apiStatus == RESTRICT_BACKGROUND_STATUS_ENABLED ? + STATUS_NETWORK_UNAVAILABLE_PREFIX : STATUS_NETWORK_AVAILABLE_PREFIX; + assertTrue("Wrong network status for API status " + actualApiStatus + ": " + + actualNetworkStatus, actualNetworkStatus.startsWith(expectedPrefix)); } private String toString(int status) { diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java index 9f0bfb8415..2b0b1c16ba 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java @@ -18,23 +18,29 @@ package com.android.cts.net; import com.android.ddmlib.Log; import com.android.tradefed.device.DeviceNotAvailableException; +import com.android.tradefed.device.WifiHelper; public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestCase { private static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2"; private static final String TEST_APP2_APK = "CtsHostsideNetworkTestsApp2.apk"; private int mUid; + private WifiHelper mWifiHelper; @Override protected void setUp() throws Exception { super.setUp(); + mUid = getUid(TEST_PKG); + mWifiHelper = new WifiHelper(getDevice()); + + setWifiMeteredStatus(true); setRestrictBackground(false); + uninstallPackage(TEST_APP2_PKG, false); installPackage(TEST_APP2_APK); startBroadcastReceiverService(); - mUid = getUid(TEST_PKG); } @Override @@ -43,6 +49,7 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC uninstallPackage(TEST_APP2_PKG, true); setRestrictBackground(false); + setWifiMeteredStatus(false); } public void testGetRestrictBackgroundStatus_disabled() throws Exception { @@ -151,6 +158,25 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC + expected + ", got " + actual); } + private void setWifiMeteredStatus(boolean metered) throws DeviceNotAvailableException { + mWifiHelper.enableWifi(); + // TODO: if it's not guaranteed the device has wi-fi, we need to change the tests + // to make the actual verification of restrictions optional. + final String netId = mWifiHelper.getSSID(); + assertNotNull("null SSID", netId); + assertFalse("empty SSID", netId.trim().isEmpty()); + + Log.i(TAG, "Setting wi-fi network " + netId + " metered status to " + metered); + final String setCommand = "cmd netpolicy set metered-network " + netId + " "+ metered; + final String result = runCommand(setCommand); + assertTrue("Command '" + setCommand + "' failed: " + result, result.trim().isEmpty()); + + // Sanity check. + final String newStatus = runCommand("cmd netpolicy get metered-network " + netId); + assertEquals("Metered status of wi-fi network " + netId + " not set properly", + newStatus.trim(), Boolean.toString(metered)); + } + private void setRestrictBackground(boolean enabled) throws DeviceNotAvailableException { runCommand("cmd netpolicy set restrict-background " + enabled); final String output = runCommand("cmd netpolicy get restrict-background ").trim(); From 38300a564a2b29c72781e421ef3d44a7f6d28291 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Wed, 10 Feb 2016 09:50:24 -0800 Subject: [PATCH 0207/1109] Refactored tests to make a real network connection. The current approach assumes that if the active network is null it is blocked for background access, but that's not the case. BUG: 26685616 Change-Id: Ic6990037a2bc503c14512d7303ec71eb178f784b --- .../net/hostside/ConnectivityManagerTest.java | 46 ++++++++++++++----- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java index 34c8d28f7f..b27c80a0ad 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java @@ -25,11 +25,12 @@ import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; import android.net.ConnectivityManager; -import android.net.Network; import android.net.NetworkInfo; import android.test.InstrumentationTestCase; import android.util.Log; +import java.net.HttpURLConnection; +import java.net.URL; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; @@ -49,6 +50,9 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { private static final String STATUS_NETWORK_UNAVAILABLE_PREFIX = "NetworkUnavailable:"; private static final String STATUS_NETWORK_AVAILABLE_PREFIX = "NetworkAvailable:"; + private static final int NETWORK_TIMEOUT_MS = 15000; + private static final int SLEEP_TIME_SEC = 1; + private ConnectivityManager mCm; private int mUid; @@ -91,7 +95,6 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { int attempts = 0; int count = 0; final int maxAttempts = 5; - final int sleepTime = 10; do { attempts++; count = getNumberBroadcastsReceived(getInstrumentation().getContext(), receiverName, @@ -100,13 +103,14 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { break; } Log.d(TAG, "Count is " + count + " after " + attempts + " attempts; sleeping " - + sleepTime + " seconds before trying again"); - Thread.sleep(sleepTime * 1000); + + SLEEP_TIME_SEC + " seconds before trying again"); + Thread.sleep(SLEEP_TIME_SEC * 1000); } while (attempts <= maxAttempts); assertEquals("Number of expected broadcasts for " + receiverName + " not reached after " - + maxAttempts * sleepTime + " seconds", expectedCount, count); + + maxAttempts * SLEEP_TIME_SEC + " seconds", expectedCount, count); } + static int getNumberBroadcastsReceived(Context context, String receiverName, String action) throws Exception { final Context sharedContext = context.createPackageContext( @@ -129,13 +133,7 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { new Thread(new Runnable() { @Override public void run() { - Log.d(TAG, "Running on thread " + Thread.currentThread().getName()); - final Network network = mCm.getActiveNetwork(); - final NetworkInfo networkInfo = mCm.getActiveNetworkInfo(); - Log.d(TAG, "activeNetwork: " + network + " activeNetworkInfo: " + networkInfo); - final String prefix = network == null ? - STATUS_NETWORK_UNAVAILABLE_PREFIX : STATUS_NETWORK_AVAILABLE_PREFIX; - result.offer(prefix + networkInfo); + result.offer(checkNetworkStatus()); } }, "CheckNetworkThread").start(); final String actualNetworkStatus = result.poll(10, TimeUnit.SECONDS); @@ -146,6 +144,30 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { + actualNetworkStatus, actualNetworkStatus.startsWith(expectedPrefix)); } + protected String checkNetworkStatus() { + // TODO: connect to a hostside server instead + final String address = "http://example.com"; + final NetworkInfo networkInfo = mCm.getActiveNetworkInfo(); + Log.d(TAG, "Running checkNetworkStatus() on thread " + Thread.currentThread().getName() + + "\n\tactiveNetworkInfo: " + networkInfo + "\n\tURL: " + address); + String prefix = STATUS_NETWORK_AVAILABLE_PREFIX; + try { + final URL url = new URL(address); + final HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setReadTimeout(NETWORK_TIMEOUT_MS); + conn.setConnectTimeout(NETWORK_TIMEOUT_MS); + conn.setRequestMethod("GET"); + conn.setDoInput(true); + conn.connect(); + final int response = conn.getResponseCode(); + Log.d(TAG, "HTTP response for " + address + ": " + response); + } catch (Exception e) { + Log.d(TAG, "Exception getting " + address + ": " + e); + prefix = STATUS_NETWORK_UNAVAILABLE_PREFIX; + } + return prefix + networkInfo; + } + private String toString(int status) { switch (status) { case RESTRICT_BACKGROUND_STATUS_DISABLED: From a557ba681804c0cab73959c114bdaffe334fff2c Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Thu, 11 Feb 2016 11:56:30 -0800 Subject: [PATCH 0208/1109] Updated tests cases after to assert the proper number of notifications. Previously NMPS was broadcasting an intent every time add|removeRestrictBackgroundWhitelistedUid() was called, but that behavior has been changed to just broadcast an intent when there is a change. BUG: 26685616 Change-Id: I4eb7a4fda864a28ea23b661d1a88e18bfb80533d --- .../cts/net/hostside/ConnectivityManagerTest.java | 5 +++++ .../net/HostsideRestrictBackgroundNetworkTests.java | 12 +++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java index b27c80a0ad..8975dabd3a 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java @@ -80,6 +80,11 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); } + public void testRestrictBackgroundChangedNotReceived() throws Exception { + assertRestrictBackgroundChangedReceived(DYNAMIC_RECEIVER, 0); + assertRestrictBackgroundChangedReceived(MANIFEST_RECEIVER, 0); + } + public void testRestrictBackgroundChangedReceivedOnce() throws Exception { assertRestrictBackgroundChangedReceived(DYNAMIC_RECEIVER, 1); assertRestrictBackgroundChangedReceived(MANIFEST_RECEIVER, 0); diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java index 2b0b1c16ba..18047406cc 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java @@ -55,12 +55,13 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC public void testGetRestrictBackgroundStatus_disabled() throws Exception { removeRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundStatusDisabled(); - assertRestrictBackgroundChangedReceivedOnce(); + // From the app's point of view, nothing changed, it still have access + assertRestrictBackgroundChangedNotReceived(); // Sanity check: make sure status is always disabled, never whitelisted addRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundStatusDisabled(); - assertRestrictBackgroundChangedReceivedTwice(); + assertRestrictBackgroundChangedNotReceived(); } public void testGetRestrictBackgroundStatus_whitelisted() throws Exception { @@ -78,7 +79,7 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC removeRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundStatusEnabled(); - assertRestrictBackgroundChangedReceivedTwice(); + assertRestrictBackgroundChangedReceivedOnce(); } public void testGetRestrictBackgroundStatus_uninstall() throws Exception { @@ -121,6 +122,11 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC "testGetRestrictBackgroundStatus_enabled"); } + private void assertRestrictBackgroundChangedNotReceived() throws DeviceNotAvailableException { + runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", + "testRestrictBackgroundChangedNotReceived"); + } + private void assertRestrictBackgroundChangedReceivedOnce() throws DeviceNotAvailableException { runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", "testRestrictBackgroundChangedReceivedOnce"); From a0f49f2384fcbf1dff3b01d8511bd88effb600b6 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Thu, 18 Feb 2016 10:43:54 -0800 Subject: [PATCH 0209/1109] Refactored how data is shared between test apps. When running the device-site tests, it's necessary to share state between a second app and the main test app. Currently that's achieved through a shared preference file that is accessed by both apps (since they use a shared id), but this approach will not work on power save mode tests (because the test app will be in foreground and the background restrictions won't be applied in the second app). This change refactors the data sharing mechanism by: - Using an ordered broadcast that is sent from the test app to the secondary app. - Checking for the network status in the secondary app. - Moving the test logic to the client-side tests. BUG: 27127112 Change-Id: I44987701b908b329fdf40e3a7a97e9f30cfadecb --- tests/cts/hostside/app/AndroidManifest.xml | 7 +- .../net/hostside/ConnectivityManagerTest.java | 282 ++++++++++++------ tests/cts/hostside/app2/AndroidManifest.xml | 20 +- .../android/cts/net/hostside/app2/Common.java | 12 + .../hostside/app2/MyBroadcastReceiver.java | 126 +++++++- ...ostsideRestrictBackgroundNetworkTests.java | 133 +-------- 6 files changed, 362 insertions(+), 218 deletions(-) diff --git a/tests/cts/hostside/app/AndroidManifest.xml b/tests/cts/hostside/app/AndroidManifest.xml index f44fdd1dfc..c7978f8775 100644 --- a/tests/cts/hostside/app/AndroidManifest.xml +++ b/tests/cts/hostside/app/AndroidManifest.xml @@ -15,11 +15,12 @@ --> + package="com.android.cts.net.hostside"> - + + + diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java index 8975dabd3a..9a4f318ce8 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java @@ -16,24 +16,26 @@ package com.android.cts.net.hostside; +import static android.cts.util.SystemUtil.runShellCommand; import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.test.InstrumentationTestCase; -import android.util.Log; - -import java.net.HttpURLConnection; -import java.net.URL; +import java.io.IOException; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import android.app.Instrumentation; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.net.wifi.WifiManager; +import android.test.InstrumentationTestCase; +import android.util.Log; + /** * Tests for the {@link ConnectivityManager} API. * @@ -44,54 +46,91 @@ import java.util.concurrent.TimeUnit; public class ConnectivityManagerTest extends InstrumentationTestCase { private static final String TAG = "ConnectivityManagerTest"; + private static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2"; + + private static final int SLEEP_TIME_SEC = 1; + private static final boolean DEBUG = true; + + // Constants below must match values defined on app2's Common.java private static final String MANIFEST_RECEIVER = "ManifestReceiver"; private static final String DYNAMIC_RECEIVER = "DynamicReceiver"; - + private static final String ACTION_GET_COUNTERS = + "com.android.cts.net.hostside.app2.action.GET_COUNTERS"; + private static final String ACTION_CHECK_NETWORK = + "com.android.cts.net.hostside.app2.action.CHECK_NETWORK"; + private static final String EXTRA_ACTION = "com.android.cts.net.hostside.app2.extra.ACTION"; + private static final String EXTRA_RECEIVER_NAME = + "com.android.cts.net.hostside.app2.extra.RECEIVER_NAME"; + private static final String RESULT_SEPARATOR = ";"; private static final String STATUS_NETWORK_UNAVAILABLE_PREFIX = "NetworkUnavailable:"; private static final String STATUS_NETWORK_AVAILABLE_PREFIX = "NetworkAvailable:"; - private static final int NETWORK_TIMEOUT_MS = 15000; - private static final int SLEEP_TIME_SEC = 1; - + private Context mContext; + private Instrumentation mInstrumentation; private ConnectivityManager mCm; + private WifiManager mWfm; private int mUid; + private boolean mResetMeteredWifi = false; @Override public void setUp() throws Exception { super.setUp(); - final Context context = getInstrumentation().getContext(); - mCm = (ConnectivityManager) context.getSystemService(Activity.CONNECTIVITY_SERVICE); - mUid = context.getPackageManager() - .getPackageInfo(context.getPackageName(), 0).applicationInfo.uid; - final boolean metered = mCm.isActiveNetworkMetered(); - Log.i(TAG, getName() + ": uid=" + mUid + ", metered=" + metered); - assertTrue("Active network is not metered", metered); + mInstrumentation = getInstrumentation(); + mContext = mInstrumentation.getContext(); + mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); + mWfm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); + mUid = mContext.getPackageManager().getPackageInfo(TEST_APP2_PKG, 0).applicationInfo.uid; + final int myUid = mContext.getPackageManager() + .getPackageInfo(mContext.getPackageName(), 0).applicationInfo.uid; + + Log.d(TAG, "UIDS: test app=" + myUid + ", app2=" + mUid); + + setRestrictBackground(false); + setMeteredNetwork(); + + registerApp2BroadcastReceiver(); } + @Override + protected void tearDown() throws Exception { + super.tearDown(); + + if (mResetMeteredWifi) { + setWifiMeteredStatus(false); + } + } + public void testGetRestrictBackgroundStatus_disabled() throws Exception { + removeRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + assertRestrictBackgroundChangedReceived(0); + + // Sanity check: make sure status is always disabled, never whitelisted + addRestrictBackgroundWhitelist(mUid); + assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + assertRestrictBackgroundChangedReceived(0); } public void testGetRestrictBackgroundStatus_whitelisted() throws Exception { + setRestrictBackground(true); + assertRestrictBackgroundChangedReceived(1); + + addRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_WHITELISTED); + assertRestrictBackgroundChangedReceived(2); } public void testGetRestrictBackgroundStatus_enabled() throws Exception { + setRestrictBackground(true); + assertRestrictBackgroundChangedReceived(1); + + removeRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); + assertRestrictBackgroundChangedReceived(1); } - public void testRestrictBackgroundChangedNotReceived() throws Exception { - assertRestrictBackgroundChangedReceived(DYNAMIC_RECEIVER, 0); - assertRestrictBackgroundChangedReceived(MANIFEST_RECEIVER, 0); - } - - public void testRestrictBackgroundChangedReceivedOnce() throws Exception { - assertRestrictBackgroundChangedReceived(DYNAMIC_RECEIVER, 1); - assertRestrictBackgroundChangedReceived(MANIFEST_RECEIVER, 0); - } - - public void testRestrictBackgroundChangedReceivedTwice() throws Exception { - assertRestrictBackgroundChangedReceived(DYNAMIC_RECEIVER, 2); + public void assertRestrictBackgroundChangedReceived(int expectedCount) throws Exception { + assertRestrictBackgroundChangedReceived(DYNAMIC_RECEIVER, expectedCount); assertRestrictBackgroundChangedReceived(MANIFEST_RECEIVER, 0); } @@ -102,12 +141,12 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { final int maxAttempts = 5; do { attempts++; - count = getNumberBroadcastsReceived(getInstrumentation().getContext(), receiverName, - ACTION_RESTRICT_BACKGROUND_CHANGED); + count = getNumberBroadcastsReceived(receiverName, ACTION_RESTRICT_BACKGROUND_CHANGED); if (count == expectedCount) { break; } - Log.d(TAG, "Count is " + count + " after " + attempts + " attempts; sleeping " + Log.d(TAG, "Expecting count " + expectedCount + " but actual is " + count + " after " + + attempts + " attempts; sleeping " + SLEEP_TIME_SEC + " seconds before trying again"); Thread.sleep(SLEEP_TIME_SEC * 1000); } while (attempts <= maxAttempts); @@ -115,62 +154,139 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { + maxAttempts * SLEEP_TIME_SEC + " seconds", expectedCount, count); } + private String sendOrderedBroadcast(Intent intent) throws Exception { + final LinkedBlockingQueue result = new LinkedBlockingQueue<>(1); + Log.d(TAG, "Sending ordered broadcast: " + intent); + mContext.sendOrderedBroadcast(intent, null, new BroadcastReceiver() { - static int getNumberBroadcastsReceived(Context context, String receiverName, String action) - throws Exception { - final Context sharedContext = context.createPackageContext( - "com.android.cts.net.hostside.app2", Context.CONTEXT_IGNORE_SECURITY); - final SharedPreferences prefs = sharedContext.getSharedPreferences(receiverName, - Context.MODE_PRIVATE); - return prefs.getInt(action, 0); + @Override + public void onReceive(Context context, Intent intent) { + final String resultData = getResultData(); + if (resultData == null) { + Log.e(TAG, "Received null data from ordered intent"); + return; + } + result.offer(resultData); + } + }, null, 0, null, null); + + final String resultData = result.poll(60, TimeUnit.SECONDS); + assertNotNull("timeout waiting for ordered broadcast result", resultData); + Log.d(TAG, "Ordered broadcast response: " + resultData); + return resultData; } - private void assertRestrictBackgroundStatus(int expectedApiStatus) throws InterruptedException { - // First asserts the API returns the proper value... - final String expected = toString(expectedApiStatus); - Log.d(TAG, getName() + " (expecting " + expected + ")"); - final int apiStatus = mCm.getRestrictBackgroundStatus(); - String actualApiStatus = toString(apiStatus); - assertEquals("wrong status", expected, actualApiStatus); + private int getNumberBroadcastsReceived(String receiverName, String action) throws Exception { + final Intent intent = new Intent(ACTION_GET_COUNTERS); + intent.putExtra(EXTRA_ACTION, ACTION_RESTRICT_BACKGROUND_CHANGED); + intent.putExtra(EXTRA_RECEIVER_NAME, receiverName); + final String resultData = sendOrderedBroadcast(intent); + return Integer.valueOf(resultData); + } - //...then use a background thread to verify the actual network status. - final LinkedBlockingQueue result = new LinkedBlockingQueue<>(1); - new Thread(new Runnable() { - @Override - public void run() { - result.offer(checkNetworkStatus()); - } - }, "CheckNetworkThread").start(); - final String actualNetworkStatus = result.poll(10, TimeUnit.SECONDS); - assertNotNull("timeout waiting for background thread", actualNetworkStatus); - final String expectedPrefix = apiStatus == RESTRICT_BACKGROUND_STATUS_ENABLED ? - STATUS_NETWORK_UNAVAILABLE_PREFIX : STATUS_NETWORK_AVAILABLE_PREFIX; + private void assertRestrictBackgroundStatus(int expectedApiStatus) throws Exception { + final Intent intent = new Intent(ACTION_CHECK_NETWORK); + final String resultData = sendOrderedBroadcast(intent); + final String[] resultItems = resultData.split(RESULT_SEPARATOR); + final String actualApiStatus = toString(Integer.parseInt(resultItems[0])); + final String actualNetworkStatus = resultItems[1]; + + // First asserts the API returns the proper value... + assertEquals("wrong status", toString(expectedApiStatus), actualApiStatus); + + //...then the actual network status in the background thread. + final String expectedPrefix = expectedApiStatus == RESTRICT_BACKGROUND_STATUS_ENABLED ? + STATUS_NETWORK_UNAVAILABLE_PREFIX : STATUS_NETWORK_AVAILABLE_PREFIX; assertTrue("Wrong network status for API status " + actualApiStatus + ": " + actualNetworkStatus, actualNetworkStatus.startsWith(expectedPrefix)); } - protected String checkNetworkStatus() { - // TODO: connect to a hostside server instead - final String address = "http://example.com"; - final NetworkInfo networkInfo = mCm.getActiveNetworkInfo(); - Log.d(TAG, "Running checkNetworkStatus() on thread " + Thread.currentThread().getName() - + "\n\tactiveNetworkInfo: " + networkInfo + "\n\tURL: " + address); - String prefix = STATUS_NETWORK_AVAILABLE_PREFIX; - try { - final URL url = new URL(address); - final HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setReadTimeout(NETWORK_TIMEOUT_MS); - conn.setConnectTimeout(NETWORK_TIMEOUT_MS); - conn.setRequestMethod("GET"); - conn.setDoInput(true); - conn.connect(); - final int response = conn.getResponseCode(); - Log.d(TAG, "HTTP response for " + address + ": " + response); - } catch (Exception e) { - Log.d(TAG, "Exception getting " + address + ": " + e); - prefix = STATUS_NETWORK_UNAVAILABLE_PREFIX; + private String executeShellCommand(String command) throws IOException { + final String result = runShellCommand(mInstrumentation, command).trim(); + if (DEBUG) Log.d(TAG, "Command '" + command + "' returned '" + result + "'"); + return result; + } + + private void setMeteredNetwork() throws IOException { + final NetworkInfo info = mCm.getActiveNetworkInfo(); + final boolean metered = mCm.isActiveNetworkMetered(); + if (metered) { + Log.d(TAG, "Active network already metered: " + info); + return; } - return prefix + networkInfo; + final String netId = setWifiMeteredStatus(true); + assertTrue("Could not set wifi '" + netId + "' as metered (" + + mCm.getActiveNetworkInfo() +")", mCm.isActiveNetworkMetered()); + // Set flag so status is reverted on teardown. + mResetMeteredWifi = true; + } + + private String setWifiMeteredStatus(boolean metered) throws IOException { + mWfm.setWifiEnabled(true); + // TODO: if it's not guaranteed the device has wi-fi, we need to change the tests + // to make the actual verification of restrictions optional. + final String ssid = mWfm.getConnectionInfo().getSSID(); + assertNotNull("null SSID", ssid); + final String netId = ssid.trim().replaceAll("\"", ""); // remove quotes, if any. + assertFalse("empty SSID", ssid.isEmpty()); + + Log.i(TAG, "Setting wi-fi network " + netId + " metered status to " + metered); + final String setCommand = "cmd netpolicy set metered-network " + netId + " " + metered; + final String result = executeShellCommand(setCommand); + assertTrue("Command '" + setCommand + "' failed: " + result, result.isEmpty()); + + // Sanity check. + final String newStatus = executeShellCommand("cmd netpolicy get metered-network " + netId); + assertEquals("Metered status of wi-fi network " + netId + " not set properly", + newStatus.trim(), Boolean.toString(metered)); + return netId; + } + + private void setRestrictBackground(boolean enabled) throws IOException { + executeShellCommand("cmd netpolicy set restrict-background " + enabled); + final String output = executeShellCommand("cmd netpolicy get restrict-background "); + final String expectedSuffix = enabled ? "enabled" : "disabled"; + // TODO: use MoreAsserts? + assertTrue("output '" + output + "' should end with '" + expectedSuffix + "'", + output.endsWith(expectedSuffix)); + } + + private void addRestrictBackgroundWhitelist(int uid) throws Exception { + executeShellCommand("cmd netpolicy add restrict-background-whitelist " + uid); + assertRestrictBackgroundWhitelist(uid, true); + } + + private void removeRestrictBackgroundWhitelist(int uid) throws Exception { + executeShellCommand("cmd netpolicy remove restrict-background-whitelist " + uid); + assertRestrictBackgroundWhitelist(uid, false); + } + + private void assertRestrictBackgroundWhitelist(int uid, boolean expected) throws Exception { + final int maxTries = 5; + boolean actual = false; + for (int i = 1; i <= maxTries; i++) { + final String output = + executeShellCommand("cmd netpolicy list restrict-background-whitelist "); + actual = output.contains(Integer.toString(uid)); + if (expected == actual) { + return; + } + Log.v(TAG, "whitelist check for uid " + uid + " doesn't match yet (expected " + + expected + ", got " + actual + "); sleeping 1s before polling again"); + Thread.sleep(1000); + } + fail("whitelist check for uid " + uid + " failed: expected " + expected + ", got " + actual); + } + + /** + * Starts a service that will register a broadcast receiver to receive + * {@code RESTRICT_BACKGROUND_CHANGE} intents. + *

+ * The service must run in a separate app because otherwise it would be killed every time + * {@link #runDeviceTests(String, String)} is executed. + */ + private void registerApp2BroadcastReceiver() throws IOException { + executeShellCommand("am startservice com.android.cts.net.hostside.app2/.MyService"); } private String toString(int status) { diff --git a/tests/cts/hostside/app2/AndroidManifest.xml b/tests/cts/hostside/app2/AndroidManifest.xml index d69bf56a1c..fa4cb43d29 100644 --- a/tests/cts/hostside/app2/AndroidManifest.xml +++ b/tests/cts/hostside/app2/AndroidManifest.xml @@ -16,20 +16,28 @@ --> + package="com.android.cts.net.hostside.app2" > - - + + + diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java index 91caeda97d..3be4261258 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java @@ -18,6 +18,18 @@ package com.android.cts.net.hostside.app2; public final class Common { static final String TAG = "CtsNetApp2"; + + // Constants below must match values defined on app's ConnectivityManagerTest.java static final String MANIFEST_RECEIVER = "ManifestReceiver"; static final String DYNAMIC_RECEIVER = "DynamicReceiver"; + static final String ACTION_GET_COUNTERS = + "com.android.cts.net.hostside.app2.action.GET_COUNTERS"; + static final String ACTION_CHECK_NETWORK = + "com.android.cts.net.hostside.app2.action.CHECK_NETWORK"; + static final String EXTRA_ACTION = "com.android.cts.net.hostside.app2.extra.ACTION"; + static final String EXTRA_RECEIVER_NAME = + "com.android.cts.net.hostside.app2.extra.RECEIVER_NAME"; + static final char RESULT_SEPARATOR = ';'; + static final String STATUS_NETWORK_UNAVAILABLE_PREFIX = "NetworkUnavailable:"; + static final String STATUS_NETWORK_AVAILABLE_PREFIX = "NetworkAvailable:"; } diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java index 0cbf360d8f..65c7b6009d 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java @@ -13,21 +13,44 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.android.cts.net.hostside.app2; +import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; +import static com.android.cts.net.hostside.app2.Common.ACTION_CHECK_NETWORK; +import static com.android.cts.net.hostside.app2.Common.ACTION_GET_COUNTERS; +import static com.android.cts.net.hostside.app2.Common.EXTRA_ACTION; +import static com.android.cts.net.hostside.app2.Common.EXTRA_RECEIVER_NAME; import static com.android.cts.net.hostside.app2.Common.MANIFEST_RECEIVER; +import static com.android.cts.net.hostside.app2.Common.RESULT_SEPARATOR; +import static com.android.cts.net.hostside.app2.Common.STATUS_NETWORK_AVAILABLE_PREFIX; +import static com.android.cts.net.hostside.app2.Common.STATUS_NETWORK_UNAVAILABLE_PREFIX; import static com.android.cts.net.hostside.app2.Common.TAG; + +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; import android.util.Log; /** - * Receiver that stores received broadcasts in a shared preference. + * Receiver used to: + *

    + *
  1. Stored received RESTRICT_BACKGROUND_CHANGED broadcasts in a shared preference. + *
  2. Returned the number of RESTRICT_BACKGROUND_CHANGED broadcasts in an ordered broadcast. + *
*/ public class MyBroadcastReceiver extends BroadcastReceiver { + private static final int NETWORK_TIMEOUT_MS = 15 * 1000; + private final String mName; public MyBroadcastReceiver() { @@ -37,15 +60,106 @@ public class MyBroadcastReceiver extends BroadcastReceiver { MyBroadcastReceiver(String name) { Log.d(TAG, "Constructing MyBroadcastReceiver named " + name); mName = name; - } + } @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "onReceive() for " + mName + ": " + intent); + final String action = intent.getAction(); + switch (action) { + case ACTION_RESTRICT_BACKGROUND_CHANGED: + increaseCounter(context, action); + break; + case ACTION_GET_COUNTERS: + setResultDataFromCounter(context, intent); + break; + case ACTION_CHECK_NETWORK: + checkNetwork(context, intent); + break; + default: + Log.e(TAG, "received unexpected action: " + action); + } + } + + private void increaseCounter(Context context, String action) { final SharedPreferences prefs = context.getSharedPreferences(mName, Context.MODE_PRIVATE); - final String pref = intent.getAction(); - final int value = prefs.getInt(pref, 0) + 1; - Log.d(TAG, "Setting " + pref + " = " + value); - prefs.edit().putInt(pref, value).apply(); + final int value = prefs.getInt(action, 0) + 1; + Log.d(TAG, "increaseCounter('" + action + "'): setting '" + mName + "' to " + value); + prefs.edit().putInt(action, value).apply(); + } + + private int getCounter(Context context, String action, String receiverName) { + final SharedPreferences prefs = context.getSharedPreferences(receiverName, + Context.MODE_PRIVATE); + final int value = prefs.getInt(action, 0); + Log.d(TAG, "getCounter('" + action + "', '" + receiverName + "'): " + value); + return value; + } + + private void checkNetwork(final Context context, Intent intent) { + final ConnectivityManager cm = (ConnectivityManager) context + .getSystemService(Context.CONNECTIVITY_SERVICE); + + final StringBuilder data = new StringBuilder(); + final int apiStatus = cm.getRestrictBackgroundStatus(); + String netStatus; + try { + netStatus = checkNetworkStatus(cm); + } catch (InterruptedException e) { + Log.e(TAG, "Timeout checking network status"); + setResultData(null); + return; + } + data.append(apiStatus).append(RESULT_SEPARATOR).append(netStatus); + Log.d(TAG, "checkNetwork: returning " + data); + setResultData(data.toString()); + } + + private String checkNetworkStatus(final ConnectivityManager cm) throws InterruptedException { + final LinkedBlockingQueue result = new LinkedBlockingQueue<>(1); + new Thread(new Runnable() { + + @Override + public void run() { + // TODO: connect to a hostside server instead + final String address = "http://example.com"; + final NetworkInfo networkInfo = cm.getActiveNetworkInfo(); + Log.d(TAG, "Running checkNetworkStatus() on thread " + + Thread.currentThread().getName() + + "\n\tactiveNetworkInfo: " + networkInfo + "\n\tURL: " + address); + String prefix = STATUS_NETWORK_AVAILABLE_PREFIX; + try { + final URL url = new URL(address); + final HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setReadTimeout(NETWORK_TIMEOUT_MS); + conn.setConnectTimeout(NETWORK_TIMEOUT_MS); + conn.setRequestMethod("GET"); + conn.setDoInput(true); + conn.connect(); + final int response = conn.getResponseCode(); + Log.d(TAG, "HTTP response for " + address + ": " + response); + } catch (Exception e) { + Log.d(TAG, "Exception getting " + address + ": " + e); + prefix = STATUS_NETWORK_UNAVAILABLE_PREFIX + "Exception " + e + ":"; + } + result.offer(prefix + networkInfo); + } + }, mName).start(); + return result.poll(NETWORK_TIMEOUT_MS * 2, TimeUnit.MILLISECONDS); + } + + private void setResultDataFromCounter(Context context, Intent intent) { + final String action = intent.getStringExtra(EXTRA_ACTION); + if (action == null) { + Log.e(TAG, "Missing extra '" + EXTRA_ACTION + "' on " + intent); + return; + } + final String receiverName = intent.getStringExtra(EXTRA_RECEIVER_NAME); + if (receiverName == null) { + Log.e(TAG, "Missing extra '" + EXTRA_RECEIVER_NAME + "' on " + intent); + return; + } + final int counter = getCounter(context, action, receiverName); + setResultData(String.valueOf(counter)); } } diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java index 18047406cc..f2c3b1f7d2 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java @@ -17,30 +17,19 @@ package com.android.cts.net; import com.android.ddmlib.Log; -import com.android.tradefed.device.DeviceNotAvailableException; -import com.android.tradefed.device.WifiHelper; public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestCase { + private static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2"; private static final String TEST_APP2_APK = "CtsHostsideNetworkTestsApp2.apk"; - private int mUid; - private WifiHelper mWifiHelper; - @Override protected void setUp() throws Exception { super.setUp(); - mUid = getUid(TEST_PKG); - mWifiHelper = new WifiHelper(getDevice()); - - setWifiMeteredStatus(true); - setRestrictBackground(false); - uninstallPackage(TEST_APP2_PKG, false); installPackage(TEST_APP2_APK); - startBroadcastReceiverService(); } @Override @@ -48,103 +37,35 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC super.tearDown(); uninstallPackage(TEST_APP2_PKG, true); - setRestrictBackground(false); - setWifiMeteredStatus(false); } public void testGetRestrictBackgroundStatus_disabled() throws Exception { - removeRestrictBackgroundWhitelist(mUid); - assertRestrictBackgroundStatusDisabled(); - // From the app's point of view, nothing changed, it still have access - assertRestrictBackgroundChangedNotReceived(); - - // Sanity check: make sure status is always disabled, never whitelisted - addRestrictBackgroundWhitelist(mUid); - assertRestrictBackgroundStatusDisabled(); - assertRestrictBackgroundChangedNotReceived(); - } - - public void testGetRestrictBackgroundStatus_whitelisted() throws Exception { - setRestrictBackground(true); - assertRestrictBackgroundChangedReceivedOnce(); - - addRestrictBackgroundWhitelist(mUid); - assertRestrictBackgroundStatusWhitelisted(); - assertRestrictBackgroundChangedReceivedTwice(); - } - - public void testGetRestrictBackgroundStatus_enabled() throws Exception { - setRestrictBackground(true); - assertRestrictBackgroundChangedReceivedOnce(); - - removeRestrictBackgroundWhitelist(mUid); - assertRestrictBackgroundStatusEnabled(); - assertRestrictBackgroundChangedReceivedOnce(); - } - - public void testGetRestrictBackgroundStatus_uninstall() throws Exception { - addRestrictBackgroundWhitelist(mUid); - assertRestrictBackgroundWhitelist(mUid, true); - - uninstallPackage(TEST_PKG, true); - assertPackageUninstalled(TEST_PKG); - assertRestrictBackgroundWhitelist(mUid, false); - - installPackage(TEST_APK); - final int newUid = getUid(TEST_PKG); - assertRestrictBackgroundWhitelist(mUid, false); - assertRestrictBackgroundWhitelist(newUid, false); - } - - /** - * Starts a service that will register a broadcast receiver to receive - * {@code RESTRICT_BACKGROUND_CHANGE} intents. - *

- * The service must run in a separate app because otherwise it would be killed every time - * {@link #runDeviceTests(String, String)} is executed. - */ - private void startBroadcastReceiverService() throws DeviceNotAvailableException { - runCommand("am startservice " + TEST_APP2_PKG + "/.MyService"); - } - - private void assertRestrictBackgroundStatusDisabled() throws DeviceNotAvailableException { runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", "testGetRestrictBackgroundStatus_disabled"); } - private void assertRestrictBackgroundStatusWhitelisted() throws DeviceNotAvailableException { + public void testGetRestrictBackgroundStatus_whitelisted() throws Exception { runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", "testGetRestrictBackgroundStatus_whitelisted"); } - private void assertRestrictBackgroundStatusEnabled() throws DeviceNotAvailableException { + public void testGetRestrictBackgroundStatus_enabled() throws Exception { runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", "testGetRestrictBackgroundStatus_enabled"); } - private void assertRestrictBackgroundChangedNotReceived() throws DeviceNotAvailableException { - runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", - "testRestrictBackgroundChangedNotReceived"); - } + public void testGetRestrictBackgroundStatus_uninstall() throws Exception { + final int oldUid = getUid(TEST_PKG); + testGetRestrictBackgroundStatus_whitelisted(); - private void assertRestrictBackgroundChangedReceivedOnce() throws DeviceNotAvailableException { - runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", - "testRestrictBackgroundChangedReceivedOnce"); - } + uninstallPackage(TEST_PKG, true); + assertPackageUninstalled(TEST_PKG); + assertRestrictBackgroundWhitelist(oldUid, false); - private void assertRestrictBackgroundChangedReceivedTwice() throws DeviceNotAvailableException { - runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", - "testRestrictBackgroundChangedReceivedTwice"); - } - - private void addRestrictBackgroundWhitelist(int uid) throws Exception { - runCommand("cmd netpolicy add restrict-background-whitelist " + uid); - assertRestrictBackgroundWhitelist(uid, true); - } - - private void removeRestrictBackgroundWhitelist(int uid) throws Exception { - runCommand("cmd netpolicy remove restrict-background-whitelist " + uid); - assertRestrictBackgroundWhitelist(uid, false); + installPackage(TEST_APK); + final int newUid = getUid(TEST_PKG); + assertRestrictBackgroundWhitelist(oldUid, false); + assertRestrictBackgroundWhitelist(newUid, false); } private void assertRestrictBackgroundWhitelist(int uid, boolean expected) throws Exception { @@ -163,32 +84,4 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC fail("whitelist check for uid " + uid + " failed: expected " + expected + ", got " + actual); } - - private void setWifiMeteredStatus(boolean metered) throws DeviceNotAvailableException { - mWifiHelper.enableWifi(); - // TODO: if it's not guaranteed the device has wi-fi, we need to change the tests - // to make the actual verification of restrictions optional. - final String netId = mWifiHelper.getSSID(); - assertNotNull("null SSID", netId); - assertFalse("empty SSID", netId.trim().isEmpty()); - - Log.i(TAG, "Setting wi-fi network " + netId + " metered status to " + metered); - final String setCommand = "cmd netpolicy set metered-network " + netId + " "+ metered; - final String result = runCommand(setCommand); - assertTrue("Command '" + setCommand + "' failed: " + result, result.trim().isEmpty()); - - // Sanity check. - final String newStatus = runCommand("cmd netpolicy get metered-network " + netId); - assertEquals("Metered status of wi-fi network " + netId + " not set properly", - newStatus.trim(), Boolean.toString(metered)); - } - - private void setRestrictBackground(boolean enabled) throws DeviceNotAvailableException { - runCommand("cmd netpolicy set restrict-background " + enabled); - final String output = runCommand("cmd netpolicy get restrict-background ").trim(); - final String expectedSuffix = enabled ? "enabled" : "disabled"; - // TODO: use MoreAsserts? - assertTrue("output '" + output + "' should end with '" + expectedSuffix + "'", - output.endsWith(expectedSuffix)); - } } From 0a0857762a05c5b7e80a2fab5142aa4ea91eed18 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Thu, 18 Feb 2016 17:22:33 -0800 Subject: [PATCH 0210/1109] Split client-side test in 2 classes so some common code can be used to test Power Save Mode. BUG: 27127112 Change-Id: I6954ce8474da6da678d4bfe194334ed5a08aaeff --- ...actRestrictBackgroundNetworkTestCase.java} | 78 +++++-------------- .../cts/net/hostside/DataSaverModeTest.java | 61 +++++++++++++++ ...ostsideRestrictBackgroundNetworkTests.java | 6 +- 3 files changed, 85 insertions(+), 60 deletions(-) rename tests/cts/hostside/app/src/com/android/cts/net/hostside/{ConnectivityManagerTest.java => AbstractRestrictBackgroundNetworkTestCase.java} (78%) create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java similarity index 78% rename from tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java rename to tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 9a4f318ce8..59de7593b2 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/ConnectivityManagerTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -37,14 +37,10 @@ import android.test.InstrumentationTestCase; import android.util.Log; /** - * Tests for the {@link ConnectivityManager} API. - * - *

These tests rely on a host-side test to use {@code adb shell cmd netpolicy} to put the device - * in the proper state. In fact, they're more like "assertions" than tests per se - the real test - * logic is done on {@code HostsideNetworkTests}. + * Superclass for tests related to background network restrictions. */ -public class ConnectivityManagerTest extends InstrumentationTestCase { - private static final String TAG = "ConnectivityManagerTest"; +abstract class AbstractRestrictBackgroundNetworkTestCase extends InstrumentationTestCase { + protected static final String TAG = "RestrictBackgroundNetworkTests"; private static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2"; @@ -65,11 +61,11 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { private static final String STATUS_NETWORK_UNAVAILABLE_PREFIX = "NetworkUnavailable:"; private static final String STATUS_NETWORK_AVAILABLE_PREFIX = "NetworkAvailable:"; - private Context mContext; - private Instrumentation mInstrumentation; - private ConnectivityManager mCm; - private WifiManager mWfm; - private int mUid; + protected Context mContext; + protected Instrumentation mInstrumentation; + protected ConnectivityManager mCm; + protected WifiManager mWfm; + protected int mUid; private boolean mResetMeteredWifi = false; @Override @@ -85,10 +81,7 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { Log.d(TAG, "UIDS: test app=" + myUid + ", app2=" + mUid); - setRestrictBackground(false); setMeteredNetwork(); - - registerApp2BroadcastReceiver(); } @Override @@ -100,41 +93,12 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { } } - public void testGetRestrictBackgroundStatus_disabled() throws Exception { - removeRestrictBackgroundWhitelist(mUid); - assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); - assertRestrictBackgroundChangedReceived(0); - - // Sanity check: make sure status is always disabled, never whitelisted - addRestrictBackgroundWhitelist(mUid); - assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); - assertRestrictBackgroundChangedReceived(0); - } - - public void testGetRestrictBackgroundStatus_whitelisted() throws Exception { - setRestrictBackground(true); - assertRestrictBackgroundChangedReceived(1); - - addRestrictBackgroundWhitelist(mUid); - assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_WHITELISTED); - assertRestrictBackgroundChangedReceived(2); - } - - public void testGetRestrictBackgroundStatus_enabled() throws Exception { - setRestrictBackground(true); - assertRestrictBackgroundChangedReceived(1); - - removeRestrictBackgroundWhitelist(mUid); - assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); - assertRestrictBackgroundChangedReceived(1); - } - - public void assertRestrictBackgroundChangedReceived(int expectedCount) throws Exception { + protected void assertRestrictBackgroundChangedReceived(int expectedCount) throws Exception { assertRestrictBackgroundChangedReceived(DYNAMIC_RECEIVER, expectedCount); assertRestrictBackgroundChangedReceived(MANIFEST_RECEIVER, 0); } - private void assertRestrictBackgroundChangedReceived(String receiverName, int expectedCount) + protected void assertRestrictBackgroundChangedReceived(String receiverName, int expectedCount) throws Exception { int attempts = 0; int count = 0; @@ -154,7 +118,7 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { + maxAttempts * SLEEP_TIME_SEC + " seconds", expectedCount, count); } - private String sendOrderedBroadcast(Intent intent) throws Exception { + protected String sendOrderedBroadcast(Intent intent) throws Exception { final LinkedBlockingQueue result = new LinkedBlockingQueue<>(1); Log.d(TAG, "Sending ordered broadcast: " + intent); mContext.sendOrderedBroadcast(intent, null, new BroadcastReceiver() { @@ -176,7 +140,7 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { return resultData; } - private int getNumberBroadcastsReceived(String receiverName, String action) throws Exception { + protected int getNumberBroadcastsReceived(String receiverName, String action) throws Exception { final Intent intent = new Intent(ACTION_GET_COUNTERS); intent.putExtra(EXTRA_ACTION, ACTION_RESTRICT_BACKGROUND_CHANGED); intent.putExtra(EXTRA_RECEIVER_NAME, receiverName); @@ -184,7 +148,7 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { return Integer.valueOf(resultData); } - private void assertRestrictBackgroundStatus(int expectedApiStatus) throws Exception { + protected void assertRestrictBackgroundStatus(int expectedApiStatus) throws Exception { final Intent intent = new Intent(ACTION_CHECK_NETWORK); final String resultData = sendOrderedBroadcast(intent); final String[] resultItems = resultData.split(RESULT_SEPARATOR); @@ -201,13 +165,13 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { + actualNetworkStatus, actualNetworkStatus.startsWith(expectedPrefix)); } - private String executeShellCommand(String command) throws IOException { + protected String executeShellCommand(String command) throws IOException { final String result = runShellCommand(mInstrumentation, command).trim(); if (DEBUG) Log.d(TAG, "Command '" + command + "' returned '" + result + "'"); return result; } - private void setMeteredNetwork() throws IOException { + protected void setMeteredNetwork() throws IOException { final NetworkInfo info = mCm.getActiveNetworkInfo(); final boolean metered = mCm.isActiveNetworkMetered(); if (metered) { @@ -221,7 +185,7 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { mResetMeteredWifi = true; } - private String setWifiMeteredStatus(boolean metered) throws IOException { + protected String setWifiMeteredStatus(boolean metered) throws IOException { mWfm.setWifiEnabled(true); // TODO: if it's not guaranteed the device has wi-fi, we need to change the tests // to make the actual verification of restrictions optional. @@ -242,7 +206,7 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { return netId; } - private void setRestrictBackground(boolean enabled) throws IOException { + protected void setRestrictBackground(boolean enabled) throws IOException { executeShellCommand("cmd netpolicy set restrict-background " + enabled); final String output = executeShellCommand("cmd netpolicy get restrict-background "); final String expectedSuffix = enabled ? "enabled" : "disabled"; @@ -251,17 +215,17 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { output.endsWith(expectedSuffix)); } - private void addRestrictBackgroundWhitelist(int uid) throws Exception { + protected void addRestrictBackgroundWhitelist(int uid) throws Exception { executeShellCommand("cmd netpolicy add restrict-background-whitelist " + uid); assertRestrictBackgroundWhitelist(uid, true); } - private void removeRestrictBackgroundWhitelist(int uid) throws Exception { + protected void removeRestrictBackgroundWhitelist(int uid) throws Exception { executeShellCommand("cmd netpolicy remove restrict-background-whitelist " + uid); assertRestrictBackgroundWhitelist(uid, false); } - private void assertRestrictBackgroundWhitelist(int uid, boolean expected) throws Exception { + protected void assertRestrictBackgroundWhitelist(int uid, boolean expected) throws Exception { final int maxTries = 5; boolean actual = false; for (int i = 1; i <= maxTries; i++) { @@ -285,7 +249,7 @@ public class ConnectivityManagerTest extends InstrumentationTestCase { * The service must run in a separate app because otherwise it would be killed every time * {@link #runDeviceTests(String, String)} is executed. */ - private void registerApp2BroadcastReceiver() throws IOException { + protected void registerApp2BroadcastReceiver() throws IOException { executeShellCommand("am startservice com.android.cts.net.hostside.app2/.MyService"); } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java new file mode 100644 index 0000000000..c62189ed23 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2016 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.cts.net.hostside; + +import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; +import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; +import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; + +public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase { + + @Override + public void setUp() throws Exception { + super.setUp(); + + setRestrictBackground(false); + registerApp2BroadcastReceiver(); + } + + public void testGetRestrictBackgroundStatus_disabled() throws Exception { + removeRestrictBackgroundWhitelist(mUid); + assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + assertRestrictBackgroundChangedReceived(0); + + // Sanity check: make sure status is always disabled, never whitelisted + addRestrictBackgroundWhitelist(mUid); + assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + assertRestrictBackgroundChangedReceived(0); + } + + public void testGetRestrictBackgroundStatus_whitelisted() throws Exception { + setRestrictBackground(true); + assertRestrictBackgroundChangedReceived(1); + + addRestrictBackgroundWhitelist(mUid); + assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_WHITELISTED); + assertRestrictBackgroundChangedReceived(2); + } + + public void testGetRestrictBackgroundStatus_enabled() throws Exception { + setRestrictBackground(true); + assertRestrictBackgroundChangedReceived(1); + + removeRestrictBackgroundWhitelist(mUid); + assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); + assertRestrictBackgroundChangedReceived(1); + } +} diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java index f2c3b1f7d2..21e5aa7f48 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java @@ -40,17 +40,17 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC } public void testGetRestrictBackgroundStatus_disabled() throws Exception { - runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", + runDeviceTests(TEST_PKG, TEST_PKG + ".DataSaverModeTest", "testGetRestrictBackgroundStatus_disabled"); } public void testGetRestrictBackgroundStatus_whitelisted() throws Exception { - runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", + runDeviceTests(TEST_PKG, TEST_PKG + ".DataSaverModeTest", "testGetRestrictBackgroundStatus_whitelisted"); } public void testGetRestrictBackgroundStatus_enabled() throws Exception { - runDeviceTests(TEST_PKG, TEST_PKG + ".ConnectivityManagerTest", + runDeviceTests(TEST_PKG, TEST_PKG + ".DataSaverModeTest", "testGetRestrictBackgroundStatus_enabled"); } From 31c9ec9cb4d42cb5bd7bbd7d0a287d9d8e35f481 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Tue, 23 Feb 2016 11:24:54 -0800 Subject: [PATCH 0211/1109] Added CTS tests to check background network access while on power save mode. BUG: 27127112 Change-Id: Ifa3019d7b94459d737a9dff80b4b36a2dd43aca5 --- ...ractRestrictBackgroundNetworkTestCase.java | 116 +++++++++++++++--- .../net/hostside/BatterySaverModeTest.java | 55 +++++++++ .../cts/net/hostside/DataSaverModeTest.java | 7 ++ .../hostside/app2/MyBroadcastReceiver.java | 5 +- ...ostsideRestrictBackgroundNetworkTests.java | 62 +++++++++- 5 files changed, 224 insertions(+), 21 deletions(-) create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 59de7593b2..3f80b5a406 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -22,7 +22,6 @@ import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLE import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; -import java.io.IOException; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; @@ -42,7 +41,8 @@ import android.util.Log; abstract class AbstractRestrictBackgroundNetworkTestCase extends InstrumentationTestCase { protected static final String TAG = "RestrictBackgroundNetworkTests"; - private static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2"; + protected static final String TEST_PKG = "com.android.cts.net.hostside"; + protected static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2"; private static final int SLEEP_TIME_SEC = 1; private static final boolean DEBUG = true; @@ -60,6 +60,10 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation private static final String RESULT_SEPARATOR = ";"; private static final String STATUS_NETWORK_UNAVAILABLE_PREFIX = "NetworkUnavailable:"; private static final String STATUS_NETWORK_AVAILABLE_PREFIX = "NetworkAvailable:"; + private static final int NETWORK_TIMEOUT_MS = 15 * 1000; + + // Must be higher than NETWORK_TIMEOUT_MS + private static final int ORDERED_BROADCAST_TIMEOUT_MS = NETWORK_TIMEOUT_MS * 4; protected Context mContext; protected Instrumentation mInstrumentation; @@ -134,8 +138,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation } }, null, 0, null, null); - final String resultData = result.poll(60, TimeUnit.SECONDS); - assertNotNull("timeout waiting for ordered broadcast result", resultData); + final String resultData = result.poll(ORDERED_BROADCAST_TIMEOUT_MS, TimeUnit.MILLISECONDS); Log.d(TAG, "Ordered broadcast response: " + resultData); return resultData; } @@ -145,6 +148,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation intent.putExtra(EXTRA_ACTION, ACTION_RESTRICT_BACKGROUND_CHANGED); intent.putExtra(EXTRA_RECEIVER_NAME, receiverName); final String resultData = sendOrderedBroadcast(intent); + assertNotNull("timeout waiting for ordered broadcast result", resultData); return Integer.valueOf(resultData); } @@ -153,25 +157,73 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation final String resultData = sendOrderedBroadcast(intent); final String[] resultItems = resultData.split(RESULT_SEPARATOR); final String actualApiStatus = toString(Integer.parseInt(resultItems[0])); - final String actualNetworkStatus = resultItems[1]; - // First asserts the API returns the proper value... assertEquals("wrong status", toString(expectedApiStatus), actualApiStatus); //...then the actual network status in the background thread. - final String expectedPrefix = expectedApiStatus == RESTRICT_BACKGROUND_STATUS_ENABLED ? - STATUS_NETWORK_UNAVAILABLE_PREFIX : STATUS_NETWORK_AVAILABLE_PREFIX; - assertTrue("Wrong network status for API status " + actualApiStatus + ": " - + actualNetworkStatus, actualNetworkStatus.startsWith(expectedPrefix)); + final String networkStatus = getNetworkStatus(resultItems); + assertNetworkStatus(expectedApiStatus != RESTRICT_BACKGROUND_STATUS_ENABLED, networkStatus); } - protected String executeShellCommand(String command) throws IOException { + protected void assertBackgroundNetworkAccess(boolean expectAllowed) throws Exception { + final Intent intent = new Intent(ACTION_CHECK_NETWORK); + final String resultData = sendOrderedBroadcast(intent); + final String[] resultItems = resultData.split(RESULT_SEPARATOR); + final String networkStatus = getNetworkStatus(resultItems); + assertNetworkStatus(expectAllowed, networkStatus); + } + + private String getNetworkStatus(String[] resultItems) { + return resultItems.length < 2 ? null : resultItems[1]; + } + + private void assertNetworkStatus(boolean expectAvailable, String status) throws Exception { + if (status == null) { + Log.d(TAG, "timeout waiting for ordered broadcast"); + if (expectAvailable) { + fail("did not get network status when access was allowed"); + } + return; + } + final String expectedPrefix = expectAvailable ? + STATUS_NETWORK_AVAILABLE_PREFIX : STATUS_NETWORK_UNAVAILABLE_PREFIX; + assertTrue("Wrong network status (" + status + ") when expectedAvailable is " + + expectAvailable, status.startsWith(expectedPrefix)); + } + + protected String executeShellCommand(String command) throws Exception { final String result = runShellCommand(mInstrumentation, command).trim(); if (DEBUG) Log.d(TAG, "Command '" + command + "' returned '" + result + "'"); return result; } - protected void setMeteredNetwork() throws IOException { + /** + * Runs a Shell command which is not expected to generate output. + */ + protected void executeSilentShellCommand(String command) throws Exception { + final String result = executeShellCommand(command); + assertTrue("Command '" + command + "' failed: " + result, result.trim().isEmpty()); + } + + /** + * Asserts the result of a command, wait and re-running it a couple times if necessary. + */ + protected void assertDelayedShellCommand(String command, String expectedResult) + throws Exception { + final int maxTries = 5; + for (int i = 1; i <= maxTries; i++) { + final String result = executeShellCommand(command).trim(); + if (result.equals(expectedResult)) + return; + Log.v(TAG, "Command '" + command + "' returned '" + result + " instead of '" + + expectedResult + "' on attempt #; sleeping 1s before polling again"); + Thread.sleep(1000); + } + fail("Command '" + command + "' did not return '" + expectedResult + "' after " + maxTries + + " attempts"); + } + + protected void setMeteredNetwork() throws Exception { final NetworkInfo info = mCm.getActiveNetworkInfo(); final boolean metered = mCm.isActiveNetworkMetered(); if (metered) { @@ -185,7 +237,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation mResetMeteredWifi = true; } - protected String setWifiMeteredStatus(boolean metered) throws IOException { + protected String setWifiMeteredStatus(boolean metered) throws Exception { mWfm.setWifiEnabled(true); // TODO: if it's not guaranteed the device has wi-fi, we need to change the tests // to make the actual verification of restrictions optional. @@ -206,7 +258,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation return netId; } - protected void setRestrictBackground(boolean enabled) throws IOException { + protected void setRestrictBackground(boolean enabled) throws Exception { executeShellCommand("cmd netpolicy set restrict-background " + enabled); final String output = executeShellCommand("cmd netpolicy get restrict-background "); final String expectedSuffix = enabled ? "enabled" : "disabled"; @@ -242,6 +294,40 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation fail("whitelist check for uid " + uid + " failed: expected " + expected + ", got " + actual); } + protected void assertPowerSaveModeWhitelist(String packageName, boolean expected) + throws Exception { + // TODO: currently the power-save mode is behaving like idle, but once it changes, we'll + // need to use netpolicy for whitelisting + assertDelayedShellCommand("dumpsys deviceidle whitelist =" + packageName, + Boolean.toString(expected)); + } + + protected void addPowerSaveModeWhitelist(String packageName) throws Exception { + Log.i(TAG, "Adding package " + packageName + " to power-save-mode whitelist"); + // TODO: currently the power-save mode is behaving like idle, but once it changes, we'll + // need to use netpolicy for whitelisting + executeShellCommand("dumpsys deviceidle whitelist +" + packageName); + assertPowerSaveModeWhitelist(packageName, true); // Sanity check + } + + protected void removePowerSaveModeWhitelist(String packageName) throws Exception { + Log.i(TAG, "Removing package " + packageName + " from power-save-mode whitelist"); + // TODO: currently the power-save mode is behaving like idle, but once it changes, we'll + // need to use netpolicy for whitelisting + executeShellCommand("dumpsys deviceidle whitelist -" + packageName); + assertPowerSaveModeWhitelist(packageName, false); // Sanity check + } + + protected void setPowerSaveMode(boolean enabled) throws Exception { + Log.i(TAG, "Setting power mode to " + enabled); + if (enabled) { + executeSilentShellCommand("cmd battery unplug"); + executeSilentShellCommand("settings put global low_power 1"); + } else { + executeSilentShellCommand("cmd battery reset"); + } + } + /** * Starts a service that will register a broadcast receiver to receive * {@code RESTRICT_BACKGROUND_CHANGE} intents. @@ -249,7 +335,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation * The service must run in a separate app because otherwise it would be killed every time * {@link #runDeviceTests(String, String)} is executed. */ - protected void registerApp2BroadcastReceiver() throws IOException { + protected void registerApp2BroadcastReceiver() throws Exception { executeShellCommand("am startservice com.android.cts.net.hostside.app2/.MyService"); } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java new file mode 100644 index 0000000000..29a0309bd1 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2016 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.cts.net.hostside; + +public class BatterySaverModeTest extends AbstractRestrictBackgroundNetworkTestCase { + + @Override + public void setUp() throws Exception { + super.setUp(); + + setPowerSaveMode(false); + assertPowerSaveModeWhitelist(TEST_APP2_PKG, false); // Sanity check + registerApp2BroadcastReceiver(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + + setPowerSaveMode(false); + } + + public void testBackgroundNetworkAccess_enabled() throws Exception { + setPowerSaveMode(true); + assertBackgroundNetworkAccess(false); + } + + public void testBackgroundNetworkAccess_whitelisted() throws Exception { + setPowerSaveMode(true); + assertBackgroundNetworkAccess(false); + addPowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(true); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + } + + public void testBackgroundNetworkAccess_disabled() throws Exception { + setPowerSaveMode(false); + assertBackgroundNetworkAccess(true); + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index c62189ed23..ccb1fe9600 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -30,6 +30,13 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase registerApp2BroadcastReceiver(); } + @Override + protected void tearDown() throws Exception { + super.tearDown(); + + setRestrictBackground(false); + } + public void testGetRestrictBackgroundStatus_disabled() throws Exception { removeRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java index 65c7b6009d..f32bd44d79 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java @@ -110,7 +110,10 @@ public class MyBroadcastReceiver extends BroadcastReceiver { setResultData(null); return; } - data.append(apiStatus).append(RESULT_SEPARATOR).append(netStatus); + data.append(apiStatus).append(RESULT_SEPARATOR); + if (netStatus != null) { + data.append(netStatus); + } Log.d(TAG, "checkNetwork: returning " + data); setResultData(data.toString()); } diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java index 21e5aa7f48..4786450c42 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java @@ -17,6 +17,7 @@ package com.android.cts.net; import com.android.ddmlib.Log; +import com.android.tradefed.device.DeviceNotAvailableException; public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestCase { @@ -39,24 +40,24 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC uninstallPackage(TEST_APP2_PKG, true); } - public void testGetRestrictBackgroundStatus_disabled() throws Exception { + public void testDataSaverMode_disabled() throws Exception { runDeviceTests(TEST_PKG, TEST_PKG + ".DataSaverModeTest", "testGetRestrictBackgroundStatus_disabled"); } - public void testGetRestrictBackgroundStatus_whitelisted() throws Exception { + public void testDataSaverMode_whitelisted() throws Exception { runDeviceTests(TEST_PKG, TEST_PKG + ".DataSaverModeTest", "testGetRestrictBackgroundStatus_whitelisted"); } - public void testGetRestrictBackgroundStatus_enabled() throws Exception { + public void testDataSaverMode_enabled() throws Exception { runDeviceTests(TEST_PKG, TEST_PKG + ".DataSaverModeTest", "testGetRestrictBackgroundStatus_enabled"); } - public void testGetRestrictBackgroundStatus_uninstall() throws Exception { + public void testDataSaverMode_reinstall() throws Exception { final int oldUid = getUid(TEST_PKG); - testGetRestrictBackgroundStatus_whitelisted(); + testDataSaverMode_whitelisted(); uninstallPackage(TEST_PKG, true); assertPackageUninstalled(TEST_PKG); @@ -68,6 +69,32 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC assertRestrictBackgroundWhitelist(newUid, false); } + public void testBatterySaverMode_disabled() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeTest", + "testBackgroundNetworkAccess_disabled"); + } + + public void testBatterySaverMode_whitelisted() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeTest", + "testBackgroundNetworkAccess_whitelisted"); + } + + public void testBatterySaverMode_enabled() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeTest", + "testBackgroundNetworkAccess_enabled"); + } + + public void testBatterySaverMode_reinstall() throws Exception { + testBatterySaverMode_whitelisted(); + + uninstallPackage(TEST_PKG, true); + assertPackageUninstalled(TEST_PKG); + assertPowerSaveModeWhitelist(TEST_PKG, false); + + installPackage(TEST_APK); + assertPowerSaveModeWhitelist(TEST_PKG, false); + } + private void assertRestrictBackgroundWhitelist(int uid, boolean expected) throws Exception { final int max_tries = 5; boolean actual = false; @@ -84,4 +111,29 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC fail("whitelist check for uid " + uid + " failed: expected " + expected + ", got " + actual); } + + private void assertPowerSaveModeWhitelist(String packageName, boolean expected) + throws Exception { + // TODO: currently the power-save mode is behaving like idle, but once it changes, we'll + // need to use netpolicy for whitelisting + assertDelayedCommand("dumpsys deviceidle whitelist =" + packageName, + Boolean.toString(expected)); + } + + /** + * Asserts the result of a command, wait and re-running it a couple times if necessary. + */ + private void assertDelayedCommand(String command, String expectedResult) + throws InterruptedException, DeviceNotAvailableException { + final int maxTries = 5; + for (int i = 1; i <= maxTries; i++) { + final String result = runCommand(command).trim(); + if (result.equals(expectedResult)) return; + Log.v(TAG, "Command '" + command + "' returned '" + result + " instead of '" + + expectedResult + "' on attempt #; sleeping 1s before polling again"); + Thread.sleep(1000); + } + fail("Command '" + command + "' did not return '" + expectedResult + "' after " + maxTries + + " attempts"); + } } From 4b05fbd1e7201b15aba4b9ac490a3cc065004147 Mon Sep 17 00:00:00 2001 From: Edward Savage-Jones Date: Thu, 25 Feb 2016 00:36:09 +0100 Subject: [PATCH 0212/1109] Swapped memset params memset bug Change-Id: Icf173de400ae1cfcffd590b3fb789c54f6a55bae --- tests/cts/net/jni/NativeDnsJni.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/jni/NativeDnsJni.c b/tests/cts/net/jni/NativeDnsJni.c index 4eb3c7aebc..352c0c52cc 100644 --- a/tests/cts/net/jni/NativeDnsJni.c +++ b/tests/cts/net/jni/NativeDnsJni.c @@ -126,7 +126,7 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas return JNI_FALSE; } - memset(buf, sizeof(buf), 0); + memset(buf, 0, sizeof(buf)); res = getnameinfo((const struct sockaddr*)&sa6, sizeof(sa6), buf, sizeof(buf), NULL, 0, flags); if (res != 0) { ALOGD("getnameinfo(%s (GoogleDNS) ) gave error %d (%s)", GoogleDNSIpV6Address2, From a9e563cf831498fd7d0788610ca22e0c64815d9b Mon Sep 17 00:00:00 2001 From: Stuart Scott Date: Thu, 18 Feb 2016 19:25:52 -0800 Subject: [PATCH 0213/1109] Switch to CTSv2 bug:21762834 Change-Id: Ie51a0ed4560b46c2f360e14980e5fab7fe6479fe --- tests/cts/hostside/Android.mk | 6 +++--- tests/cts/hostside/app/Android.mk | 4 ++-- tests/cts/net/Android.mk | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/cts/hostside/Android.mk b/tests/cts/hostside/Android.mk index b4e1e3dafe..ad97ecdc6b 100644 --- a/tests/cts/hostside/Android.mk +++ b/tests/cts/hostside/Android.mk @@ -21,14 +21,14 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_MODULE := CtsHostsideNetworkTests -LOCAL_JAVA_LIBRARIES := cts-tradefed_v2 compatibility-host-util tradefed-prebuilt +LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt LOCAL_STATIC_JAVA_LIBRARIES := cts-migration-lib LOCAL_CTS_TEST_PACKAGE := android.net.hostsidenetwork -# Tag this module as a cts_v2 test artifact -LOCAL_COMPATIBILITY_SUITE := cts_v2 +# Tag this module as a cts test artifact +LOCAL_COMPATIBILITY_SUITE := cts include $(BUILD_CTS_HOST_JAVA_LIBRARY) diff --git a/tests/cts/hostside/app/Android.mk b/tests/cts/hostside/app/Android.mk index b64c4c95f2..7f8da07943 100644 --- a/tests/cts/hostside/app/Android.mk +++ b/tests/cts/hostside/app/Android.mk @@ -29,7 +29,7 @@ LOCAL_PACKAGE_NAME := CtsHostsideNetworkTestsApp LOCAL_PROGUARD_ENABLED := disabled LOCAL_DEX_PREOPT := false -# Tag this module as a cts_v2 test artifact -LOCAL_COMPATIBILITY_SUITE := cts_v2 +# Tag this module as a cts test artifact +LOCAL_COMPATIBILITY_SUITE := cts include $(BUILD_CTS_SUPPORT_PACKAGE) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index 608ea47bc7..c553a9bb2e 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -40,8 +40,8 @@ LOCAL_STATIC_JAVA_LIBRARIES := core-tests-support ctsdeviceutil \ # uncomment when b/13249961 is fixed #LOCAL_SDK_VERSION := current -# Tag this module as a cts_v2 test artifact -LOCAL_COMPATIBILITY_SUITE := cts_v2 +# Tag this module as a cts test artifact +LOCAL_COMPATIBILITY_SUITE := cts include $(BUILD_CTS_PACKAGE) From d207fe5bebdba93d0d65a54dadaa45dea33b6023 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Tue, 1 Mar 2016 16:31:58 -0800 Subject: [PATCH 0214/1109] Tagged app2 as a CTS test artifact. BUG: 27436960 Change-Id: I4e97b6341dae3361f4efdaec3132a7aa9a38dece --- tests/cts/hostside/app2/Android.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/cts/hostside/app2/Android.mk b/tests/cts/hostside/app2/Android.mk index e330bf7508..3b59f8f6ce 100644 --- a/tests/cts/hostside/app2/Android.mk +++ b/tests/cts/hostside/app2/Android.mk @@ -28,4 +28,7 @@ LOCAL_PACKAGE_NAME := CtsHostsideNetworkTestsApp2 LOCAL_PROGUARD_ENABLED := disabled LOCAL_DEX_PREOPT := false +# Tag this module as a cts test artifact +LOCAL_COMPATIBILITY_SUITE := cts + include $(BUILD_CTS_SUPPORT_PACKAGE) From 37c0bf0477fe4f087ae0b65152f3459ed267193b Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Tue, 1 Mar 2016 13:53:27 -0800 Subject: [PATCH 0215/1109] Added CTS tests for apps that are blacklisted for restricted background data. BUG: 27432317 Change-Id: Ie9156ab4f2fa7c639d8e9a978954e09b322d6187 --- ...ractRestrictBackgroundNetworkTestCase.java | 54 ++++++++++++++++--- .../cts/net/hostside/DataSaverModeTest.java | 24 +++++++++ .../android/cts/net/hostside/app2/Common.java | 5 +- .../hostside/app2/MyBroadcastReceiver.java | 6 +++ .../cts/net/hostside/app2/MyService.java | 10 +++- ...ostsideRestrictBackgroundNetworkTests.java | 5 ++ 6 files changed, 93 insertions(+), 11 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 3f80b5a406..73a5d57e42 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -54,13 +54,16 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation "com.android.cts.net.hostside.app2.action.GET_COUNTERS"; private static final String ACTION_CHECK_NETWORK = "com.android.cts.net.hostside.app2.action.CHECK_NETWORK"; + private static final String ACTION_RECEIVER_READY = + "com.android.cts.net.hostside.app2.action.RECEIVER_READY"; private static final String EXTRA_ACTION = "com.android.cts.net.hostside.app2.extra.ACTION"; private static final String EXTRA_RECEIVER_NAME = "com.android.cts.net.hostside.app2.extra.RECEIVER_NAME"; private static final String RESULT_SEPARATOR = ";"; private static final String STATUS_NETWORK_UNAVAILABLE_PREFIX = "NetworkUnavailable:"; private static final String STATUS_NETWORK_AVAILABLE_PREFIX = "NetworkAvailable:"; - private static final int NETWORK_TIMEOUT_MS = 15 * 1000; + private static final int SECOND_IN_MS = 1000; + private static final int NETWORK_TIMEOUT_MS = 15 * SECOND_IN_MS; // Must be higher than NETWORK_TIMEOUT_MS private static final int ORDERED_BROADCAST_TIMEOUT_MS = NETWORK_TIMEOUT_MS * 4; @@ -116,13 +119,17 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation Log.d(TAG, "Expecting count " + expectedCount + " but actual is " + count + " after " + attempts + " attempts; sleeping " + SLEEP_TIME_SEC + " seconds before trying again"); - Thread.sleep(SLEEP_TIME_SEC * 1000); + Thread.sleep(SLEEP_TIME_SEC * SECOND_IN_MS); } while (attempts <= maxAttempts); assertEquals("Number of expected broadcasts for " + receiverName + " not reached after " + maxAttempts * SLEEP_TIME_SEC + " seconds", expectedCount, count); } protected String sendOrderedBroadcast(Intent intent) throws Exception { + return sendOrderedBroadcast(intent, ORDERED_BROADCAST_TIMEOUT_MS); + } + + protected String sendOrderedBroadcast(Intent intent, int timeoutMs) throws Exception { final LinkedBlockingQueue result = new LinkedBlockingQueue<>(1); Log.d(TAG, "Sending ordered broadcast: " + intent); mContext.sendOrderedBroadcast(intent, null, new BroadcastReceiver() { @@ -138,7 +145,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation } }, null, 0, null, null); - final String resultData = result.poll(ORDERED_BROADCAST_TIMEOUT_MS, TimeUnit.MILLISECONDS); + final String resultData = result.poll(timeoutMs, TimeUnit.MILLISECONDS); Log.d(TAG, "Ordered broadcast response: " + resultData); return resultData; } @@ -217,7 +224,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation return; Log.v(TAG, "Command '" + command + "' returned '" + result + " instead of '" + expectedResult + "' on attempt #; sleeping 1s before polling again"); - Thread.sleep(1000); + Thread.sleep(SECOND_IN_MS); } fail("Command '" + command + "' did not return '" + expectedResult + "' after " + maxTries + " attempts"); @@ -278,20 +285,38 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation } protected void assertRestrictBackgroundWhitelist(int uid, boolean expected) throws Exception { + assertRestrictBackground("restrict-background-whitelist", uid, expected); + } + + protected void addRestrictBackgroundBlacklist(int uid) throws Exception { + executeShellCommand("cmd netpolicy add restrict-background-blacklist " + uid); + assertRestrictBackgroundBlacklist(uid, true); + } + + protected void removeRestrictBackgroundBlacklist(int uid) throws Exception { + executeShellCommand("cmd netpolicy remove restrict-background-blacklist " + uid); + assertRestrictBackgroundBlacklist(uid, false); + } + + protected void assertRestrictBackgroundBlacklist(int uid, boolean expected) throws Exception { + assertRestrictBackground("restrict-background-blacklist", uid, expected); + } + + private void assertRestrictBackground(String list, int uid, boolean expected) throws Exception { final int maxTries = 5; boolean actual = false; for (int i = 1; i <= maxTries; i++) { final String output = - executeShellCommand("cmd netpolicy list restrict-background-whitelist "); + executeShellCommand("cmd netpolicy list " + list); actual = output.contains(Integer.toString(uid)); if (expected == actual) { return; } - Log.v(TAG, "whitelist check for uid " + uid + " doesn't match yet (expected " + Log.v(TAG, list + " check for uid " + uid + " doesn't match yet (expected " + expected + ", got " + actual + "); sleeping 1s before polling again"); - Thread.sleep(1000); + Thread.sleep(SECOND_IN_MS); } - fail("whitelist check for uid " + uid + " failed: expected " + expected + ", got " + actual); + fail(list + " check for uid " + uid + " failed: expected " + expected + ", got " + actual); } protected void assertPowerSaveModeWhitelist(String packageName, boolean expected) @@ -337,6 +362,19 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation */ protected void registerApp2BroadcastReceiver() throws Exception { executeShellCommand("am startservice com.android.cts.net.hostside.app2/.MyService"); + // Wait until receiver is ready. + final int maxTries = 5; + for (int i = 1; i <= maxTries; i++) { + final String message = + sendOrderedBroadcast(new Intent(ACTION_RECEIVER_READY), SECOND_IN_MS); + Log.d(TAG, "app2 receiver acked: " + message); + if (message != null) { + return; + } + Log.v(TAG, "app2 receiver is not ready yet; sleeping 1s before polling again"); + Thread.sleep(SECOND_IN_MS); + } + fail("app2 receiver is not ready"); } private String toString(int status) { diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index ccb1fe9600..61593a1226 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -65,4 +65,28 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); assertRestrictBackgroundChangedReceived(1); } + + public void testGetRestrictBackgroundStatus_blacklisted() throws Exception { + addRestrictBackgroundBlacklist(mUid); + assertRestrictBackgroundChangedReceived(1); + + assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); + + // TODO: currently whitelist is prevailing, hence remaining of the test below is disabled + if (true) return; + + // Make sure blacklist prevails over whitelist. + setRestrictBackground(true); + assertRestrictBackgroundChangedReceived(2); + addRestrictBackgroundWhitelist(mUid); + assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); + + // Check status after removing blacklist. + removeRestrictBackgroundBlacklist(mUid); + assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_WHITELISTED); + assertRestrictBackgroundChangedReceived(3); + setRestrictBackground(false); + assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + assertRestrictBackgroundChangedReceived(4); + } } diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java index 3be4261258..f5f5fafa31 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java @@ -19,13 +19,16 @@ public final class Common { static final String TAG = "CtsNetApp2"; - // Constants below must match values defined on app's ConnectivityManagerTest.java + // Constants below must match values defined on app's + // AbstractRestrictBackgroundNetworkTestCase.java static final String MANIFEST_RECEIVER = "ManifestReceiver"; static final String DYNAMIC_RECEIVER = "DynamicReceiver"; static final String ACTION_GET_COUNTERS = "com.android.cts.net.hostside.app2.action.GET_COUNTERS"; static final String ACTION_CHECK_NETWORK = "com.android.cts.net.hostside.app2.action.CHECK_NETWORK"; + static final String ACTION_RECEIVER_READY = + "com.android.cts.net.hostside.app2.action.RECEIVER_READY"; static final String EXTRA_ACTION = "com.android.cts.net.hostside.app2.extra.ACTION"; static final String EXTRA_RECEIVER_NAME = "com.android.cts.net.hostside.app2.extra.RECEIVER_NAME"; diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java index f32bd44d79..94ec6af7ee 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java @@ -19,6 +19,7 @@ package com.android.cts.net.hostside.app2; import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; import static com.android.cts.net.hostside.app2.Common.ACTION_CHECK_NETWORK; import static com.android.cts.net.hostside.app2.Common.ACTION_GET_COUNTERS; +import static com.android.cts.net.hostside.app2.Common.ACTION_RECEIVER_READY; import static com.android.cts.net.hostside.app2.Common.EXTRA_ACTION; import static com.android.cts.net.hostside.app2.Common.EXTRA_RECEIVER_NAME; import static com.android.cts.net.hostside.app2.Common.MANIFEST_RECEIVER; @@ -76,6 +77,11 @@ public class MyBroadcastReceiver extends BroadcastReceiver { case ACTION_CHECK_NETWORK: checkNetwork(context, intent); break; + case ACTION_RECEIVER_READY: + final String message = mName + " is ready to rumble"; + Log.d(TAG, message); + setResultData(message); + break; default: Log.e(TAG, "received unexpected action: " + action); } diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java index 882bb62c2c..55249f2208 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java @@ -16,9 +16,12 @@ package com.android.cts.net.hostside.app2; import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; +import static com.android.cts.net.hostside.app2.Common.ACTION_RECEIVER_READY; import static com.android.cts.net.hostside.app2.Common.DYNAMIC_RECEIVER; import static com.android.cts.net.hostside.app2.Common.TAG; + import android.app.Service; +import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.IBinder; @@ -37,8 +40,11 @@ public class MyService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "onStartCommand: " + intent); - getApplicationContext().registerReceiver(new MyBroadcastReceiver(DYNAMIC_RECEIVER), - new IntentFilter(ACTION_RESTRICT_BACKGROUND_CHANGED)); + final Context context = getApplicationContext(); + final MyBroadcastReceiver myReceiver = new MyBroadcastReceiver(DYNAMIC_RECEIVER); + context.registerReceiver(myReceiver, new IntentFilter(ACTION_RECEIVER_READY)); + context.registerReceiver(myReceiver, new IntentFilter(ACTION_RESTRICT_BACKGROUND_CHANGED)); + Log.d(TAG, "receiver registered"); return START_STICKY; } } diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java index 4786450c42..eade26184d 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java @@ -55,6 +55,11 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC "testGetRestrictBackgroundStatus_enabled"); } + public void testDataSaverMode_blacklisted() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".DataSaverModeTest", + "testGetRestrictBackgroundStatus_blacklisted"); + } + public void testDataSaverMode_reinstall() throws Exception { final int oldUid = getUid(TEST_PKG); testDataSaverMode_whitelisted(); From d7f1dbef6694f4389d0df76ed292b84f746b4ae0 Mon Sep 17 00:00:00 2001 From: Wally Yau Date: Mon, 7 Mar 2016 16:16:09 -0800 Subject: [PATCH 0216/1109] Fixed test for lingering traffic data. Change-Id: I7d68a518e25e17dbbaa57b12e2af4dc57b8df8d3 --- tests/cts/net/src/android/net/cts/TrafficStatsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java index 5b93beead5..a8dd8acecc 100755 --- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java +++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java @@ -215,7 +215,7 @@ public class TrafficStatsTest extends AndroidTestCase { if (deltaTxOtherPackets > 0 || deltaRxOtherPackets > 0) { Log.i(LOG_TAG, "lingering traffic data: " + deltaTxOtherPackets + "/" + deltaRxOtherPackets); // Make sure that not too many non-localhost packets are accounted for - assertTrue("too many non-localhost packets on the sam UID", deltaTxOtherPackets + deltaTxOtherPackets < 20); + assertTrue("too many non-localhost packets on the same UID", deltaTxOtherPackets + deltaRxOtherPackets < 20); } assertTrue("uidtxp: " + uidTxPacketsBefore + " -> " + uidTxPacketsAfter + " delta=" + uidTxDeltaPackets + From b3cc6ef3ae22dcee15910db24e840edcd0931acd Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Mon, 7 Mar 2016 15:20:58 -0800 Subject: [PATCH 0217/1109] Added tests for battery save mode on non-metered networks. BUG: 27127112 Change-Id: I4a05194a32294d15badfaa4156606e728f943a9a --- ...ractRestrictBackgroundNetworkTestCase.java | 2 - .../BatterySaverModeNonMeteredTest.java | 56 +++++++++++++++++++ .../net/hostside/BatterySaverModeTest.java | 2 + .../cts/net/hostside/DataSaverModeTest.java | 1 + ...ostsideRestrictBackgroundNetworkTests.java | 15 +++++ 5 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 73a5d57e42..def3439eef 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -87,8 +87,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation .getPackageInfo(mContext.getPackageName(), 0).applicationInfo.uid; Log.d(TAG, "UIDS: test app=" + myUid + ", app2=" + mUid); - - setMeteredNetwork(); } @Override diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java new file mode 100644 index 0000000000..5181057d85 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2016 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.cts.net.hostside; + +//TODO: move this and BatterySaverModeTest's logic into a common superclass +public class BatterySaverModeNonMeteredTest extends AbstractRestrictBackgroundNetworkTestCase { + + @Override + public void setUp() throws Exception { + super.setUp(); + + setPowerSaveMode(false); + assertPowerSaveModeWhitelist(TEST_APP2_PKG, false); // Sanity check + registerApp2BroadcastReceiver(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + + setPowerSaveMode(false); + } + + public void testBackgroundNetworkAccess_enabled() throws Exception { + setPowerSaveMode(true); + assertBackgroundNetworkAccess(false); + } + + public void testBackgroundNetworkAccess_whitelisted() throws Exception { + setPowerSaveMode(true); + assertBackgroundNetworkAccess(false); + addPowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(true); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + } + + public void testBackgroundNetworkAccess_disabled() throws Exception { + setPowerSaveMode(false); + assertBackgroundNetworkAccess(true); + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java index 29a0309bd1..18e2b3e054 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java @@ -16,12 +16,14 @@ package com.android.cts.net.hostside; +//TODO: move this and BatterySaverModeNonMeteredTest's logic into a common superclass public class BatterySaverModeTest extends AbstractRestrictBackgroundNetworkTestCase { @Override public void setUp() throws Exception { super.setUp(); + setMeteredNetwork(); setPowerSaveMode(false); assertPowerSaveModeWhitelist(TEST_APP2_PKG, false); // Sanity check registerApp2BroadcastReceiver(); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index 61593a1226..b9fca39312 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -26,6 +26,7 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase public void setUp() throws Exception { super.setUp(); + setMeteredNetwork(); setRestrictBackground(false); registerApp2BroadcastReceiver(); } diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java index eade26184d..2bd76e6c93 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java @@ -100,6 +100,21 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC assertPowerSaveModeWhitelist(TEST_PKG, false); } + public void testBatteryBatterySaverModeNonMeteredTest_disabled() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeNonMeteredTest", + "testBackgroundNetworkAccess_disabled"); + } + + public void testBatteryBatterySaverModeNonMeteredTest_whitelisted() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeNonMeteredTest", + "testBackgroundNetworkAccess_whitelisted"); + } + + public void testBatteryBatterySaverModeNonMeteredTest_enabled() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeNonMeteredTest", + "testBackgroundNetworkAccess_enabled"); + } + private void assertRestrictBackgroundWhitelist(int uid, boolean expected) throws Exception { final int max_tries = 5; boolean actual = false; From f448ccd08d7795b319ca00985a2fed54947f65be Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Wed, 9 Mar 2016 12:28:36 -0800 Subject: [PATCH 0218/1109] Print uid when running network checks. BUG: 27570398 Change-Id: I4dcbd4e41641c406c687a0e29e2637581d91b17c --- .../com/android/cts/net/hostside/app2/Common.java | 13 +++++++++++++ .../cts/net/hostside/app2/MyBroadcastReceiver.java | 12 ++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java index f5f5fafa31..668669bc2e 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java @@ -15,6 +15,10 @@ */ package com.android.cts.net.hostside.app2; +import android.content.Context; +import android.content.pm.PackageManager.NameNotFoundException; +import android.util.Log; + public final class Common { static final String TAG = "CtsNetApp2"; @@ -35,4 +39,13 @@ public final class Common { static final char RESULT_SEPARATOR = ';'; static final String STATUS_NETWORK_UNAVAILABLE_PREFIX = "NetworkUnavailable:"; static final String STATUS_NETWORK_AVAILABLE_PREFIX = "NetworkAvailable:"; + + static int getUid(Context context) { + final String packageName = context.getPackageName(); + try { + return context.getPackageManager().getPackageUid(packageName, 0); + } catch (NameNotFoundException e) { + throw new IllegalStateException("Could not get UID for " + packageName, e); + } + } } diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java index 94ec6af7ee..07f717b192 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java @@ -27,6 +27,7 @@ import static com.android.cts.net.hostside.app2.Common.RESULT_SEPARATOR; import static com.android.cts.net.hostside.app2.Common.STATUS_NETWORK_AVAILABLE_PREFIX; import static com.android.cts.net.hostside.app2.Common.STATUS_NETWORK_UNAVAILABLE_PREFIX; import static com.android.cts.net.hostside.app2.Common.TAG; +import static com.android.cts.net.hostside.app2.Common.getUid; import java.net.HttpURLConnection; import java.net.URL; @@ -110,7 +111,7 @@ public class MyBroadcastReceiver extends BroadcastReceiver { final int apiStatus = cm.getRestrictBackgroundStatus(); String netStatus; try { - netStatus = checkNetworkStatus(cm); + netStatus = checkNetworkStatus(context, cm); } catch (InterruptedException e) { Log.e(TAG, "Timeout checking network status"); setResultData(null); @@ -124,7 +125,8 @@ public class MyBroadcastReceiver extends BroadcastReceiver { setResultData(data.toString()); } - private String checkNetworkStatus(final ConnectivityManager cm) throws InterruptedException { + private String checkNetworkStatus(final Context context, final ConnectivityManager cm) + throws InterruptedException { final LinkedBlockingQueue result = new LinkedBlockingQueue<>(1); new Thread(new Runnable() { @@ -134,7 +136,7 @@ public class MyBroadcastReceiver extends BroadcastReceiver { final String address = "http://example.com"; final NetworkInfo networkInfo = cm.getActiveNetworkInfo(); Log.d(TAG, "Running checkNetworkStatus() on thread " - + Thread.currentThread().getName() + + Thread.currentThread().getName() + " for UID " + getUid(context) + "\n\tactiveNetworkInfo: " + networkInfo + "\n\tURL: " + address); String prefix = STATUS_NETWORK_AVAILABLE_PREFIX; try { @@ -151,7 +153,9 @@ public class MyBroadcastReceiver extends BroadcastReceiver { Log.d(TAG, "Exception getting " + address + ": " + e); prefix = STATUS_NETWORK_UNAVAILABLE_PREFIX + "Exception " + e + ":"; } - result.offer(prefix + networkInfo); + final String netInfo = prefix + networkInfo; + Log.d(TAG, "Offering " + netInfo); + result.offer(netInfo); } }, mName).start(); return result.poll(NETWORK_TIMEOUT_MS * 2, TimeUnit.MILLISECONDS); From 2bbc892a8081a59e434c423c5e6c9d6bb6651907 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Mon, 14 Mar 2016 12:07:07 -0700 Subject: [PATCH 0219/1109] Wifi Cts: Set 'disableOthers' flag in enableNetwork Wifi framework only enables a network if it is going to connect to it which is not the case when 'disableOthers' flag is false. BUG: 27567420 Change-Id: I45d39f4f8efebd7e19fd0bcf5bd97a68d08217ee --- tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 4478bd4c52..55fd1f5722 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -373,7 +373,7 @@ public class WifiManagerTest extends AndroidTestCase { assertTrue(notExist != pos); // Enable & disable network - boolean disableOthers = false; + boolean disableOthers = true; assertTrue(mWifiManager.enableNetwork(netId, disableOthers)); wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); assertDisableOthers(wifiConfiguration, disableOthers); From 744f5e2688d7ab24c7c960acf7a3ee46ebd4f761 Mon Sep 17 00:00:00 2001 From: Kevin Ma Date: Mon, 14 Mar 2016 13:10:02 -0700 Subject: [PATCH 0220/1109] Add Airplane mode test. Change-Id: If3bfa92828cdc878b2f994beafc41faba7398feb --- tests/cts/net/AndroidManifest.xml | 1 + .../src/android/net/cts/AirplaneModeTest.java | 85 +++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 tests/cts/net/src/android/net/cts/AirplaneModeTest.java diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index 001e2946b1..848ed995b6 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -28,6 +28,7 @@ + diff --git a/tests/cts/net/src/android/net/cts/AirplaneModeTest.java b/tests/cts/net/src/android/net/cts/AirplaneModeTest.java new file mode 100644 index 0000000000..0a3146cbcc --- /dev/null +++ b/tests/cts/net/src/android/net/cts/AirplaneModeTest.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2016 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.content.ContentResolver; +import android.content.Context; +import android.content.pm.PackageManager; +import android.provider.Settings; +import android.test.AndroidTestCase; +import android.util.Log; + +import java.lang.Thread; + +public class AirplaneModeTest extends AndroidTestCase { + private static final String TAG = "AirplaneModeTest"; + private static final String FEATURE_BLUETOOTH = "android.hardware.bluetooth"; + private static final String FEATURE_WIFI = "android.hardware.wifi"; + private static final int TIMEOUT_MS = 10 * 1000; + private boolean mHasFeature; + private Context mContext; + private ContentResolver resolver; + + public void setup() { + mContext= getContext(); + resolver = mContext.getContentResolver(); + mHasFeature = (mContext.getPackageManager().hasSystemFeature(FEATURE_BLUETOOTH) + || mContext.getPackageManager().hasSystemFeature(FEATURE_WIFI)); + } + + public void testAirplaneMode() { + setup(); + if (!mHasFeature) { + Log.i(TAG, "The device doesn't support network bluetooth or wifi feature"); + return; + } + + for (int testCount = 0; testCount < 2; testCount++) { + if (!doOneTest()) { + fail("Airplane mode failed to change in " + TIMEOUT_MS + "msec"); + return; + } + } + } + + private boolean doOneTest() { + boolean airplaneModeOn = isAirplaneModeOn(); + setAirplaneModeOn(!airplaneModeOn); + + try { + Thread.sleep(TIMEOUT_MS); + } catch (InterruptedException e) { + Log.e(TAG, "Sleep time interrupted.", e); + } + + if (airplaneModeOn == isAirplaneModeOn()) { + return false; + } + return true; + } + + private void setAirplaneModeOn(boolean enabling) { + // Change the system setting for airplane mode + Settings.Global.putInt(resolver, Settings.Global.AIRPLANE_MODE_ON, enabling ? 1 : 0); + } + + private boolean isAirplaneModeOn() { + // Read the system setting for airplane mode + return Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.AIRPLANE_MODE_ON, 0) != 0; + } +} From d857ae7745c7b865a1fdbfbf1754c3840fbdc705 Mon Sep 17 00:00:00 2001 From: Kevin Ma Date: Mon, 14 Mar 2016 13:59:21 -0700 Subject: [PATCH 0221/1109] Add theater mode test. Change-Id: Ie4c4d690fc1b10e917104536e7224c667365db6e --- .../src/android/net/cts/TheaterModeTest.java | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 tests/cts/net/src/android/net/cts/TheaterModeTest.java diff --git a/tests/cts/net/src/android/net/cts/TheaterModeTest.java b/tests/cts/net/src/android/net/cts/TheaterModeTest.java new file mode 100644 index 0000000000..10fca6fd74 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/TheaterModeTest.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2016 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.content.ContentResolver; +import android.content.Context; +import android.provider.Settings; +import android.test.AndroidTestCase; +import android.util.Log; + +import java.lang.Thread; + +public class TheaterModeTest extends AndroidTestCase { + private static final String TAG = "TheaterModeTest"; + private static final String FEATURE_BLUETOOTH = "android.hardware.bluetooth"; + private static final String FEATURE_WIFI = "android.hardware.wifi"; + private static final int TIMEOUT_MS = 10 * 1000; + private boolean mHasFeature; + private Context mContext; + private ContentResolver resolver; + + public void setup() { + mContext= getContext(); + resolver = mContext.getContentResolver(); + mHasFeature = (mContext.getPackageManager().hasSystemFeature(FEATURE_BLUETOOTH) + || mContext.getPackageManager().hasSystemFeature(FEATURE_WIFI)); + } + + public void testTheaterMode() { + setup(); + if (!mHasFeature) { + Log.i(TAG, "The device doesn't support network bluetooth or wifi feature"); + return; + } + + for (int testCount = 0; testCount < 2; testCount++) { + if (!doOneTest()) { + fail("Theater mode failed to change in " + TIMEOUT_MS + "msec"); + return; + } + } + } + + private boolean doOneTest() { + boolean theaterModeOn = isTheaterModeOn(); + + setTheaterModeOn(!theaterModeOn); + try { + Thread.sleep(TIMEOUT_MS); + } catch (InterruptedException e) { + Log.e(TAG, "Sleep time interrupted.", e); + } + + if (theaterModeOn == isTheaterModeOn()) { + return false; + } + return true; + } + + private void setTheaterModeOn(boolean enabling) { + // Change the system setting for theater mode + Settings.Global.putInt(resolver, Settings.Global.THEATER_MODE_ON, enabling ? 1 : 0); + } + + private boolean isTheaterModeOn() { + // Read the system setting for theater mode + return Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.THEATER_MODE_ON, 0) != 0; + } +} From 104fd51f871d99cb7ccf64ff0decc6071b7d2630 Mon Sep 17 00:00:00 2001 From: Paul Stewart Date: Wed, 16 Mar 2016 09:44:34 -0700 Subject: [PATCH 0222/1109] WifiManagerTest#testWifiWatchdog: Disambiguate failures There is nothing in the WifiWatchdog test that supports the assumption that the device under test is pre-configured with a working WiFi network configuration. This CL makes it possible from the test stack trace whether the test failed at the beginning or during the reconnections. Bug: 27638295 Change-Id: Iff1bd398c74076fb1a969741818562ea582e868e --- tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 55fd1f5722..5497454bfd 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -484,6 +484,9 @@ public class WifiManagerTest extends AndroidTestCase { } assertTrue(mWifiManager.isWifiEnabled()); + // This will generate a distinct stack trace if the initial connection fails. + connectWifi(); + int i = 0; for (; i < 15; i++) { // Wait for a WiFi connection From 275d05f0d3efa8d90670883786bf14b2b4364c27 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Thu, 17 Mar 2016 14:08:46 -0700 Subject: [PATCH 0223/1109] Re-try commands that set/get metered networks. BUG: 27671582 Change-Id: I9160a964b44e6d48d8932dc1e1ea7702a5359885 --- .../AbstractRestrictBackgroundNetworkTestCase.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index def3439eef..adaaf84848 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -221,7 +221,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation if (result.equals(expectedResult)) return; Log.v(TAG, "Command '" + command + "' returned '" + result + " instead of '" - + expectedResult + "' on attempt #; sleeping 1s before polling again"); + + expectedResult + "' on attempt #" + i + "; sleeping 1s before trying again"); Thread.sleep(SECOND_IN_MS); } fail("Command '" + command + "' did not return '" + expectedResult + "' after " + maxTries @@ -253,13 +253,12 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation Log.i(TAG, "Setting wi-fi network " + netId + " metered status to " + metered); final String setCommand = "cmd netpolicy set metered-network " + netId + " " + metered; - final String result = executeShellCommand(setCommand); - assertTrue("Command '" + setCommand + "' failed: " + result, result.isEmpty()); + assertDelayedShellCommand(setCommand, ""); // Sanity check. - final String newStatus = executeShellCommand("cmd netpolicy get metered-network " + netId); - assertEquals("Metered status of wi-fi network " + netId + " not set properly", - newStatus.trim(), Boolean.toString(metered)); + final String getCommand = "cmd netpolicy get metered-network " + netId; + assertDelayedShellCommand(getCommand, Boolean.toString(metered)); + return netId; } From a55231798284f72b3869aa74fcbe627209dcc40a Mon Sep 17 00:00:00 2001 From: Nicholas Sauer Date: Fri, 18 Mar 2016 17:08:24 -0700 Subject: [PATCH 0224/1109] [CTS] - Set test runtimes bug: 27747405 Change-Id: If08ec156678d5435c88d9f179d3bacd064493aff --- tests/cts/hostside/AndroidTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/cts/hostside/AndroidTest.xml b/tests/cts/hostside/AndroidTest.xml index 4b6994a082..9945805252 100644 --- a/tests/cts/hostside/AndroidTest.xml +++ b/tests/cts/hostside/AndroidTest.xml @@ -16,5 +16,6 @@ From ebbfd8ce11d6c82404860874b89d4f7c8c2f43f2 Mon Sep 17 00:00:00 2001 From: Ningyuan Wang Date: Tue, 22 Mar 2016 16:20:27 -0700 Subject: [PATCH 0225/1109] handle null mScanResult for CTS test This adds one more assert statement to ensure the ScanResult variable is not null before we proceed. Bug: 27744749 TEST=run cts test without error Change-Id: I48f3c5369792d3a55b594b71250b0dfdf0d5282b --- tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 5497454bfd..897e5cfe8e 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -296,6 +296,8 @@ public class WifiManagerTest extends AndroidTestCase { for (int i = 0; i < WIFI_SCAN_TEST_ITERATIONS; ++i) { startScan(); // Make sure at least one AP is found. + assertTrue("mScanResult should not be null. This may be due to a scan timeout", + mScanResults != null); assertFalse("empty scan results!", mScanResults.isEmpty()); long nowMillis = SystemClock.elapsedRealtime(); // Keep track of how many APs are fresh in one scan. From 10788e7864f750e276814342ae647cb0caac5679 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Wed, 16 Mar 2016 10:56:48 -0700 Subject: [PATCH 0226/1109] Test that we can set and read txt records. Bug: 27696905 Change-Id: I494665adeb8a859791bb5d08fe5b6ee73f20ac8d --- .../android/net/wifi/cts/NsdManagerTest.java | 146 +++++++++++++++++- 1 file changed, 140 insertions(+), 6 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java index e132cce25f..2e2e75b359 100644 --- a/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java @@ -24,6 +24,7 @@ import android.util.Log; import java.io.IOException; import java.net.ServerSocket; +import java.util.Arrays; import java.util.Random; import java.util.List; import java.util.ArrayList; @@ -41,6 +42,7 @@ public class NsdManagerTest extends AndroidTestCase { NsdManager.RegistrationListener mRegistrationListener; NsdManager.DiscoveryListener mDiscoveryListener; NsdManager.ResolveListener mResolveListener; + private NsdServiceInfo mResolvedService; public NsdManagerTest() { initRegistrationListener(); @@ -119,6 +121,7 @@ public class NsdManagerTest extends AndroidTestCase { @Override public void onServiceResolved(NsdServiceInfo serviceInfo) { + mResolvedService = serviceInfo; setEvent("onServiceResolved", serviceInfo); } }; @@ -254,14 +257,87 @@ public class NsdManagerTest extends AndroidTestCase { if (DBG) Log.d(TAG, "Tear down test ..."); } - public void runTest() throws Exception { + public void testNDSManager() throws Exception { + EventData lastEvent = null; + + if (DBG) Log.d(TAG, "Starting test ..."); + NsdServiceInfo si = new NsdServiceInfo(); si.setServiceType(SERVICE_TYPE); si.setServiceName(mServiceName); - EventData lastEvent = null; + byte testByteArray[] = new byte[] {-128, 127, 2, 1, 0, 1, 2}; + String String256 = "1_________2_________3_________4_________5_________6_________" + + "7_________8_________9_________10________11________12________13________" + + "14________15________16________17________18________19________20________" + + "21________22________23________24________25________123456"; - if (DBG) Log.d(TAG, "Starting test ..."); + // Illegal attributes + try { + si.setAttribute(null, (String) null); + fail("Could set null key"); + } catch (IllegalArgumentException e) { + // expected + } + + try { + si.setAttribute("", (String) null); + fail("Could set empty key"); + } catch (IllegalArgumentException e) { + // expected + } + + try { + si.setAttribute(String256, (String) null); + fail("Could set key with 255 characters"); + } catch (IllegalArgumentException e) { + // expected + } + + try { + si.setAttribute("key", String256.substring(3)); + fail("Could set key+value combination with more than 255 characters"); + } catch (IllegalArgumentException e) { + // expected + } + + try { + si.setAttribute("key", String256.substring(4)); + fail("Could set key+value combination with 255 characters"); + } catch (IllegalArgumentException e) { + // expected + } + + try { + si.setAttribute(new String(new byte[]{0x19}), (String) null); + fail("Could set key with invalid character"); + } catch (IllegalArgumentException e) { + // expected + } + + try { + si.setAttribute("=", (String) null); + fail("Could set key with invalid character"); + } catch (IllegalArgumentException e) { + // expected + } + + try { + si.setAttribute(new String(new byte[]{0x7F}), (String) null); + fail("Could set key with invalid character"); + } catch (IllegalArgumentException e) { + // expected + } + + // Allowed attributes + si.setAttribute("booleanAttr", (String) null); + si.setAttribute("keyValueAttr", "value"); + si.setAttribute("keyEqualsAttr", "="); + si.setAttribute(" whiteSpaceKeyValueAttr ", " value "); + si.setAttribute("binaryDataAttr", testByteArray); + si.setAttribute("nullBinaryDataAttr", (byte[]) null); + si.setAttribute("emptyBinaryDataAttr", new byte[]{}); + si.setAttribute("longkey", String256.substring(9)); ServerSocket socket; int localPort; @@ -347,6 +423,25 @@ public class NsdManagerTest extends AndroidTestCase { mNsdManager.resolveService(si, mResolveListener); lastEvent = waitForCallback("onServiceResolved"); // id = 4 + assertNotNull(mResolvedService); + + // Check Txt attributes + assertEquals(8, mResolvedService.getAttributes().size()); + assertTrue(mResolvedService.getAttributes().containsKey("booleanAttr")); + assertNull(mResolvedService.getAttributes().get("booleanAttr")); + assertEquals("value", new String(mResolvedService.getAttributes().get("keyValueAttr"))); + assertEquals("=", new String(mResolvedService.getAttributes().get("keyEqualsAttr"))); + assertEquals(" value ", new String(mResolvedService.getAttributes() + .get(" whiteSpaceKeyValueAttr "))); + assertEquals(String256.substring(9), new String(mResolvedService.getAttributes() + .get("longkey"))); + assertTrue(Arrays.equals(testByteArray, + mResolvedService.getAttributes().get("binaryDataAttr"))); + assertTrue(mResolvedService.getAttributes().containsKey("nullBinaryDataAttr")); + assertNull(mResolvedService.getAttributes().get("nullBinaryDataAttr")); + assertTrue(mResolvedService.getAttributes().containsKey("emptyBinaryDataAttr")); + assertNull(mResolvedService.getAttributes().get("emptyBinaryDataAttr")); + assertTrue(lastEvent != null); assertTrue(lastEvent.mSucceeded); @@ -394,7 +489,41 @@ public class NsdManagerTest extends AndroidTestCase { registeredName = lastEvent.mInfo.getServiceName(); // Expect a record to be discovered - lastEvent = waitForCallback("onServiceFound"); // id = 8 + // Expect a service record to be discovered (and filter the ones + // that are unrelated to this test) + found = false; + for (int i = 0; i < 32; i++) { + + lastEvent = waitForCallback("onServiceFound"); // id = 8 + if (lastEvent == null) { + // no more onServiceFound events are being reported! + break; + } + + assertTrue(lastEvent.mSucceeded); + + if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": ServiceName = " + + lastEvent.mInfo.getServiceName()); + + if (lastEvent.mInfo.getServiceName().equals(registeredName)) { + // Save it, as it will get overwritten with new serviceFound events + si = lastEvent.mInfo; + found = true; + } + + // Remove this event from the event cache, so it won't be found by subsequent + // calls to waitForCallback + synchronized (mEventCache) { + mEventCache.remove(lastEvent); + } + } + + assertTrue(found); + + // Resolve the service + clearEventCache(); + mNsdManager.resolveService(si, mResolveListener); + lastEvent = waitForCallback("onServiceResolved"); // id = 9 assertTrue(lastEvent != null); assertTrue(lastEvent.mSucceeded); @@ -404,11 +533,16 @@ public class NsdManagerTest extends AndroidTestCase { assertTrue(lastEvent.mInfo.getServiceName().equals(registeredName)); + assertNotNull(mResolvedService); + + // Check that we don't have any TXT records + assertEquals(0, mResolvedService.getAttributes().size()); + checkForAdditionalEvents(); clearEventCache(); mNsdManager.stopServiceDiscovery(mDiscoveryListener); - lastEvent = waitForCallback("onDiscoveryStopped"); // id = 9 + lastEvent = waitForCallback("onDiscoveryStopped"); // id = 10 assertTrue(lastEvent != null); assertTrue(lastEvent.mSucceeded); assertTrue(checkCacheSize(1)); @@ -418,7 +552,7 @@ public class NsdManagerTest extends AndroidTestCase { mNsdManager.unregisterService(mRegistrationListener); - lastEvent = waitForCallback("onServiceUnregistered"); // id = 10 + lastEvent = waitForCallback("onServiceUnregistered"); // id = 11 assertTrue(lastEvent != null); assertTrue(lastEvent.mSucceeded); assertTrue(checkCacheSize(1)); From de7cbcf6ee5954c3385e7ac3ca84f8266be7b95c Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Fri, 25 Mar 2016 17:17:33 -0700 Subject: [PATCH 0227/1109] Added sanity check to verify process state. BUG: 26776313 BUG: 27324964 Change-Id: I209c04d5c6d89acdac9b5bdaee5a4dbd7700c53e --- ...ractRestrictBackgroundNetworkTestCase.java | 44 ++++++++++++++++++- .../cts/net/hostside/DataSaverModeTest.java | 6 +++ ...ostsideRestrictBackgroundNetworkTests.java | 1 - 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index adaaf84848..68be6a5b5b 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -25,6 +25,7 @@ import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELI import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import android.app.ActivityManager; import android.app.Instrumentation; import android.content.BroadcastReceiver; import android.content.Context; @@ -86,7 +87,9 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation final int myUid = mContext.getPackageManager() .getPackageInfo(mContext.getPackageName(), 0).applicationInfo.uid; - Log.d(TAG, "UIDS: test app=" + myUid + ", app2=" + mUid); + Log.i(TAG, "Apps status on " + getName() + ":\n" + + "\ttest app: uid=" + myUid + ", state=" + getProcessStateByUid(myUid) + "\n" + + "\tapp2: uid=" + mUid + ", state=" + getProcessStateByUid(mUid)); } @Override @@ -158,6 +161,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation } protected void assertRestrictBackgroundStatus(int expectedApiStatus) throws Exception { + assertBackgroundState(); // Sanity check. final Intent intent = new Intent(ACTION_CHECK_NETWORK); final String resultData = sendOrderedBroadcast(intent); final String[] resultItems = resultData.split(RESULT_SEPARATOR); @@ -171,6 +175,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation } protected void assertBackgroundNetworkAccess(boolean expectAllowed) throws Exception { + assertBackgroundState(); // Sanity check. final Intent intent = new Intent(ACTION_CHECK_NETWORK); final String resultData = sendOrderedBroadcast(intent); final String[] resultItems = resultData.split(RESULT_SEPARATOR); @@ -178,6 +183,20 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation assertNetworkStatus(expectAllowed, networkStatus); } + protected final void assertBackgroundState() throws Exception { + final ProcessState state = getProcessStateByUid(mUid); + Log.v(TAG, "assertBackgroundState(): status for app2 (" + mUid + "): " + state); + final boolean isBackground = isBackground(state.state); + assertTrue("App2 is not on background state: " + state, isBackground); + } + + /** + * Returns whether an app state should be considered "background" for restriction purposes. + */ + protected boolean isBackground(int state) { + return state > 4; // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; + } + private String getNetworkStatus(String[] resultItems) { return resultItems.length < 2 ? null : resultItems[1]; } @@ -386,4 +405,27 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation return "UNKNOWN_STATUS_" + status; } } + + private ProcessState getProcessStateByUid(int uid) throws Exception { + return new ProcessState(executeShellCommand("cmd activity get-uid-state " + uid)); + } + + private static class ProcessState { + private final String fullState; + final int state; + + ProcessState(String fullState) { + this.fullState = fullState; + try { + this.state = Integer.parseInt(fullState.split(" ")[0]); + } catch (Exception e) { + throw new IllegalArgumentException("Could not parse " + fullState); + } + } + + @Override + public String toString() { + return fullState; + } + } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index b9fca39312..de75a49935 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -20,6 +20,12 @@ import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLE import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; +/* + * TODO: need to add more scenarios: + * - test access on foreground app + * - test access on foreground service app + * - make sure it tests transition of data saver status while app is on foreground + */ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase { @Override diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java index 2bd76e6c93..15a4e0a84f 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java @@ -30,7 +30,6 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC uninstallPackage(TEST_APP2_PKG, false); installPackage(TEST_APP2_APK); - } @Override From c3d29ebf21d3d168374b3f083832eb6a05146401 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Tue, 29 Mar 2016 14:29:55 -0700 Subject: [PATCH 0228/1109] Refactored method to get UIDs. BUG: 27904062 Change-Id: Ib0d3911f40e0a5deed833f71e75abd10a224768f --- .../AbstractRestrictBackgroundNetworkTestCase.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index adaaf84848..824624313b 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -82,9 +82,8 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation mContext = mInstrumentation.getContext(); mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); mWfm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); - mUid = mContext.getPackageManager().getPackageInfo(TEST_APP2_PKG, 0).applicationInfo.uid; - final int myUid = mContext.getPackageManager() - .getPackageInfo(mContext.getPackageName(), 0).applicationInfo.uid; + mUid = getUid(TEST_APP2_PKG); + final int myUid = getUid(mContext.getPackageName()); Log.d(TAG, "UIDS: test app=" + myUid + ", app2=" + mUid); } @@ -98,6 +97,10 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation } } + protected int getUid(String packageName) throws Exception { + return mContext.getPackageManager().getPackageUid(packageName, 0); + } + protected void assertRestrictBackgroundChangedReceived(int expectedCount) throws Exception { assertRestrictBackgroundChangedReceived(DYNAMIC_RECEIVER, expectedCount); assertRestrictBackgroundChangedReceived(MANIFEST_RECEIVER, 0); From 9a4643cd0e2167c362465a51e75a18ac8c9cfb36 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Fri, 25 Mar 2016 17:51:45 -0700 Subject: [PATCH 0229/1109] Improved test case for blacklist access. BUG: 27127112 BUG: 26685616 Change-Id: I8b183cdb1cf5ebbc446176a042e4196ab063f1a3 --- .../cts/net/hostside/DataSaverModeTest.java | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index de75a49935..2971f9dfee 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -24,7 +24,10 @@ import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELI * TODO: need to add more scenarios: * - test access on foreground app * - test access on foreground service app - * - make sure it tests transition of data saver status while app is on foreground + * - make sure it works when app is on foreground and state is transitioned: + * - data saver is enabled + * - app is added/removed to blacklist + * */ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase { @@ -46,13 +49,13 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase public void testGetRestrictBackgroundStatus_disabled() throws Exception { removeRestrictBackgroundWhitelist(mUid); - assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); assertRestrictBackgroundChangedReceived(0); + assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); // Sanity check: make sure status is always disabled, never whitelisted addRestrictBackgroundWhitelist(mUid); - assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); assertRestrictBackgroundChangedReceived(0); + assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); } public void testGetRestrictBackgroundStatus_whitelisted() throws Exception { @@ -60,40 +63,39 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertRestrictBackgroundChangedReceived(1); addRestrictBackgroundWhitelist(mUid); - assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_WHITELISTED); assertRestrictBackgroundChangedReceived(2); + assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_WHITELISTED); } public void testGetRestrictBackgroundStatus_enabled() throws Exception { setRestrictBackground(true); assertRestrictBackgroundChangedReceived(1); + assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); removeRestrictBackgroundWhitelist(mUid); - assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); assertRestrictBackgroundChangedReceived(1); + assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); } public void testGetRestrictBackgroundStatus_blacklisted() throws Exception { addRestrictBackgroundBlacklist(mUid); assertRestrictBackgroundChangedReceived(1); - assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); - // TODO: currently whitelist is prevailing, hence remaining of the test below is disabled - if (true) return; - // Make sure blacklist prevails over whitelist. setRestrictBackground(true); assertRestrictBackgroundChangedReceived(2); + assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); addRestrictBackgroundWhitelist(mUid); + assertRestrictBackgroundChangedReceived(3); assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); // Check status after removing blacklist. removeRestrictBackgroundBlacklist(mUid); - assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_WHITELISTED); - assertRestrictBackgroundChangedReceived(3); - setRestrictBackground(false); - assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); assertRestrictBackgroundChangedReceived(4); + assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_WHITELISTED); + setRestrictBackground(false); + assertRestrictBackgroundChangedReceived(5); + assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); } } From eb7e5053c14775439f7df880462c53344080f60c Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Tue, 29 Mar 2016 17:31:25 -0700 Subject: [PATCH 0230/1109] Test network restrictions while on foreground service state. BUG: 27324964 BUG: 26776313 Change-Id: Idcd0a391333d243d17b6bd68c67becaad2b37fdd --- ...ractRestrictBackgroundNetworkTestCase.java | 18 +++++++- .../BatterySaverModeNonMeteredTest.java | 6 ++- .../net/hostside/BatterySaverModeTest.java | 7 ++- .../cts/net/hostside/DataSaverModeTest.java | 8 +++- tests/cts/hostside/app2/AndroidManifest.xml | 1 + .../hostside/app2/MyForegroundService.java | 44 +++++++++++++++++++ .../cts/net/hostside/app2/MyService.java | 2 +- 7 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index a701c66225..4c272ee747 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -65,6 +65,8 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation private static final String STATUS_NETWORK_AVAILABLE_PREFIX = "NetworkAvailable:"; private static final int SECOND_IN_MS = 1000; private static final int NETWORK_TIMEOUT_MS = 15 * SECOND_IN_MS; + private static final int PROCESS_STATE_FOREGROUND_SERVICE = 4; + // Must be higher than NETWORK_TIMEOUT_MS private static final int ORDERED_BROADCAST_TIMEOUT_MS = NETWORK_TIMEOUT_MS * 4; @@ -193,11 +195,18 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation assertTrue("App2 is not on background state: " + state, isBackground); } + protected final void assertForegroundServiceState() throws Exception { + final ProcessState state = getProcessState(mUid); + Log.v(TAG, "assertForegroundServiceState(): status for app2 (" + mUid + "): " + state); + assertEquals("App2 is not on foreground service state: " + state, + PROCESS_STATE_FOREGROUND_SERVICE, state.state); + } + /** * Returns whether an app state should be considered "background" for restriction purposes. */ protected boolean isBackground(int state) { - return state > 4; // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; + return state >= PROCESS_STATE_FOREGROUND_SERVICE; } private String getNetworkStatus(String[] resultItems) { @@ -379,7 +388,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation * The service must run in a separate app because otherwise it would be killed every time * {@link #runDeviceTests(String, String)} is executed. */ - protected void registerApp2BroadcastReceiver() throws Exception { + protected void registerBroadcastReceiver() throws Exception { executeShellCommand("am startservice com.android.cts.net.hostside.app2/.MyService"); // Wait until receiver is ready. final int maxTries = 5; @@ -396,6 +405,11 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation fail("app2 receiver is not ready"); } + protected void startForegroundService() throws Exception { + executeShellCommand( + "am startservice com.android.cts.net.hostside.app2/.MyForegroundService"); + } + private String toString(int status) { switch (status) { case RESTRICT_BACKGROUND_STATUS_DISABLED: diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java index 5181057d85..8e83fa2b7f 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java @@ -25,7 +25,7 @@ public class BatterySaverModeNonMeteredTest extends AbstractRestrictBackgroundNe setPowerSaveMode(false); assertPowerSaveModeWhitelist(TEST_APP2_PKG, false); // Sanity check - registerApp2BroadcastReceiver(); + registerBroadcastReceiver(); } @Override @@ -38,6 +38,10 @@ public class BatterySaverModeNonMeteredTest extends AbstractRestrictBackgroundNe public void testBackgroundNetworkAccess_enabled() throws Exception { setPowerSaveMode(true); assertBackgroundNetworkAccess(false); + // Make sure app is allowed if running a foreground service. + startForegroundService(); + assertForegroundServiceState(); + assertBackgroundNetworkAccess(true); } public void testBackgroundNetworkAccess_whitelisted() throws Exception { diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java index 18e2b3e054..6a8540a526 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java @@ -26,7 +26,7 @@ public class BatterySaverModeTest extends AbstractRestrictBackgroundNetworkTestC setMeteredNetwork(); setPowerSaveMode(false); assertPowerSaveModeWhitelist(TEST_APP2_PKG, false); // Sanity check - registerApp2BroadcastReceiver(); + registerBroadcastReceiver(); } @Override @@ -39,6 +39,11 @@ public class BatterySaverModeTest extends AbstractRestrictBackgroundNetworkTestC public void testBackgroundNetworkAccess_enabled() throws Exception { setPowerSaveMode(true); assertBackgroundNetworkAccess(false); + + // Make sure app is allowed if running a foreground service. + startForegroundService(); + assertForegroundServiceState(); + assertBackgroundNetworkAccess(true); } public void testBackgroundNetworkAccess_whitelisted() throws Exception { diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index 2971f9dfee..ff68090d3e 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -37,7 +37,7 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase setMeteredNetwork(); setRestrictBackground(false); - registerApp2BroadcastReceiver(); + registerBroadcastReceiver(); } @Override @@ -75,6 +75,12 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase removeRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundChangedReceived(1); assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); + + // Make sure app is allowed if running a foreground service. + assertBackgroundNetworkAccess(false); + startForegroundService(); + assertForegroundServiceState(); + assertBackgroundNetworkAccess(true); } public void testGetRestrictBackgroundStatus_blacklisted() throws Exception { diff --git a/tests/cts/hostside/app2/AndroidManifest.xml b/tests/cts/hostside/app2/AndroidManifest.xml index fa4cb43d29..9ce57817de 100644 --- a/tests/cts/hostside/app2/AndroidManifest.xml +++ b/tests/cts/hostside/app2/AndroidManifest.xml @@ -32,6 +32,7 @@ --> + diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java new file mode 100644 index 0000000000..bbafd4c274 --- /dev/null +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2016 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.cts.net.hostside.app2; + +import static com.android.cts.net.hostside.app2.Common.TAG; +import android.R; +import android.app.Notification; +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; +import android.util.Log; + +/** + * Service used to change app state to FOREGROUND_SERVICE. + */ +public class MyForegroundService extends Service { + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + Log.d(TAG, "MyForegroundService.onStartCommand: " + intent); + startForeground(42, new Notification.Builder(this) + .setSmallIcon(R.drawable.ic_dialog_alert) // any icon is fine + .build()); + return START_STICKY; + } +} diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java index 55249f2208..e6454c7be0 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java @@ -39,7 +39,7 @@ public class MyService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { - Log.d(TAG, "onStartCommand: " + intent); + Log.d(TAG, "MyService.onStartCommand: " + intent); final Context context = getApplicationContext(); final MyBroadcastReceiver myReceiver = new MyBroadcastReceiver(DYNAMIC_RECEIVER); context.registerReceiver(myReceiver, new IntentFilter(ACTION_RECEIVER_READY)); From bbb00ffc0fe58ca94feaa0e940aaba5949572e00 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Wed, 30 Mar 2016 16:37:24 -0700 Subject: [PATCH 0231/1109] Fixed build broken by bad merge. BUG: 27324964 Change-Id: Idbe6f8237b560db31eb949971358db41ac00d530 --- .../net/hostside/AbstractRestrictBackgroundNetworkTestCase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 4c272ee747..f33d4341c3 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -196,7 +196,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation } protected final void assertForegroundServiceState() throws Exception { - final ProcessState state = getProcessState(mUid); + final ProcessState state = getProcessStateByUid(mUid); Log.v(TAG, "assertForegroundServiceState(): status for app2 (" + mUid + "): " + state); assertEquals("App2 is not on foreground service state: " + state, PROCESS_STATE_FOREGROUND_SERVICE, state.state); From eac0fe6ab18c5a8c243a2c738979abc0189e7eaa Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Wed, 30 Mar 2016 18:06:09 -0700 Subject: [PATCH 0232/1109] Moved wi-fi switch to hostside. BUG: 27808364 Change-Id: I89bca5f5ba90a7dc145d2ac170fd505161fd073d --- .../AbstractRestrictBackgroundNetworkTestCase.java | 12 +++++++++--- .../com/android/cts/net/HostsideNetworkTestCase.java | 2 ++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index f33d4341c3..41fd63853a 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -247,8 +247,9 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected void assertDelayedShellCommand(String command, String expectedResult) throws Exception { final int maxTries = 5; + String result = ""; for (int i = 1; i <= maxTries; i++) { - final String result = executeShellCommand(command).trim(); + result = executeShellCommand(command).trim(); if (result.equals(expectedResult)) return; Log.v(TAG, "Command '" + command + "' returned '" + result + " instead of '" @@ -256,7 +257,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation Thread.sleep(SECOND_IN_MS); } fail("Command '" + command + "' did not return '" + expectedResult + "' after " + maxTries - + " attempts"); + + " attempts. Last result: '" + result + "'"); } protected void setMeteredNetwork() throws Exception { @@ -265,6 +266,8 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation if (metered) { Log.d(TAG, "Active network already metered: " + info); return; + } else { + Log.w(TAG, "Active network not metered: " + info); } final String netId = setWifiMeteredStatus(true); assertTrue("Could not set wifi '" + netId + "' as metered (" @@ -274,7 +277,10 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation } protected String setWifiMeteredStatus(boolean metered) throws Exception { - mWfm.setWifiEnabled(true); + // We could call setWifiEnabled() here, but it might take sometime to be in a consistent + // state (for example, if one of the saved network is not properly authenticated), so it's + // better to let the hostside test take care of that. + assertTrue("wi-fi is disabled", mWfm.isWifiEnabled()); // TODO: if it's not guaranteed the device has wi-fi, we need to change the tests // to make the actual verification of restrictions optional. final String ssid = mWfm.getConnectionInfo().getSSID(); diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java index 08fb887932..ab1b7d699a 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java @@ -63,6 +63,8 @@ abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiRec assertNotNull(mAbi); assertNotNull(mCtsBuild); + assertTrue("device not connected to network", getDevice().checkConnectivity()); + uninstallPackage(TEST_PKG, false); installPackage(TEST_APK); } From 52be3a68ad31901aa2bf98a8698a4a634eabe080 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Fri, 1 Apr 2016 15:40:41 -0700 Subject: [PATCH 0233/1109] Refactored tests to use 'list wifi-networks'. BUG: 27808364 Change-Id: Ife3f35e9c3c6a4285b671eeb7d7d0223be908a1b --- ...ractRestrictBackgroundNetworkTestCase.java | 57 +++++++++++++++---- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 41fd63853a..360257a8e1 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -244,19 +244,36 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation /** * Asserts the result of a command, wait and re-running it a couple times if necessary. */ - protected void assertDelayedShellCommand(String command, String expectedResult) + protected void assertDelayedShellCommand(String command, final String expectedResult) + throws Exception { + assertDelayedShellCommand(command, new ExpectResultChecker() { + + @Override + public boolean isExpected(String result) { + return expectedResult.equals(result); + } + + @Override + public String getExpected() { + return expectedResult; + } + }); + } + + protected void assertDelayedShellCommand(String command, ExpectResultChecker checker) throws Exception { final int maxTries = 5; String result = ""; for (int i = 1; i <= maxTries; i++) { result = executeShellCommand(command).trim(); - if (result.equals(expectedResult)) - return; + if (checker.isExpected(result)) return; Log.v(TAG, "Command '" + command + "' returned '" + result + " instead of '" - + expectedResult + "' on attempt #" + i + "; sleeping 1s before trying again"); + + checker.getExpected() + "' on attempt #" + i + + "; sleeping 1s before trying again"); Thread.sleep(SECOND_IN_MS); } - fail("Command '" + command + "' did not return '" + expectedResult + "' after " + maxTries + fail("Command '" + command + "' did not return '" + checker.getExpected() + "' after " + + maxTries + " attempts. Last result: '" + result + "'"); } @@ -274,9 +291,11 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation + mCm.getActiveNetworkInfo() +")", mCm.isActiveNetworkMetered()); // Set flag so status is reverted on teardown. mResetMeteredWifi = true; + // Sanity check. + assertMeteredNetwork(netId, true); } - protected String setWifiMeteredStatus(boolean metered) throws Exception { + private String setWifiMeteredStatus(boolean metered) throws Exception { // We could call setWifiEnabled() here, but it might take sometime to be in a consistent // state (for example, if one of the saved network is not properly authenticated), so it's // better to let the hostside test take care of that. @@ -292,13 +311,26 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation final String setCommand = "cmd netpolicy set metered-network " + netId + " " + metered; assertDelayedShellCommand(setCommand, ""); - // Sanity check. - final String getCommand = "cmd netpolicy get metered-network " + netId; - assertDelayedShellCommand(getCommand, Boolean.toString(metered)); - return netId; } + private void assertMeteredNetwork(String netId, boolean status) throws Exception { + final String command = "cmd netpolicy list wifi-networks"; + final String expectedLine = netId + ";" + status; + assertDelayedShellCommand(command, new ExpectResultChecker() { + + @Override + public boolean isExpected(String result) { + return result.contains(expectedLine); + } + + @Override + public String getExpected() { + return "line containing " + expectedLine; + } + }); + } + protected void setRestrictBackground(boolean enabled) throws Exception { executeShellCommand("cmd netpolicy set restrict-background " + enabled); final String output = executeShellCommand("cmd netpolicy get restrict-background "); @@ -451,4 +483,9 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation return fullState; } } + + protected static interface ExpectResultChecker { + boolean isExpected(String result); + String getExpected(); + } } From 8d422e8c57ce8c45c6a11e46caa9b835e0bbbad6 Mon Sep 17 00:00:00 2001 From: Erik Kline Date: Fri, 1 Apr 2016 14:50:20 +0900 Subject: [PATCH 0234/1109] Extend CTS test coverage to include registerDefaultNetworkRequest() Change-Id: I36491c2697ed1510da38c06324d2e4ddf653bc4e --- .../net/cts/ConnectivityManagerTest.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 9a99c22c07..6ed43680a8 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -265,13 +265,16 @@ public class ConnectivityManagerTest extends AndroidTestCase { } // We will register for a WIFI network being available or lost. - NetworkRequest request = new NetworkRequest.Builder() + final NetworkRequest request = new NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .build(); - TestNetworkCallback callback = new TestNetworkCallback(); + final TestNetworkCallback callback = new TestNetworkCallback(); mCm.registerNetworkCallback(request, callback); - boolean previousWifiEnabledState = mWifiManager.isWifiEnabled(); + final TestNetworkCallback defaultTrackingCallback = new TestNetworkCallback(); + mCm.registerDefaultNetworkCallback(defaultTrackingCallback); + + final boolean previousWifiEnabledState = mWifiManager.isWifiEnabled(); try { // Make sure WiFi is connected to an access point to start with. @@ -284,12 +287,16 @@ public class ConnectivityManagerTest extends AndroidTestCase { // is registered. assertTrue("Did not receive NetworkCallback.onAvailable for TRANSPORT_WIFI", callback.waitForAvailable()); + + assertTrue("Did not receive NetworkCallback.onAvailable for any default network", + defaultTrackingCallback.waitForAvailable()); } catch (InterruptedException e) { fail("Broadcast receiver or NetworkCallback wait was interrupted."); } finally { mCm.unregisterNetworkCallback(callback); + mCm.unregisterNetworkCallback(defaultTrackingCallback); - // Return WiFI to its original enabled/disabled state. + // Return WiFi to its original enabled/disabled state. if (!previousWifiEnabledState) { disconnectFromWifi(); } @@ -327,7 +334,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { .build(); mCm.registerNetworkCallback(request, pendingIntent); - boolean previousWifiEnabledState = mWifiManager.isWifiEnabled(); + final boolean previousWifiEnabledState = mWifiManager.isWifiEnabled(); try { // Make sure WiFi is connected to an access point to start with. @@ -347,7 +354,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { pendingIntent.cancel(); mContext.unregisterReceiver(receiver); - // Return WiFI to its original enabled/disabled state. + // Return WiFi to its original enabled/disabled state. if (!previousWifiEnabledState) { disconnectFromWifi(); } From d5dc8fe740d6a09a282e0f8711c580f52ebf55d7 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Wed, 13 Apr 2016 16:24:29 -0700 Subject: [PATCH 0235/1109] Test for issue #28156248: Receiving connectivity receiver... ...broadcasts in Android N New test to verify that modern apps can't receive CONNECTIVITY_CHANGE. Change-Id: I9c5b6e99d14b782b3857460d8297f6a405545d87 --- tests/cts/net/AndroidManifest.xml | 6 ++ .../net/cts/ConnectivityManagerTest.java | 30 ++++++++ .../android/net/cts/ConnectivityReceiver.java | 69 +++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 tests/cts/net/src/android/net/cts/ConnectivityReceiver.java diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index f8daabf02e..dd310a1cac 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -33,6 +33,12 @@ + + + + + + Date: Thu, 14 Apr 2016 15:54:44 +0100 Subject: [PATCH 0236/1109] Added assertion message to testDns failures Identify tests that fail testDns because of no network connection. Bug:26560000 Change-Id: I7683d54d2932ec46c5850bf360c602f6548b179e --- tests/cts/net/src/android/net/cts/DnsTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/DnsTest.java b/tests/cts/net/src/android/net/cts/DnsTest.java index 0377d048e7..7d485a619e 100644 --- a/tests/cts/net/src/android/net/cts/DnsTest.java +++ b/tests/cts/net/src/android/net/cts/DnsTest.java @@ -62,7 +62,8 @@ public class DnsTest extends AndroidTestCase { try { addrs = InetAddress.getAllByName("www.google.com"); } catch (UnknownHostException e) {} - assertTrue(addrs.length != 0); + assertTrue("[RERUN] DNS could not resolve www.gooogle.com. Check internet connection", + addrs.length != 0); boolean foundV4 = false, foundV6 = false; for (InetAddress addr : addrs) { if (addr instanceof Inet4Address) foundV4 = true; From c408601c24b419f7c63b67d256ea3050cbc46bcc Mon Sep 17 00:00:00 2001 From: Owain Davies Date: Thu, 14 Apr 2016 16:12:38 +0100 Subject: [PATCH 0237/1109] Add assertion message if testDns ipv6 lookup reutrns ipv4. Some partner test networks connect by VPN and if the connection fails during the testing this test will fail as the local internet provider intercepts the DNS request and returns an ipv4 address. Added a message to check the network configuration and rerun the test. Bug: 26560000 Change-Id: I54e4976b2cef549bfe9fd55ff9609ba2e6513239 --- tests/cts/net/src/android/net/cts/DnsTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/DnsTest.java b/tests/cts/net/src/android/net/cts/DnsTest.java index 0377d048e7..6dd8520395 100644 --- a/tests/cts/net/src/android/net/cts/DnsTest.java +++ b/tests/cts/net/src/android/net/cts/DnsTest.java @@ -96,7 +96,8 @@ public class DnsTest extends AndroidTestCase { if (DBG) Log.e(TAG, "ipv6.google.com gave " + addr.toString()); } - assertTrue(foundV4 == false); + assertTrue("[RERUN] ipv6.google.com returned an ipv4 address, check your network's DNS connection.", + foundV4 == false); assertTrue(foundV6 == true); assertTrue(testNativeDns()); From f744474a281cc7fd98e4f17a3233131f91c93fb7 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Thu, 14 Apr 2016 11:47:34 -0700 Subject: [PATCH 0238/1109] Improvements on test case setup. - On hostside, checks if wi-fi is on instead of checking for connectivity (which can be very slow). - Don't automatically reset metered network on superclass' tearDown(). - Make sure tearDown() cleans up all state changes. BUG: 27808364 Change-Id: I4818047c5fb8f6f430b0aab5ecfa77717f860db3 --- ...ractRestrictBackgroundNetworkTestCase.java | 29 +++++++++++-------- .../net/hostside/BatterySaverModeTest.java | 6 +++- .../cts/net/hostside/DataSaverModeTest.java | 6 +++- .../cts/net/HostsideNetworkTestCase.java | 2 +- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 360257a8e1..2b7dd39c00 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -76,11 +76,12 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected ConnectivityManager mCm; protected WifiManager mWfm; protected int mUid; - private boolean mResetMeteredWifi = false; + private String mMeteredWifi; @Override public void setUp() throws Exception { super.setUp(); + mInstrumentation = getInstrumentation(); mContext = mInstrumentation.getContext(); mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); @@ -93,15 +94,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation + "\tapp2: uid=" + mUid + ", state=" + getProcessStateByUid(mUid)); } - @Override - protected void tearDown() throws Exception { - super.tearDown(); - - if (mResetMeteredWifi) { - setWifiMeteredStatus(false); - } - } - protected int getUid(String packageName) throws Exception { return mContext.getPackageManager().getPackageUid(packageName, 0); } @@ -289,12 +281,21 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation final String netId = setWifiMeteredStatus(true); assertTrue("Could not set wifi '" + netId + "' as metered (" + mCm.getActiveNetworkInfo() +")", mCm.isActiveNetworkMetered()); - // Set flag so status is reverted on teardown. - mResetMeteredWifi = true; + // Set flag so status is reverted on resetMeteredNetwork(); + mMeteredWifi = netId; // Sanity check. assertMeteredNetwork(netId, true); } + protected void resetMeteredNetwork() throws Exception { + if (mMeteredWifi == null) { + Log.d(TAG, "resetMeteredNetwork(): wifi not set as metered"); + return; + } + Log.i(TAG, "resetMeteredNetwork(): resetting " + mMeteredWifi); + setWifiMeteredStatus(mMeteredWifi, false); + } + private String setWifiMeteredStatus(boolean metered) throws Exception { // We could call setWifiEnabled() here, but it might take sometime to be in a consistent // state (for example, if one of the saved network is not properly authenticated), so it's @@ -303,6 +304,10 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation // TODO: if it's not guaranteed the device has wi-fi, we need to change the tests // to make the actual verification of restrictions optional. final String ssid = mWfm.getConnectionInfo().getSSID(); + return setWifiMeteredStatus(ssid, metered); + } + + private String setWifiMeteredStatus(String ssid, boolean metered) throws Exception { assertNotNull("null SSID", ssid); final String netId = ssid.trim().replaceAll("\"", ""); // remove quotes, if any. assertFalse("empty SSID", ssid.isEmpty()); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java index 6a8540a526..d1217b4ed7 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java @@ -33,7 +33,11 @@ public class BatterySaverModeTest extends AbstractRestrictBackgroundNetworkTestC protected void tearDown() throws Exception { super.tearDown(); - setPowerSaveMode(false); + try { + resetMeteredNetwork(); + } finally { + setPowerSaveMode(false); + } } public void testBackgroundNetworkAccess_enabled() throws Exception { diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index ff68090d3e..62f670ed43 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -44,7 +44,11 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase protected void tearDown() throws Exception { super.tearDown(); - setRestrictBackground(false); + try { + resetMeteredNetwork(); + } finally { + setRestrictBackground(false); + } } public void testGetRestrictBackgroundStatus_disabled() throws Exception { diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java index ab1b7d699a..39b5652c76 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java @@ -63,7 +63,7 @@ abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiRec assertNotNull(mAbi); assertNotNull(mCtsBuild); - assertTrue("device not connected to network", getDevice().checkConnectivity()); + assertTrue("wi-fi not enabled", getDevice().isWifiEnabled()); uninstallPackage(TEST_PKG, false); installPackage(TEST_APK); From 0e47422a47489a8eea8fa7cd8b56ae94ac4f123c Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Thu, 14 Apr 2016 12:45:34 -0700 Subject: [PATCH 0239/1109] Changed order of metered network check. BUG: 27808364 Change-Id: I8a1088673cdd2c310a787a0b0708ad58876e9ac0 --- .../AbstractRestrictBackgroundNetworkTestCase.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 2b7dd39c00..27d4a2b2ef 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -279,12 +279,13 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation Log.w(TAG, "Active network not metered: " + info); } final String netId = setWifiMeteredStatus(true); - assertTrue("Could not set wifi '" + netId + "' as metered (" - + mCm.getActiveNetworkInfo() +")", mCm.isActiveNetworkMetered()); + // Set flag so status is reverted on resetMeteredNetwork(); mMeteredWifi = netId; // Sanity check. - assertMeteredNetwork(netId, true); + assertWifiMeteredStatus(netId, true); + assertTrue("Could not set wifi '" + netId + "' as metered (" + + mCm.getActiveNetworkInfo() +")", mCm.isActiveNetworkMetered()); } protected void resetMeteredNetwork() throws Exception { @@ -319,7 +320,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation return netId; } - private void assertMeteredNetwork(String netId, boolean status) throws Exception { + private void assertWifiMeteredStatus(String netId, boolean status) throws Exception { final String command = "cmd netpolicy list wifi-networks"; final String expectedLine = netId + ";" + status; assertDelayedShellCommand(command, new ExpectResultChecker() { From bac071b74f0a0a7c20db21cc30c7b21b432eb948 Mon Sep 17 00:00:00 2001 From: Chad Brubaker Date: Wed, 20 Apr 2016 13:34:40 -0700 Subject: [PATCH 0240/1109] Rewrite X509TrustManagerExtensionsTest X509TrustManagerExtensionsTest used internal implementation details to test X509TrustManagerExtensions#isUserAddedCertificate, these implementation details are no longer the same and so this test failed to catch the API being broken and then incorrectly flagged the fixed API as broken. To ensure that isUserAddedCertificate is properly covered the tests for the API are split into two places: X509TrustManagerExtensionsTest covers tests for the default case where there are no added CAs and CaCertManagementTest to test the behavior when CAs have been added. Bug:28262103 Change-Id: I14f3211c277fdc9c8bfc3d4ac932be375961fa28 --- .../cts/X509TrustManagerExtensionsTest.java | 72 +++++++------------ 1 file changed, 25 insertions(+), 47 deletions(-) diff --git a/tests/cts/net/src/android/net/http/cts/X509TrustManagerExtensionsTest.java b/tests/cts/net/src/android/net/http/cts/X509TrustManagerExtensionsTest.java index 9c0d7744c7..99de614d80 100644 --- a/tests/cts/net/src/android/net/http/cts/X509TrustManagerExtensionsTest.java +++ b/tests/cts/net/src/android/net/http/cts/X509TrustManagerExtensionsTest.java @@ -17,61 +17,39 @@ package android.net.http.cts; import android.net.http.X509TrustManagerExtensions; -import android.util.Base64; - -import java.io.File; -import java.io.ByteArrayInputStream; import java.security.KeyStore; -import java.security.cert.CertificateFactory; +import java.security.cert.Certificate; import java.security.cert.X509Certificate; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + import junit.framework.TestCase; -import com.android.org.conscrypt.TrustedCertificateStore; -import com.android.org.conscrypt.TrustManagerImpl; - public class X509TrustManagerExtensionsTest extends TestCase { - public void testIsUserAddedCert() throws Exception { - final String testCert = - "MIICfjCCAeegAwIBAgIJAMefIzKHY5H4MA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV" + - "BAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEPMA0G" + - "A1UECgwGR2V3Z3VsMRMwEQYDVQQDDApnZXdndWwuY29tMB4XDTEzMTEwNTAwNDE0" + - "MFoXDTEzMTIwNTAwNDE0MFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRYw" + - "FAYDVQQHDA1Nb3VudGFpbiBWaWV3MQ8wDQYDVQQKDAZHZXdndWwxEzARBgNVBAMM" + - "Cmdld2d1bC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKpc/I0Ss4sm" + - "yV2iX5xRMM7+XXAhiWrceGair4MpvDrGIa1kFj2phtx4IqTfDnNU7AhRJYkDYmJQ" + - "fUJ8i6F+I08uNiGVO4DtPJbZcBXg9ME9EMaJCslm995ueeNWSw1Ky8zM0tt4p+94" + - "BcXJ7PC3N2WgkvtE8xwNbaeUfhGPzJKXAgMBAAGjUDBOMB0GA1UdDgQWBBQQ/iW7" + - "JCkSI2sbn4nTBiZ9PSiO8zAfBgNVHSMEGDAWgBQQ/iW7JCkSI2sbn4nTBiZ9PSiO" + - "8zAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBABQBrUOWTCSIl3vkRR3w" + - "3bPzh3BpqDmxH9xe4rZr+MVKKjpGjY1z2m2EEtyNz3tbgVQym5+si00DUHFL0IP1" + - "SuRULmPyEpTBVbV+PA5Kc967ZcDgYt4JtdMcCeKbIFaU6r8oEYEL2PTlNZmgbunM" + - "pXktkhVvNxZeSa8yM9bPhXkN"; + private static X509TrustManager getFirstX509TrustManager(TrustManagerFactory tmf) + throws Exception { + for (TrustManager trustManager : tmf.getTrustManagers()) { + if (trustManager instanceof X509TrustManager) { + return (X509TrustManager) trustManager; + } + } + fail("Unable to find X509TrustManager"); + return null; + } - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - X509Certificate cert = (X509Certificate)cf.generateCertificate( - new ByteArrayInputStream(Base64.decode(testCert, Base64.DEFAULT))); - - // Test without adding cert to keystore. - KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); - X509TrustManagerExtensions tmeNegative = - new X509TrustManagerExtensions(new TrustManagerImpl(keyStore)); - assertEquals(false, tmeNegative.isUserAddedCertificate(cert)); - - // Test with cert added to keystore. - final File DIR_TEMP = new File(System.getProperty("java.io.tmpdir")); - final File DIR_TEST = new File(DIR_TEMP, "test"); - final File system = new File(DIR_TEST, "system-test"); - final File added = new File(DIR_TEST, "added-test"); - final File deleted = new File(DIR_TEST, "deleted-test"); - - TrustedCertificateStore tcs = new TrustedCertificateStore(system, added, deleted); - added.mkdirs(); - tcs.installCertificate(cert); - X509TrustManagerExtensions tmePositive = - new X509TrustManagerExtensions(new TrustManagerImpl(keyStore, null, tcs)); - assertEquals(true, tmePositive.isUserAddedCertificate(cert)); + public void testIsUserAddedCertificateDefaults() throws Exception { + final TrustManagerFactory tmf = + TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init((KeyStore) null); + X509TrustManager tm = getFirstX509TrustManager(tmf); + X509TrustManagerExtensions xtm = new X509TrustManagerExtensions(tm); + // Verify that all the default system provided CAs are not marked as user added. + for (Certificate cert : tm.getAcceptedIssuers()) { + assertFalse(xtm.isUserAddedCertificate((X509Certificate) cert)); + } } } From 8a14c224e30ee4a76fd83cb92c47e00bb5f4abea Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Tue, 19 Apr 2016 13:00:51 +0900 Subject: [PATCH 0241/1109] Add more test coverage to ConnectivityManagerTest. 1. Test NetworkCallbacks as well as CONNECTIVITY_ACTION, since we are moving away from CONNECTIVITY_ACTION. 2. Use the Network objects we get back to test Network#getSocketFactory(). 3. Check that TCP connections are closed with ECONNABORTED when a network disconnects. Bug: 28251576 Change-Id: I41a438b82ef9251e52866332f3445f1bf876e04f --- .../net/cts/ConnectivityManagerTest.java | 156 +++++++++++++++--- 1 file changed, 134 insertions(+), 22 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 4112466877..231db97d2b 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -38,9 +38,16 @@ import android.net.wifi.WifiManager; import android.test.AndroidTestCase; import android.util.Log; import android.os.SystemProperties; +import android.system.Os; +import android.system.OsConstants; import com.android.internal.telephony.PhoneConstants; +import java.io.InputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; +import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -57,7 +64,15 @@ public class ConnectivityManagerTest extends AndroidTestCase { public static final int TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE; public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI; + private static final int HOST_ADDRESS = 0x7f000001;// represent ip 127.0.0.1 + private static final String TEST_HOST = "connectivitycheck.gstatic.com"; + private static final int SOCKET_TIMEOUT_MS = 2000; + private static final int HTTP_PORT = 80; + private static final String HTTP_REQUEST = + "GET /generate_204 HTTP/1.0\r\n" + + "Host: " + TEST_HOST + "\r\n" + + "Connection: keep-alive\r\n\r\n"; // Action sent to ConnectivityActionReceiver when a network callback is sent via PendingIntent. private static final String NETWORK_CALLBACK_ACTION = @@ -249,6 +264,12 @@ public class ConnectivityManagerTest extends AndroidTestCase { mCm.getBackgroundDataSetting(); } + private NetworkRequest makeWifiNetworkRequest() { + return new NetworkRequest.Builder() + .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) + .build(); + } + /** * Exercises both registerNetworkCallback and unregisterNetworkCallback. This checks to * see if we get a callback for the TRANSPORT_WIFI transport type being available. @@ -265,16 +286,14 @@ public class ConnectivityManagerTest extends AndroidTestCase { } // We will register for a WIFI network being available or lost. - final NetworkRequest request = new NetworkRequest.Builder() - .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) - .build(); final TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(request, callback); + mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); final TestNetworkCallback defaultTrackingCallback = new TestNetworkCallback(); mCm.registerDefaultNetworkCallback(defaultTrackingCallback); final boolean previousWifiEnabledState = mWifiManager.isWifiEnabled(); + Network wifiNetwork = null; try { // Make sure WiFi is connected to an access point to start with. @@ -285,10 +304,11 @@ public class ConnectivityManagerTest extends AndroidTestCase { // Now we should expect to get a network callback about availability of the wifi // network even if it was already connected as a state-based action when the callback // is registered. - assertTrue("Did not receive NetworkCallback.onAvailable for TRANSPORT_WIFI", - callback.waitForAvailable()); + wifiNetwork = callback.waitForAvailable(); + assertNotNull("Did not receive NetworkCallback.onAvailable for TRANSPORT_WIFI", + wifiNetwork); - assertTrue("Did not receive NetworkCallback.onAvailable for any default network", + assertNotNull("Did not receive NetworkCallback.onAvailable for any default network", defaultTrackingCallback.waitForAvailable()); } catch (InterruptedException e) { fail("Broadcast receiver or NetworkCallback wait was interrupted."); @@ -298,7 +318,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { // Return WiFi to its original enabled/disabled state. if (!previousWifiEnabledState) { - disconnectFromWifi(); + disconnectFromWifi(wifiNetwork); } } } @@ -329,10 +349,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); // We will register for a WIFI network being available or lost. - NetworkRequest request = new NetworkRequest.Builder() - .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) - .build(); - mCm.registerNetworkCallback(request, pendingIntent); + mCm.registerNetworkCallback(makeWifiNetworkRequest(), pendingIntent); final boolean previousWifiEnabledState = mWifiManager.isWifiEnabled(); @@ -356,7 +373,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { // Return WiFi to its original enabled/disabled state. if (!previousWifiEnabledState) { - disconnectFromWifi(); + disconnectFromWifi(null); } } } @@ -370,8 +387,10 @@ public class ConnectivityManagerTest extends AndroidTestCase { // We will toggle the state of wifi to generate a connectivity change. final boolean previousWifiEnabledState = mWifiManager.isWifiEnabled(); + if (previousWifiEnabledState) { - disconnectFromWifi(); + Network wifiNetwork = getWifiNetwork(); + disconnectFromWifi(wifiNetwork); } else { connectToWifi(); } @@ -387,12 +406,16 @@ public class ConnectivityManagerTest extends AndroidTestCase { if (previousWifiEnabledState) { connectToWifi(); } else { - disconnectFromWifi(); + disconnectFromWifi(null); } } /** Enable WiFi and wait for it to become connected to a network. */ - private void connectToWifi() { + private Network connectToWifi() { + final TestNetworkCallback callback = new TestNetworkCallback(); + mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); + Network wifiNetwork = null; + ConnectivityActionReceiver receiver = new ConnectivityActionReceiver( ConnectivityManager.TYPE_WIFI, NetworkInfo.State.CONNECTED); IntentFilter filter = new IntentFilter(); @@ -402,36 +425,94 @@ public class ConnectivityManagerTest extends AndroidTestCase { boolean connected = false; try { assertTrue(mWifiManager.setWifiEnabled(true)); + // Ensure we get both an onAvailable callback and a CONNECTIVITY_ACTION. + wifiNetwork = callback.waitForAvailable(); + assertNotNull(wifiNetwork); connected = receiver.waitForState(); } catch (InterruptedException ex) { fail("connectToWifi was interrupted"); } finally { + mCm.unregisterNetworkCallback(callback); mContext.unregisterReceiver(receiver); } assertTrue("Wifi must be configured to connect to an access point for this test.", connected); + return wifiNetwork; + } + + private Socket getBoundSocket(Network network, String host, int port) throws IOException { + InetSocketAddress addr = new InetSocketAddress(host, port); + Socket s = network.getSocketFactory().createSocket(); + try { + s.setSoTimeout(SOCKET_TIMEOUT_MS); + s.connect(addr, SOCKET_TIMEOUT_MS); + } catch (IOException e) { + s.close(); + throw e; + } + return s; + } + + private void testHttpRequest(Socket s) throws IOException { + OutputStream out = s.getOutputStream(); + InputStream in = s.getInputStream(); + + final byte[] requestBytes = HTTP_REQUEST.getBytes("UTF-8"); + byte[] responseBytes = new byte[4096]; + out.write(requestBytes); + in.read(responseBytes); + assertTrue(new String(responseBytes, "UTF-8").startsWith("HTTP/1.0 204 No Content\r\n")); } /** Disable WiFi and wait for it to become disconnected from the network. */ - private void disconnectFromWifi() { + private void disconnectFromWifi(Network wifiNetworkToCheck) { + final TestNetworkCallback callback = new TestNetworkCallback(); + mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); + Network lostWifiNetwork = null; + ConnectivityActionReceiver receiver = new ConnectivityActionReceiver( ConnectivityManager.TYPE_WIFI, NetworkInfo.State.DISCONNECTED); IntentFilter filter = new IntentFilter(); filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); mContext.registerReceiver(receiver, filter); + // Assert that we can establish a TCP connection on wifi. + Socket wifiBoundSocket = null; + if (wifiNetworkToCheck != null) { + try { + wifiBoundSocket = getBoundSocket(wifiNetworkToCheck, TEST_HOST, HTTP_PORT); + testHttpRequest(wifiBoundSocket); + } catch (IOException e) { + fail("HTTP request before wifi disconnected failed with: " + e); + } + } + boolean disconnected = false; try { assertTrue(mWifiManager.setWifiEnabled(false)); + // Ensure we get both an onLost callback and a CONNECTIVITY_ACTION. + lostWifiNetwork = callback.waitForLost(); + assertNotNull(lostWifiNetwork); disconnected = receiver.waitForState(); } catch (InterruptedException ex) { fail("disconnectFromWifi was interrupted"); } finally { + mCm.unregisterNetworkCallback(callback); mContext.unregisterReceiver(receiver); } assertTrue("Wifi failed to reach DISCONNECTED state.", disconnected); + + // Check that the socket is closed when wifi disconnects. + if (wifiBoundSocket != null) { + try { + testHttpRequest(wifiBoundSocket); + fail("HTTP request should not succeed after wifi disconnects"); + } catch (IOException expected) { + assertEquals(Os.strerror(OsConstants.ECONNABORTED), expected.getMessage()); + } + } } /** @@ -498,15 +579,48 @@ public class ConnectivityManagerTest extends AndroidTestCase { */ private static class TestNetworkCallback extends ConnectivityManager.NetworkCallback { private final CountDownLatch mAvailableLatch = new CountDownLatch(1); + private final CountDownLatch mLostLatch = new CountDownLatch(1); - public boolean waitForAvailable() throws InterruptedException { - return mAvailableLatch.await(30, TimeUnit.SECONDS); + public Network currentNetwork; + public Network lastLostNetwork; + + public Network waitForAvailable() throws InterruptedException { + return mAvailableLatch.await(30, TimeUnit.SECONDS) ? currentNetwork : null; + } + + public Network waitForLost() throws InterruptedException { + return mLostLatch.await(30, TimeUnit.SECONDS) ? lastLostNetwork : null; } @Override public void onAvailable(Network network) { + currentNetwork = network; mAvailableLatch.countDown(); } + + @Override + public void onLost(Network network) { + lastLostNetwork = network; + if (network.equals(currentNetwork)) { + currentNetwork = null; + } + mLostLatch.countDown(); + } + } + + private Network getWifiNetwork() { + TestNetworkCallback callback = new TestNetworkCallback(); + mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); + Network network = null; + try { + network = callback.waitForAvailable(); + } catch (InterruptedException e) { + fail("NetworkCallback wait was interrupted."); + } finally { + mCm.unregisterNetworkCallback(callback); + } + assertNotNull("Cannot find Network for wifi. Is wifi connected?", network); + return network; } /** Verify restricted networks cannot be requested. */ @@ -523,8 +637,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { try { mCm.requestNetwork(request, callback); fail("No exception thrown when restricted network requested."); - } catch (SecurityException e) { - // Expected. - } + } catch (SecurityException expected) {} } } From 335856c1d39eed0974be2f28dbb8aace83d847c8 Mon Sep 17 00:00:00 2001 From: Marcus Nascimento Date: Tue, 26 Apr 2016 11:32:30 +0100 Subject: [PATCH 0242/1109] Add assertion messages to testStartUsingNetworkFeature_enableHipri. testStartUsingNetworkFeature_enableHipri should be able to reconnect to Wifi Network. Added a prefix to the already defined error message to rerun the test. The ConnectivityManager's startUsingNetworkFeature will fail without SIM card and/or signal. Changed the error message to check SIM card and signal and rerun the test. Bug: 28264205 Change-Id: Ia1b35cab11afa65ae93ea7dab2f7cc3a330d8471 --- .../cts/net/src/android/net/cts/ConnectivityManagerTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 9daf3c421b..120f9984c7 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -283,7 +283,8 @@ public class ConnectivityManagerTest extends AndroidTestCase { assertTrue("Couldn't start using the HIPRI feature.", result != -1); // Check that the ConnectivityManager reported that it connected using hipri... - assertTrue("Couldn't connect using hipri...", receiver.waitForConnection()); + assertTrue("[RERUN] Couldn't connect using hipri. Check signal and SIM.", + receiver.waitForConnection()); assertTrue("Couldn't requestRouteToHost using HIPRI.", mCm.requestRouteToHost(ConnectivityManager.TYPE_MOBILE_HIPRI, HOST_ADDRESS)); @@ -311,7 +312,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { mContext.registerReceiver(receiver, filter); assertTrue(mWifiManager.setWifiEnabled(true)); - assertTrue("Wifi must be configured to connect to an access point for this test.", + assertTrue("[RERUN] Wifi must be configured to connect to an access point for this test.", receiver.waitForConnection()); mContext.unregisterReceiver(receiver); From 51eb8c19a00ea5d4973431822d24d43c75dbbed9 Mon Sep 17 00:00:00 2001 From: Marcus Nascimento Date: Tue, 26 Apr 2016 11:30:30 +0100 Subject: [PATCH 0243/1109] Add assertion message to assertions for testExecute_withMobile. Some partner test devices without a SIM Card or with no signal, thus without mobile network data connection. Added a message to check signal and SIM card and rerun the test. Also added a verification that the network type is supported in the event of a Connectivity Action's timeout. Unsuported network type could be caused by a network stack crash. Bug: 28207677 Change-Id: Ibca50359df7d5fb8371f4f4037fc81f029f48b30 --- .../net/http/cts/ApacheHttpClientTest.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/tests/cts/net/src/android/net/http/cts/ApacheHttpClientTest.java b/tests/cts/net/src/android/net/http/cts/ApacheHttpClientTest.java index 7d9189ff33..91b65b6967 100644 --- a/tests/cts/net/src/android/net/http/cts/ApacheHttpClientTest.java +++ b/tests/cts/net/src/android/net/http/cts/ApacheHttpClientTest.java @@ -146,7 +146,8 @@ public class ApacheHttpClientTest extends AndroidTestCase { mContext.registerReceiver(receiver, filter); assertTrue(mWifiManager.setWifiEnabled(true)); - assertTrue("Wifi must be configured to connect to an access point for this test.", + assertTrue( + "[RERUN] Wifi must be configured to connect to an access point for this test.", receiver.waitForStateChange()); mContext.unregisterReceiver(receiver); @@ -165,9 +166,11 @@ public class ApacheHttpClientTest extends AndroidTestCase { mContext.registerReceiver(connectMobileReceiver, filter); mContext.registerReceiver(disconnectWifiReceiver, filter); - assertTrue(mWifiManager.setWifiEnabled(false)); - assertTrue(disconnectWifiReceiver.waitForStateChange()); - assertTrue(connectMobileReceiver.waitForStateChange()); + assertTrue("Wifi did not disconnect.", mWifiManager.setWifiEnabled(false)); + assertTrue("Timeout waiting for wifi to disconnect.", + disconnectWifiReceiver.waitForStateChange()); + assertTrue("[RERUN] Timeout waiting for mobile network. Check signal and SIM.", + connectMobileReceiver.waitForStateChange()); mContext.unregisterReceiver(connectMobileReceiver); mContext.unregisterReceiver(disconnectWifiReceiver); @@ -204,7 +207,10 @@ public class ApacheHttpClientTest extends AndroidTestCase { } private boolean hasExpectedState() { - return mExpectedState == mConnectivityManager.getNetworkInfo(mNetworkType).getState(); + NetworkInfo network = mConnectivityManager.getNetworkInfo(mNetworkType); + assertNotNull("Network type should be supported but it is not. Type: " + mNetworkType, + network); + return mExpectedState == network.getState(); } } } From fa8e24c3e68264eaf6444d203567f7a579290422 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Wed, 27 Apr 2016 17:01:31 -0700 Subject: [PATCH 0244/1109] Added test for required packages whitelisted for Data Saver Mode. Also fixed code that checks for whitelist uids, otherwise it would pass when the required uid is missing but a superset was present (for example, when asking for 1009 but 10090 was whitelisted). BUG: 28431507 Change-Id: Iaaa67e586907dba215496460445ad627ba7b63c5 --- ...ractRestrictBackgroundNetworkTestCase.java | 14 +++++++---- .../cts/net/hostside/DataSaverModeTest.java | 24 +++++++++++++++++++ ...ostsideRestrictBackgroundNetworkTests.java | 5 ++++ 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 27d4a2b2ef..ce9d9704cd 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -377,18 +377,24 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation private void assertRestrictBackground(String list, int uid, boolean expected) throws Exception { final int maxTries = 5; boolean actual = false; + final String expectedUid = Integer.toString(uid); + String uids = ""; for (int i = 1; i <= maxTries; i++) { final String output = executeShellCommand("cmd netpolicy list " + list); - actual = output.contains(Integer.toString(uid)); - if (expected == actual) { - return; + uids = output.split(":")[1]; + for (String candidate : uids.split(" ")) { + actual = candidate.trim().equals(expectedUid); + if (expected == actual) { + return; + } } Log.v(TAG, list + " check for uid " + uid + " doesn't match yet (expected " + expected + ", got " + actual + "); sleeping 1s before polling again"); Thread.sleep(SECOND_IN_MS); } - fail(list + " check for uid " + uid + " failed: expected " + expected + ", got " + actual); + fail(list + " check for uid " + uid + " failed: expected " + expected + ", got " + actual + + ". Full list: " + uids); } protected void assertPowerSaveModeWhitelist(String packageName, boolean expected) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index 62f670ed43..d7604755fe 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -31,6 +31,10 @@ import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELI */ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase { + private static final String[] REQUIRED_WHITELISTED_PACKAGES = { + "com.android.providers.downloads" + }; + @Override public void setUp() throws Exception { super.setUp(); @@ -108,4 +112,24 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertRestrictBackgroundChangedReceived(5); assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); } + + public void testGetRestrictBackgroundStatus_requiredWhitelistedPackages() throws Exception { + final StringBuilder error = new StringBuilder(); + for (String packageName : REQUIRED_WHITELISTED_PACKAGES) { + int uid = -1; + try { + uid = getUid(packageName); + assertRestrictBackgroundWhitelist(uid, true); + } catch (Throwable t) { + error.append("\nFailed for '").append(packageName).append("'"); + if (uid > 0) { + error.append(" (uid ").append(uid).append(")"); + } + error.append(": ").append(t).append("\n"); + } + } + if (error.length() > 0) { + fail(error.toString()); + } + } } diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java index 15a4e0a84f..ca535bc6d2 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java @@ -73,6 +73,11 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC assertRestrictBackgroundWhitelist(newUid, false); } + public void testDataSaverMode_requiredWhitelistedPackages() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".DataSaverModeTest", + "testGetRestrictBackgroundStatus_requiredWhitelistedPackages"); + } + public void testBatterySaverMode_disabled() throws Exception { runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeTest", "testBackgroundNetworkAccess_disabled"); From 50bce69fabb711b48ec7e4502cfa9115a31fc1e0 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Fri, 29 Apr 2016 15:23:34 -0700 Subject: [PATCH 0245/1109] Improved connectivity check by also asserting NetworkInfo states. BUG: 28473659 BUG: 26571724 Change-Id: Iba687003431ed5c353412268726967a798f538da --- ...ractRestrictBackgroundNetworkTestCase.java | 41 +++++++++----- .../net/hostside/BatterySaverModeTest.java | 1 + .../android/cts/net/hostside/app2/Common.java | 3 - .../hostside/app2/MyBroadcastReceiver.java | 55 +++++++++++++++---- ...ostsideRestrictBackgroundNetworkTests.java | 6 +- 5 files changed, 76 insertions(+), 30 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index ce9d9704cd..08df9e1bbc 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -25,13 +25,14 @@ import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELI import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import android.app.ActivityManager; import android.app.Instrumentation; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; +import android.net.NetworkInfo.DetailedState; +import android.net.NetworkInfo.State; import android.net.wifi.WifiManager; import android.test.InstrumentationTestCase; import android.util.Log; @@ -61,8 +62,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation private static final String EXTRA_RECEIVER_NAME = "com.android.cts.net.hostside.app2.extra.RECEIVER_NAME"; private static final String RESULT_SEPARATOR = ";"; - private static final String STATUS_NETWORK_UNAVAILABLE_PREFIX = "NetworkUnavailable:"; - private static final String STATUS_NETWORK_AVAILABLE_PREFIX = "NetworkAvailable:"; + private static final String NETWORK_STATUS_SEPARATOR = "\\|"; private static final int SECOND_IN_MS = 1000; private static final int NETWORK_TIMEOUT_MS = 15 * SECOND_IN_MS; private static final int PROCESS_STATE_FOREGROUND_SERVICE = 4; @@ -144,7 +144,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation }, null, 0, null, null); final String resultData = result.poll(timeoutMs, TimeUnit.MILLISECONDS); - Log.d(TAG, "Ordered broadcast response: " + resultData); + Log.d(TAG, "Ordered broadcast response after " + timeoutMs + "ms: " + resultData ); return resultData; } @@ -206,17 +206,30 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation } private void assertNetworkStatus(boolean expectAvailable, String status) throws Exception { - if (status == null) { - Log.d(TAG, "timeout waiting for ordered broadcast"); - if (expectAvailable) { - fail("did not get network status when access was allowed"); - } - return; + assertNotNull("timeout waiting for ordered broadcast", status); + + // Network status format is described on MyBroadcastReceiver.checkNetworkStatus() + final String[] parts = status.split(NETWORK_STATUS_SEPARATOR); + assertEquals("Wrong network status: " + status, 5, parts.length); // Sanity check + final State state = State.valueOf(parts[0]); + final DetailedState detailedState = DetailedState.valueOf(parts[1]); + final boolean connected = Boolean.valueOf(parts[2]); + final String connectionCheckDetails = parts[3]; + final String networkInfo = parts[4]; + + if (expectAvailable) { + assertTrue("should be connected: " + connectionCheckDetails + + " (network info: " + networkInfo + ")", connected); + assertEquals("wrong state for " + networkInfo, State.CONNECTED, state); + assertEquals("wrong detailed state for " + networkInfo, + DetailedState.CONNECTED, detailedState); + } else { + assertFalse("should not be connected: " + connectionCheckDetails + + " (network info: " + networkInfo + ")", connected); + assertEquals("wrong state for " + networkInfo, State.DISCONNECTED, state); + assertEquals("wrong detailed state for " + networkInfo, + DetailedState.BLOCKED, detailedState); } - final String expectedPrefix = expectAvailable ? - STATUS_NETWORK_AVAILABLE_PREFIX : STATUS_NETWORK_UNAVAILABLE_PREFIX; - assertTrue("Wrong network status (" + status + ") when expectedAvailable is " - + expectAvailable, status.startsWith(expectedPrefix)); } protected String executeShellCommand(String command) throws Exception { diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java index d1217b4ed7..e5466cdbb9 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java @@ -42,6 +42,7 @@ public class BatterySaverModeTest extends AbstractRestrictBackgroundNetworkTestC public void testBackgroundNetworkAccess_enabled() throws Exception { setPowerSaveMode(true); + assertBackgroundNetworkAccess(false); // Make sure app is allowed if running a foreground service. diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java index 668669bc2e..d247c3177c 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java @@ -17,7 +17,6 @@ package com.android.cts.net.hostside.app2; import android.content.Context; import android.content.pm.PackageManager.NameNotFoundException; -import android.util.Log; public final class Common { @@ -37,8 +36,6 @@ public final class Common { static final String EXTRA_RECEIVER_NAME = "com.android.cts.net.hostside.app2.extra.RECEIVER_NAME"; static final char RESULT_SEPARATOR = ';'; - static final String STATUS_NETWORK_UNAVAILABLE_PREFIX = "NetworkUnavailable:"; - static final String STATUS_NETWORK_AVAILABLE_PREFIX = "NetworkAvailable:"; static int getUid(Context context) { final String packageName = context.getPackageName(); diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java index 07f717b192..e8a959c41e 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java @@ -24,8 +24,6 @@ import static com.android.cts.net.hostside.app2.Common.EXTRA_ACTION; import static com.android.cts.net.hostside.app2.Common.EXTRA_RECEIVER_NAME; import static com.android.cts.net.hostside.app2.Common.MANIFEST_RECEIVER; import static com.android.cts.net.hostside.app2.Common.RESULT_SEPARATOR; -import static com.android.cts.net.hostside.app2.Common.STATUS_NETWORK_AVAILABLE_PREFIX; -import static com.android.cts.net.hostside.app2.Common.STATUS_NETWORK_UNAVAILABLE_PREFIX; import static com.android.cts.net.hostside.app2.Common.TAG; import static com.android.cts.net.hostside.app2.Common.getUid; @@ -125,6 +123,38 @@ public class MyBroadcastReceiver extends BroadcastReceiver { setResultData(data.toString()); } + + private static final String NETWORK_STATUS_TEMPLATE = "%s|%s|%s|%s|%s"; + + /** + * Checks whether the network is available and return a string which can then be send as a + * result data for the ordered broadcast. + * + *

+ * The string has the following format: + * + *


+     * NetinfoState|NetinfoDetailedState|RealConnectionCheck|RealConnectionCheckDetails|Netinfo
+     * 
+ * + *

Where: + * + *

    + *
  • {@code NetinfoState}: enum value of {@link NetworkInfo.State}. + *
  • {@code NetinfoDetailedState}: enum value of {@link NetworkInfo.DetailedState}. + *
  • {@code RealConnectionCheck}: boolean value of a real connection check (i.e., an attempt + * to access an external website. + *
  • {@code RealConnectionCheckDetails}: if HTTP output core or exception string of the real + * connection attempt + *
  • {@code Netinfo}: string representation of the {@link NetworkInfo}. + *
+ * + * For example, if the connection was established fine, the result would be something like: + *


+     * CONNECTED|CONNECTED|true|200|[type: WIFI[], state: CONNECTED/CONNECTED, reason: ...]
+     * 
+ * + */ private String checkNetworkStatus(final Context context, final ConnectivityManager cm) throws InterruptedException { final LinkedBlockingQueue result = new LinkedBlockingQueue<>(1); @@ -138,24 +168,29 @@ public class MyBroadcastReceiver extends BroadcastReceiver { Log.d(TAG, "Running checkNetworkStatus() on thread " + Thread.currentThread().getName() + " for UID " + getUid(context) + "\n\tactiveNetworkInfo: " + networkInfo + "\n\tURL: " + address); - String prefix = STATUS_NETWORK_AVAILABLE_PREFIX; + boolean checkStatus = false; + String checkDetails = "N/A"; try { final URL url = new URL(address); final HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(NETWORK_TIMEOUT_MS); - conn.setConnectTimeout(NETWORK_TIMEOUT_MS); + conn.setConnectTimeout(NETWORK_TIMEOUT_MS / 2); conn.setRequestMethod("GET"); conn.setDoInput(true); conn.connect(); final int response = conn.getResponseCode(); - Log.d(TAG, "HTTP response for " + address + ": " + response); + checkStatus = true; + checkDetails = "HTTP response for " + address + ": " + response; } catch (Exception e) { - Log.d(TAG, "Exception getting " + address + ": " + e); - prefix = STATUS_NETWORK_UNAVAILABLE_PREFIX + "Exception " + e + ":"; + checkStatus = false; + checkDetails = "Exception getting " + address + ": " + e; } - final String netInfo = prefix + networkInfo; - Log.d(TAG, "Offering " + netInfo); - result.offer(netInfo); + Log.d(TAG, checkDetails); + final String status = String.format(NETWORK_STATUS_TEMPLATE, + networkInfo.getState().name(), networkInfo.getDetailedState().name(), + Boolean.toString(checkStatus), checkDetails, networkInfo); + Log.d(TAG, "Offering " + status); + result.offer(status); } }, mName).start(); return result.poll(NETWORK_TIMEOUT_MS * 2, TimeUnit.MILLISECONDS); diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java index ca535bc6d2..435e201ec1 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java @@ -104,17 +104,17 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC assertPowerSaveModeWhitelist(TEST_PKG, false); } - public void testBatteryBatterySaverModeNonMeteredTest_disabled() throws Exception { + public void testBatterySaverModeNonMetered_disabled() throws Exception { runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeNonMeteredTest", "testBackgroundNetworkAccess_disabled"); } - public void testBatteryBatterySaverModeNonMeteredTest_whitelisted() throws Exception { + public void testBatterySaverModeNonMeteredt_whitelisted() throws Exception { runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeNonMeteredTest", "testBackgroundNetworkAccess_whitelisted"); } - public void testBatteryBatterySaverModeNonMeteredTest_enabled() throws Exception { + public void testBatterySaverModeNonMetered_enabled() throws Exception { runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeNonMeteredTest", "testBackgroundNetworkAccess_enabled"); } From 691e85def733e6c8c3066c25448e51edad47f1dd Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Wed, 4 May 2016 11:46:08 -0700 Subject: [PATCH 0246/1109] Temporarily disable NetworkInfo check. There are known issues that cause these check to fail, and the fix has not been submitted yet. BUG: 28473659 BUG: 28521946 Change-Id: I26dfbebc2d07396ef89ac78230645e4791c708ee --- ...tractRestrictBackgroundNetworkTestCase.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 08df9e1bbc..08c8fdbcee 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -71,6 +71,8 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation // Must be higher than NETWORK_TIMEOUT_MS private static final int ORDERED_BROADCAST_TIMEOUT_MS = NETWORK_TIMEOUT_MS * 4; + private static final boolean ASSERT_NETWORK_INFO_STATE = false; + protected Context mContext; protected Instrumentation mInstrumentation; protected ConnectivityManager mCm; @@ -220,15 +222,19 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation if (expectAvailable) { assertTrue("should be connected: " + connectionCheckDetails + " (network info: " + networkInfo + ")", connected); - assertEquals("wrong state for " + networkInfo, State.CONNECTED, state); - assertEquals("wrong detailed state for " + networkInfo, - DetailedState.CONNECTED, detailedState); + if (ASSERT_NETWORK_INFO_STATE) { + assertEquals("wrong state for " + networkInfo, State.CONNECTED, state); + assertEquals("wrong detailed state for " + networkInfo, + DetailedState.CONNECTED, detailedState); + } } else { assertFalse("should not be connected: " + connectionCheckDetails + " (network info: " + networkInfo + ")", connected); - assertEquals("wrong state for " + networkInfo, State.DISCONNECTED, state); - assertEquals("wrong detailed state for " + networkInfo, - DetailedState.BLOCKED, detailedState); + if (ASSERT_NETWORK_INFO_STATE) { + assertEquals("wrong state for " + networkInfo, State.DISCONNECTED, state); + assertEquals("wrong detailed state for " + networkInfo, + DetailedState.BLOCKED, detailedState); + } } } From aa2e8ea1d8b62ea6b6ffd3a507f7f3b797a33c1e Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Thu, 5 May 2016 14:46:53 -0700 Subject: [PATCH 0247/1109] Assert whitelists are revoked on uninstall. BUG: 28616418 Change-Id: I909fd4c6024afe5b42560090c6e2f11b43c220de --- .../cts/net/hostside/DataSaverModeTest.java | 6 ++- ...ostsideRestrictBackgroundNetworkTests.java | 39 +++++++++++++------ 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index d7604755fe..60c2b9ba6c 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -73,7 +73,11 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase addRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundChangedReceived(2); assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_WHITELISTED); - } + + removeRestrictBackgroundWhitelist(mUid); + assertRestrictBackgroundChangedReceived(3); + assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); + } public void testGetRestrictBackgroundStatus_enabled() throws Exception { setRestrictBackground(true); diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java index 435e201ec1..ece09c84f5 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java @@ -60,15 +60,17 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC } public void testDataSaverMode_reinstall() throws Exception { - final int oldUid = getUid(TEST_PKG); - testDataSaverMode_whitelisted(); + final int oldUid = getUid(TEST_APP2_PKG); - uninstallPackage(TEST_PKG, true); - assertPackageUninstalled(TEST_PKG); + // Make sure whitelist is revoked when package is removed + addRestrictBackgroundWhitelist(oldUid); + + uninstallPackage(TEST_APP2_PKG, true); + assertPackageUninstalled(TEST_APP2_PKG); assertRestrictBackgroundWhitelist(oldUid, false); - installPackage(TEST_APK); - final int newUid = getUid(TEST_PKG); + installPackage(TEST_APP2_APK); + final int newUid = getUid(TEST_APP2_PKG); assertRestrictBackgroundWhitelist(oldUid, false); assertRestrictBackgroundWhitelist(newUid, false); } @@ -94,14 +96,14 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC } public void testBatterySaverMode_reinstall() throws Exception { - testBatterySaverMode_whitelisted(); + addPowerSaveModeWhitelist(TEST_APP2_PKG); - uninstallPackage(TEST_PKG, true); - assertPackageUninstalled(TEST_PKG); - assertPowerSaveModeWhitelist(TEST_PKG, false); + uninstallPackage(TEST_APP2_PKG, true); + assertPackageUninstalled(TEST_APP2_PKG); + assertPowerSaveModeWhitelist(TEST_APP2_PKG, false); - installPackage(TEST_APK); - assertPowerSaveModeWhitelist(TEST_PKG, false); + installPackage(TEST_APP2_APK); + assertPowerSaveModeWhitelist(TEST_APP2_PKG, false); } public void testBatterySaverModeNonMetered_disabled() throws Exception { @@ -160,4 +162,17 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC fail("Command '" + command + "' did not return '" + expectedResult + "' after " + maxTries + " attempts"); } + + protected void addRestrictBackgroundWhitelist(int uid) throws Exception { + runCommand("cmd netpolicy add restrict-background-whitelist " + uid); + assertRestrictBackgroundWhitelist(uid, true); + } + + private void addPowerSaveModeWhitelist(String packageName) throws Exception { + Log.i(TAG, "Adding package " + packageName + " to power-save-mode whitelist"); + // TODO: currently the power-save mode is behaving like idle, but once it changes, we'll + // need to use netpolicy for whitelisting + runCommand("dumpsys deviceidle whitelist +" + packageName); + assertPowerSaveModeWhitelist(packageName, true); // Sanity check + } } From 6cd41f6d03936d4c64cea805b347f691735c0d82 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Fri, 29 Apr 2016 16:48:14 -0700 Subject: [PATCH 0248/1109] Asserts foreground apps always have network access. BUG: 28473659 Change-Id: Iea6933a4630ff2e9c00a2d2e9e4a6f1a51de70f2 --- ...ractRestrictBackgroundNetworkTestCase.java | 117 +++++++++++------- .../BatterySaverModeNonMeteredTest.java | 13 ++ .../net/hostside/BatterySaverModeTest.java | 12 ++ .../cts/net/hostside/DataSaverModeTest.java | 46 +++++-- tests/cts/hostside/app2/AndroidManifest.xml | 2 + .../android/cts/net/hostside/app2/Common.java | 2 + .../cts/net/hostside/app2/MyActivity.java | 38 ++++++ .../hostside/app2/MyBroadcastReceiver.java | 27 ++-- ...ostsideRestrictBackgroundNetworkTests.java | 2 +- 9 files changed, 188 insertions(+), 71 deletions(-) create mode 100644 tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 08c8fdbcee..3ee2f6868e 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -54,6 +54,8 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation private static final String DYNAMIC_RECEIVER = "DynamicReceiver"; private static final String ACTION_GET_COUNTERS = "com.android.cts.net.hostside.app2.action.GET_COUNTERS"; + private static final String ACTION_GET_RESTRICT_BACKGROUND_STATUS = + "com.android.cts.net.hostside.app2.action.GET_RESTRICT_BACKGROUND_STATUS"; private static final String ACTION_CHECK_NETWORK = "com.android.cts.net.hostside.app2.action.CHECK_NETWORK"; private static final String ACTION_RECEIVER_READY = @@ -61,7 +63,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation private static final String EXTRA_ACTION = "com.android.cts.net.hostside.app2.extra.ACTION"; private static final String EXTRA_RECEIVER_NAME = "com.android.cts.net.hostside.app2.extra.RECEIVER_NAME"; - private static final String RESULT_SEPARATOR = ";"; private static final String NETWORK_STATUS_SEPARATOR = "\\|"; private static final int SECOND_IN_MS = 1000; private static final int NETWORK_TIMEOUT_MS = 15 * SECOND_IN_MS; @@ -71,8 +72,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation // Must be higher than NETWORK_TIMEOUT_MS private static final int ORDERED_BROADCAST_TIMEOUT_MS = NETWORK_TIMEOUT_MS * 4; - private static final boolean ASSERT_NETWORK_INFO_STATE = false; - protected Context mContext; protected Instrumentation mInstrumentation; protected ConnectivityManager mCm; @@ -159,27 +158,22 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation return Integer.valueOf(resultData); } - protected void assertRestrictBackgroundStatus(int expectedApiStatus) throws Exception { - assertBackgroundState(); // Sanity check. - final Intent intent = new Intent(ACTION_CHECK_NETWORK); + protected void assertRestrictBackgroundStatus(int expectedStatus) throws Exception { + final Intent intent = new Intent(ACTION_GET_RESTRICT_BACKGROUND_STATUS); final String resultData = sendOrderedBroadcast(intent); - final String[] resultItems = resultData.split(RESULT_SEPARATOR); - final String actualApiStatus = toString(Integer.parseInt(resultItems[0])); - // First asserts the API returns the proper value... - assertEquals("wrong status", toString(expectedApiStatus), actualApiStatus); - - //...then the actual network status in the background thread. - final String networkStatus = getNetworkStatus(resultItems); - assertNetworkStatus(expectedApiStatus != RESTRICT_BACKGROUND_STATUS_ENABLED, networkStatus); + assertNotNull("timeout waiting for ordered broadcast result", resultData); + final String actualStatus = toString(Integer.parseInt(resultData)); + assertEquals("wrong status", toString(expectedStatus), actualStatus); } protected void assertBackgroundNetworkAccess(boolean expectAllowed) throws Exception { assertBackgroundState(); // Sanity check. - final Intent intent = new Intent(ACTION_CHECK_NETWORK); - final String resultData = sendOrderedBroadcast(intent); - final String[] resultItems = resultData.split(RESULT_SEPARATOR); - final String networkStatus = getNetworkStatus(resultItems); - assertNetworkStatus(expectAllowed, networkStatus); + assertNetworkAccess(expectAllowed); + } + + protected void assertForegroundNetworkAccess() throws Exception { + assertForegroundState(); // Sanity check. + assertNetworkAccess(true); } protected final void assertBackgroundState() throws Exception { @@ -189,6 +183,13 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation assertTrue("App2 is not on background state: " + state, isBackground); } + protected final void assertForegroundState() throws Exception { + final ProcessState state = getProcessStateByUid(mUid); + Log.v(TAG, "assertForegroundState(): status for app2 (" + mUid + "): " + state); + final boolean isForeground = !isBackground(state.state); + assertTrue("App2 is not on foreground state: " + state, isForeground); + } + protected final void assertForegroundServiceState() throws Exception { final ProcessState state = getProcessStateByUid(mUid); Log.v(TAG, "assertForegroundServiceState(): status for app2 (" + mUid + "): " + state); @@ -203,39 +204,54 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation return state >= PROCESS_STATE_FOREGROUND_SERVICE; } - private String getNetworkStatus(String[] resultItems) { - return resultItems.length < 2 ? null : resultItems[1]; - } + private void assertNetworkAccess(boolean expectAvailable) throws Exception { + final Intent intent = new Intent(ACTION_CHECK_NETWORK); - private void assertNetworkStatus(boolean expectAvailable, String status) throws Exception { - assertNotNull("timeout waiting for ordered broadcast", status); + // When the network info state change, it's possible the app still get the previous value, + // so we need to retry a couple times. + final int maxTries = 5; + String resultData = null; + for (int i = 1; i <= maxTries; i++) { + resultData = sendOrderedBroadcast(intent); + assertNotNull("timeout waiting for ordered broadcast", resultData); - // Network status format is described on MyBroadcastReceiver.checkNetworkStatus() - final String[] parts = status.split(NETWORK_STATUS_SEPARATOR); - assertEquals("Wrong network status: " + status, 5, parts.length); // Sanity check - final State state = State.valueOf(parts[0]); - final DetailedState detailedState = DetailedState.valueOf(parts[1]); - final boolean connected = Boolean.valueOf(parts[2]); - final String connectionCheckDetails = parts[3]; - final String networkInfo = parts[4]; + // Network status format is described on MyBroadcastReceiver.checkNetworkStatus() + final String[] parts = resultData.split(NETWORK_STATUS_SEPARATOR); + assertEquals("Wrong network status: " + resultData, 5, parts.length); // Sanity check + final State state = State.valueOf(parts[0]); + final DetailedState detailedState = DetailedState.valueOf(parts[1]); + final boolean connected = Boolean.valueOf(parts[2]); + final String connectionCheckDetails = parts[3]; + final String networkInfo = parts[4]; - if (expectAvailable) { - assertTrue("should be connected: " + connectionCheckDetails - + " (network info: " + networkInfo + ")", connected); - if (ASSERT_NETWORK_INFO_STATE) { - assertEquals("wrong state for " + networkInfo, State.CONNECTED, state); - assertEquals("wrong detailed state for " + networkInfo, - DetailedState.CONNECTED, detailedState); - } - } else { - assertFalse("should not be connected: " + connectionCheckDetails - + " (network info: " + networkInfo + ")", connected); - if (ASSERT_NETWORK_INFO_STATE) { - assertEquals("wrong state for " + networkInfo, State.DISCONNECTED, state); - assertEquals("wrong detailed state for " + networkInfo, - DetailedState.BLOCKED, detailedState); + if (expectAvailable) { + assertTrue("should be connected: " + connectionCheckDetails + + " (network info: " + networkInfo + ")", connected); + if (state != State.CONNECTED) { + Log.d(TAG, "State (" + state + ") not set to CONNECTED on attempt #" + i + + "; sleeping 1s before trying again"); + Thread.sleep(SECOND_IN_MS); + } else { + assertEquals("wrong detailed state for " + networkInfo, + DetailedState.CONNECTED, detailedState); + return; + } + return; + } else { + assertFalse("should not be connected: " + connectionCheckDetails + + " (network info: " + networkInfo + ")", connected); + if (state != State.DISCONNECTED) { + Log.d(TAG, "State (" + state + ") not set to DISCONNECTED on attempt #" + i + + "; sleeping 1s before trying again"); + Thread.sleep(SECOND_IN_MS); + } else { + assertEquals("wrong detailed state for " + networkInfo, + DetailedState.BLOCKED, detailedState); + return; + } } } + fail("Invalid state after " + maxTries + " attempts. Last data: " + resultData); } protected String executeShellCommand(String command) throws Exception { @@ -479,6 +495,13 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation "am startservice com.android.cts.net.hostside.app2/.MyForegroundService"); } + /** + * Launches an activity on app2 so its process is elevated to foreground status. + */ + protected void launchApp2Activity() throws Exception { + executeShellCommand("am start com.android.cts.net.hostside.app2/.MyActivity"); + } + private String toString(int status) { switch (status) { case RESTRICT_BACKGROUND_STATUS_DISABLED: diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java index 8e83fa2b7f..5f5f80bf2c 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java @@ -38,10 +38,15 @@ public class BatterySaverModeNonMeteredTest extends AbstractRestrictBackgroundNe public void testBackgroundNetworkAccess_enabled() throws Exception { setPowerSaveMode(true); assertBackgroundNetworkAccess(false); + // Make sure app is allowed if running a foreground service. startForegroundService(); assertForegroundServiceState(); assertBackgroundNetworkAccess(true); + + // Should always have access when running on foreground + launchApp2Activity(); + assertForegroundNetworkAccess(); } public void testBackgroundNetworkAccess_whitelisted() throws Exception { @@ -51,10 +56,18 @@ public class BatterySaverModeNonMeteredTest extends AbstractRestrictBackgroundNe assertBackgroundNetworkAccess(true); removePowerSaveModeWhitelist(TEST_APP2_PKG); assertBackgroundNetworkAccess(false); + + // Should always have access when running on foreground + launchApp2Activity(); + assertForegroundNetworkAccess(); } public void testBackgroundNetworkAccess_disabled() throws Exception { setPowerSaveMode(false); assertBackgroundNetworkAccess(true); + + // Should always have access when running on foreground + launchApp2Activity(); + assertForegroundNetworkAccess(); } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java index e5466cdbb9..539c598c08 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java @@ -49,6 +49,10 @@ public class BatterySaverModeTest extends AbstractRestrictBackgroundNetworkTestC startForegroundService(); assertForegroundServiceState(); assertBackgroundNetworkAccess(true); + + // Should always have access when running on foreground + launchApp2Activity(); + assertForegroundNetworkAccess(); } public void testBackgroundNetworkAccess_whitelisted() throws Exception { @@ -58,10 +62,18 @@ public class BatterySaverModeTest extends AbstractRestrictBackgroundNetworkTestC assertBackgroundNetworkAccess(true); removePowerSaveModeWhitelist(TEST_APP2_PKG); assertBackgroundNetworkAccess(false); + + // Should always have access when running on foreground + launchApp2Activity(); + assertForegroundNetworkAccess(); } public void testBackgroundNetworkAccess_disabled() throws Exception { setPowerSaveMode(false); assertBackgroundNetworkAccess(true); + + // Should always have access when running on foreground + launchApp2Activity(); + assertForegroundNetworkAccess(); } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index 60c2b9ba6c..09717701d8 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -58,12 +58,16 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase public void testGetRestrictBackgroundStatus_disabled() throws Exception { removeRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundChangedReceived(0); - assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED); // Sanity check: make sure status is always disabled, never whitelisted addRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundChangedReceived(0); - assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED); + + // Should always have access when running on foreground + launchApp2Activity(); + assertForegroundNetworkAccess(); } public void testGetRestrictBackgroundStatus_whitelisted() throws Exception { @@ -72,49 +76,64 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase addRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundChangedReceived(2); - assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_WHITELISTED); + assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_WHITELISTED); removeRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundChangedReceived(3); assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); - } + + // Should always have access when running on foreground + launchApp2Activity(); + assertForegroundNetworkAccess(); + } public void testGetRestrictBackgroundStatus_enabled() throws Exception { setRestrictBackground(true); assertRestrictBackgroundChangedReceived(1); - assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); + assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); removeRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundChangedReceived(1); - assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); + assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); // Make sure app is allowed if running a foreground service. assertBackgroundNetworkAccess(false); startForegroundService(); assertForegroundServiceState(); assertBackgroundNetworkAccess(true); + + // Should always have access when running on foreground + launchApp2Activity(); + assertForegroundNetworkAccess(); } public void testGetRestrictBackgroundStatus_blacklisted() throws Exception { addRestrictBackgroundBlacklist(mUid); assertRestrictBackgroundChangedReceived(1); - assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); + assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); // Make sure blacklist prevails over whitelist. setRestrictBackground(true); assertRestrictBackgroundChangedReceived(2); - assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); + assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); addRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundChangedReceived(3); - assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); + assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); // Check status after removing blacklist. removeRestrictBackgroundBlacklist(mUid); assertRestrictBackgroundChangedReceived(4); - assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_WHITELISTED); + assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_WHITELISTED); setRestrictBackground(false); assertRestrictBackgroundChangedReceived(5); - assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED); + + // Should always have access when running on foreground + addRestrictBackgroundBlacklist(mUid); + assertRestrictBackgroundChangedReceived(6); + assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); + launchApp2Activity(); + assertForegroundNetworkAccess(); } public void testGetRestrictBackgroundStatus_requiredWhitelistedPackages() throws Exception { @@ -136,4 +155,9 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase fail(error.toString()); } } + + private void assertDataSaverStatusOnBackground(int expectedStatus) throws Exception { + assertRestrictBackgroundStatus(expectedStatus); + assertBackgroundNetworkAccess(expectedStatus != RESTRICT_BACKGROUND_STATUS_ENABLED); + } } diff --git a/tests/cts/hostside/app2/AndroidManifest.xml b/tests/cts/hostside/app2/AndroidManifest.xml index 9ce57817de..9c4884b525 100644 --- a/tests/cts/hostside/app2/AndroidManifest.xml +++ b/tests/cts/hostside/app2/AndroidManifest.xml @@ -31,6 +31,7 @@ test app. --> + @@ -38,6 +39,7 @@ + diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java index d247c3177c..ed58184576 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java @@ -28,6 +28,8 @@ public final class Common { static final String DYNAMIC_RECEIVER = "DynamicReceiver"; static final String ACTION_GET_COUNTERS = "com.android.cts.net.hostside.app2.action.GET_COUNTERS"; + static final String ACTION_GET_RESTRICT_BACKGROUND_STATUS = + "com.android.cts.net.hostside.app2.action.GET_RESTRICT_BACKGROUND_STATUS"; static final String ACTION_CHECK_NETWORK = "com.android.cts.net.hostside.app2.action.CHECK_NETWORK"; static final String ACTION_RECEIVER_READY = diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java new file mode 100644 index 0000000000..7c6b50494d --- /dev/null +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2016 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.cts.net.hostside.app2; + +import static com.android.cts.net.hostside.app2.Common.TAG; +import android.app.Activity; +import android.util.Log; + +/** + * Activity used to bring process to foreground. + */ +public class MyActivity extends Activity { + + @Override + protected void onStart() { + super.onStart(); + Log.d(TAG, "MyActivity.onStart()"); + } + + @Override + protected void onDestroy() { + Log.d(TAG, "MyActivity.onDestroy()"); + super.onDestroy(); + } +} diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java index e8a959c41e..b876276899 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java @@ -19,6 +19,7 @@ package com.android.cts.net.hostside.app2; import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; import static com.android.cts.net.hostside.app2.Common.ACTION_CHECK_NETWORK; import static com.android.cts.net.hostside.app2.Common.ACTION_GET_COUNTERS; +import static com.android.cts.net.hostside.app2.Common.ACTION_GET_RESTRICT_BACKGROUND_STATUS; import static com.android.cts.net.hostside.app2.Common.ACTION_RECEIVER_READY; import static com.android.cts.net.hostside.app2.Common.EXTRA_ACTION; import static com.android.cts.net.hostside.app2.Common.EXTRA_RECEIVER_NAME; @@ -73,6 +74,9 @@ public class MyBroadcastReceiver extends BroadcastReceiver { case ACTION_GET_COUNTERS: setResultDataFromCounter(context, intent); break; + case ACTION_GET_RESTRICT_BACKGROUND_STATUS: + getRestrictBackgroundStatus(context, intent); + break; case ACTION_CHECK_NETWORK: checkNetwork(context, intent); break; @@ -101,31 +105,30 @@ public class MyBroadcastReceiver extends BroadcastReceiver { return value; } + private void getRestrictBackgroundStatus(Context context, Intent intent) { + final ConnectivityManager cm = (ConnectivityManager) context + .getSystemService(Context.CONNECTIVITY_SERVICE); + final int apiStatus = cm.getRestrictBackgroundStatus(); + Log.d(TAG, "getRestrictBackgroundStatus: returning " + apiStatus); + setResultData(Integer.toString(apiStatus)); + } + private void checkNetwork(final Context context, Intent intent) { final ConnectivityManager cm = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); - final StringBuilder data = new StringBuilder(); - final int apiStatus = cm.getRestrictBackgroundStatus(); - String netStatus; + String netStatus = null; try { netStatus = checkNetworkStatus(context, cm); } catch (InterruptedException e) { Log.e(TAG, "Timeout checking network status"); - setResultData(null); - return; } - data.append(apiStatus).append(RESULT_SEPARATOR); - if (netStatus != null) { - data.append(netStatus); - } - Log.d(TAG, "checkNetwork: returning " + data); - setResultData(data.toString()); + Log.d(TAG, "checkNetwork(): returning " + netStatus); + setResultData(netStatus); } private static final String NETWORK_STATUS_TEMPLATE = "%s|%s|%s|%s|%s"; - /** * Checks whether the network is available and return a string which can then be send as a * result data for the ordered broadcast. diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java index ece09c84f5..38802d7549 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java @@ -111,7 +111,7 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC "testBackgroundNetworkAccess_disabled"); } - public void testBatterySaverModeNonMeteredt_whitelisted() throws Exception { + public void testBatterySaverModeNonMetered_whitelisted() throws Exception { runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeNonMeteredTest", "testBackgroundNetworkAccess_whitelisted"); } From ed64e61b5fce76e6eabcf45641021f1fd169e213 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Fri, 6 May 2016 14:38:06 -0700 Subject: [PATCH 0249/1109] Covers more corner cases on restricted network modes: - Tests what happens on foreground applications when a restriction (like Data Saver or Battery Saver modes) is turned on (prior tests would turn the restriction on *before* switching the app to foreground). - Tests multiple restrictions simultaneously enabled. Also improved existing code: - Fixed background state check. - Reused some common checks in helper methods. - Retries checks for process state. BUG: 28473659 Change-Id: Ifcf9cc6d895ccde0ab5177f9f5d8c347ce53b811 --- ...ractRestrictBackgroundNetworkTestCase.java | 98 ++++++++-- .../BatterySaverModeNonMeteredTest.java | 41 ++-- .../net/hostside/BatterySaverModeTest.java | 42 ++-- .../cts/net/hostside/DataSaverModeTest.java | 67 ++++--- .../cts/net/hostside/MixedModesTest.java | 179 ++++++++++++++++++ .../android/cts/net/hostside/app2/Common.java | 3 +- .../cts/net/hostside/app2/MyActivity.java | 19 ++ .../hostside/app2/MyBroadcastReceiver.java | 2 +- .../hostside/app2/MyForegroundService.java | 2 +- ...ostsideRestrictBackgroundNetworkTests.java | 10 + 10 files changed, 383 insertions(+), 80 deletions(-) create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 3ee2f6868e..f2a69f2f14 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -176,34 +176,90 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation assertNetworkAccess(true); } + protected void assertForegroundServiceNetworkAccess() throws Exception { + assertForegroundServiceState(); // Sanity check. + assertNetworkAccess(true); + } + + /** + * Asserts that an app always have access while on foreground or running a foreground service. + * + *

This method will launch an activity and a foreground service to make the assertion, but + * will finish the activity / stop the service afterwards. + */ + protected void assertsForegroundAlwaysHasNetworkAccess() throws Exception{ + // Checks foreground first. + launchActivity(); + assertForegroundNetworkAccess(); + finishActivity(); + + // Then foreground service + startForegroundService(); + assertForegroundServiceNetworkAccess(); + stopForegroundService(); + } + protected final void assertBackgroundState() throws Exception { - final ProcessState state = getProcessStateByUid(mUid); - Log.v(TAG, "assertBackgroundState(): status for app2 (" + mUid + "): " + state); - final boolean isBackground = isBackground(state.state); - assertTrue("App2 is not on background state: " + state, isBackground); + final int maxTries = 30; + ProcessState state = null; + for (int i = 1; i <= maxTries; i++) { + state = getProcessStateByUid(mUid); + Log.v(TAG, "assertBackgroundState(): status for app2 (" + mUid + ") on attempt #" + i + + ": " + state); + if (isBackground(state.state)) { + return; + } + Log.d(TAG, "App not on background state on attempt #" + i + + "; sleeping 1s before trying again"); + Thread.sleep(SECOND_IN_MS); + } + fail("App2 is not on background state after " + maxTries + " attempts: " + state ); } protected final void assertForegroundState() throws Exception { - final ProcessState state = getProcessStateByUid(mUid); - Log.v(TAG, "assertForegroundState(): status for app2 (" + mUid + "): " + state); - final boolean isForeground = !isBackground(state.state); - assertTrue("App2 is not on foreground state: " + state, isForeground); + final int maxTries = 30; + ProcessState state = null; + for (int i = 1; i <= maxTries; i++) { + state = getProcessStateByUid(mUid); + Log.v(TAG, "assertForegroundState(): status for app2 (" + mUid + ") on attempt #" + i + + ": " + state); + if (!isBackground(state.state)) { + return; + } + Log.d(TAG, "App not on foreground state on attempt #" + i + + "; sleeping 1s before trying again"); + Thread.sleep(SECOND_IN_MS); + } + fail("App2 is not on foreground state after " + maxTries + " attempts: " + state ); } protected final void assertForegroundServiceState() throws Exception { - final ProcessState state = getProcessStateByUid(mUid); - Log.v(TAG, "assertForegroundServiceState(): status for app2 (" + mUid + "): " + state); - assertEquals("App2 is not on foreground service state: " + state, - PROCESS_STATE_FOREGROUND_SERVICE, state.state); + final int maxTries = 30; + ProcessState state = null; + for (int i = 1; i <= maxTries; i++) { + state = getProcessStateByUid(mUid); + Log.v(TAG, "assertForegroundServiceState(): status for app2 (" + mUid + ") on attempt #" + + i + ": " + state); + if (state.state == PROCESS_STATE_FOREGROUND_SERVICE) { + return; + } + Log.d(TAG, "App not on foreground service state on attempt #" + i + + "; sleeping 1s before trying again"); + Thread.sleep(SECOND_IN_MS); + } + fail("App2 is not on foreground service state after " + maxTries + " attempts: " + state ); } /** * Returns whether an app state should be considered "background" for restriction purposes. */ protected boolean isBackground(int state) { - return state >= PROCESS_STATE_FOREGROUND_SERVICE; + return state > PROCESS_STATE_FOREGROUND_SERVICE; } + /** + * Asserts whether the active network is available or not. + */ private void assertNetworkAccess(boolean expectAvailable) throws Exception { final Intent intent = new Intent(ACTION_CHECK_NETWORK); @@ -495,13 +551,27 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation "am startservice com.android.cts.net.hostside.app2/.MyForegroundService"); } + protected void stopForegroundService() throws Exception { + executeShellCommand( + "am stopservice com.android.cts.net.hostside.app2/.MyForegroundService"); + } + /** * Launches an activity on app2 so its process is elevated to foreground status. */ - protected void launchApp2Activity() throws Exception { + protected void launchActivity() throws Exception { executeShellCommand("am start com.android.cts.net.hostside.app2/.MyActivity"); } + /** + * Finishes an activity on app2 so its process is demoted fromforeground status. + */ + protected void finishActivity() throws Exception { + executeShellCommand("am broadcast -a " + + " com.android.cts.net.hostside.app2.action.FINISH_ACTIVITY " + + "--receiver-foreground --receiver-registered-only"); + } + private String toString(int status) { switch (status) { case RESTRICT_BACKGROUND_STATUS_DISABLED: diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java index 5f5f80bf2c..d1db01c3b2 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java @@ -23,8 +23,10 @@ public class BatterySaverModeNonMeteredTest extends AbstractRestrictBackgroundNe public void setUp() throws Exception { super.setUp(); + // Set initial state. + removePowerSaveModeWhitelist(TEST_APP2_PKG); setPowerSaveMode(false); - assertPowerSaveModeWhitelist(TEST_APP2_PKG, false); // Sanity check + registerBroadcastReceiver(); } @@ -39,35 +41,46 @@ public class BatterySaverModeNonMeteredTest extends AbstractRestrictBackgroundNe setPowerSaveMode(true); assertBackgroundNetworkAccess(false); - // Make sure app is allowed if running a foreground service. - startForegroundService(); - assertForegroundServiceState(); - assertBackgroundNetworkAccess(true); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); - // Should always have access when running on foreground - launchApp2Activity(); + // Make sure foreground app doesn't lose access upon enabling it. + setPowerSaveMode(false); + launchActivity(); assertForegroundNetworkAccess(); + setPowerSaveMode(true); + assertForegroundNetworkAccess(); + finishActivity(); + assertBackgroundNetworkAccess(false); + + // Same for foreground service. + setPowerSaveMode(false); + startForegroundService(); + assertForegroundNetworkAccess(); + setPowerSaveMode(true); + assertForegroundNetworkAccess(); + stopForegroundService(); + assertBackgroundNetworkAccess(false); } public void testBackgroundNetworkAccess_whitelisted() throws Exception { setPowerSaveMode(true); assertBackgroundNetworkAccess(false); + addPowerSaveModeWhitelist(TEST_APP2_PKG); assertBackgroundNetworkAccess(true); + removePowerSaveModeWhitelist(TEST_APP2_PKG); assertBackgroundNetworkAccess(false); - // Should always have access when running on foreground - launchApp2Activity(); - assertForegroundNetworkAccess(); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); } public void testBackgroundNetworkAccess_disabled() throws Exception { - setPowerSaveMode(false); assertBackgroundNetworkAccess(true); - // Should always have access when running on foreground - launchApp2Activity(); - assertForegroundNetworkAccess(); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(true); } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java index 539c598c08..22b876ac3f 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java @@ -23,9 +23,11 @@ public class BatterySaverModeTest extends AbstractRestrictBackgroundNetworkTestC public void setUp() throws Exception { super.setUp(); + // Set initial state. setMeteredNetwork(); + removePowerSaveModeWhitelist(TEST_APP2_PKG); setPowerSaveMode(false); - assertPowerSaveModeWhitelist(TEST_APP2_PKG, false); // Sanity check + registerBroadcastReceiver(); } @@ -42,38 +44,48 @@ public class BatterySaverModeTest extends AbstractRestrictBackgroundNetworkTestC public void testBackgroundNetworkAccess_enabled() throws Exception { setPowerSaveMode(true); - assertBackgroundNetworkAccess(false); - // Make sure app is allowed if running a foreground service. - startForegroundService(); - assertForegroundServiceState(); - assertBackgroundNetworkAccess(true); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); - // Should always have access when running on foreground - launchApp2Activity(); + // Make sure foreground app doesn't lose access upon enabling it. + setPowerSaveMode(false); + launchActivity(); assertForegroundNetworkAccess(); + setPowerSaveMode(true); + assertForegroundNetworkAccess(); + finishActivity(); + assertBackgroundNetworkAccess(false); + + // Same for foreground service. + setPowerSaveMode(false); + startForegroundService(); + assertForegroundNetworkAccess(); + setPowerSaveMode(true); + assertForegroundNetworkAccess(); + stopForegroundService(); + assertBackgroundNetworkAccess(false); } public void testBackgroundNetworkAccess_whitelisted() throws Exception { setPowerSaveMode(true); assertBackgroundNetworkAccess(false); + addPowerSaveModeWhitelist(TEST_APP2_PKG); assertBackgroundNetworkAccess(true); + removePowerSaveModeWhitelist(TEST_APP2_PKG); assertBackgroundNetworkAccess(false); - // Should always have access when running on foreground - launchApp2Activity(); - assertForegroundNetworkAccess(); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); } public void testBackgroundNetworkAccess_disabled() throws Exception { - setPowerSaveMode(false); assertBackgroundNetworkAccess(true); - // Should always have access when running on foreground - launchApp2Activity(); - assertForegroundNetworkAccess(); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(true); } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index 09717701d8..189515683c 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -20,15 +20,6 @@ import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLE import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; -/* - * TODO: need to add more scenarios: - * - test access on foreground app - * - test access on foreground service app - * - make sure it works when app is on foreground and state is transitioned: - * - data saver is enabled - * - app is added/removed to blacklist - * - */ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase { private static final String[] REQUIRED_WHITELISTED_PACKAGES = { @@ -39,9 +30,14 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase public void setUp() throws Exception { super.setUp(); + // Set initial state. setMeteredNetwork(); setRestrictBackground(false); + removeRestrictBackgroundWhitelist(mUid); + removeRestrictBackgroundBlacklist(mUid); + registerBroadcastReceiver(); + assertRestrictBackgroundChangedReceived(0); } @Override @@ -56,8 +52,6 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase } public void testGetRestrictBackgroundStatus_disabled() throws Exception { - removeRestrictBackgroundWhitelist(mUid); - assertRestrictBackgroundChangedReceived(0); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED); // Sanity check: make sure status is always disabled, never whitelisted @@ -65,14 +59,14 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertRestrictBackgroundChangedReceived(0); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED); - // Should always have access when running on foreground - launchApp2Activity(); - assertForegroundNetworkAccess(); + assertsForegroundAlwaysHasNetworkAccess(); + assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED); } public void testGetRestrictBackgroundStatus_whitelisted() throws Exception { setRestrictBackground(true); assertRestrictBackgroundChangedReceived(1); + assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); addRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundChangedReceived(2); @@ -80,11 +74,10 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase removeRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundChangedReceived(3); - assertRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_ENABLED); + assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); - // Should always have access when running on foreground - launchApp2Activity(); - assertForegroundNetworkAccess(); + assertsForegroundAlwaysHasNetworkAccess(); + assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); } public void testGetRestrictBackgroundStatus_enabled() throws Exception { @@ -92,19 +85,26 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertRestrictBackgroundChangedReceived(1); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); - removeRestrictBackgroundWhitelist(mUid); - assertRestrictBackgroundChangedReceived(1); + assertsForegroundAlwaysHasNetworkAccess(); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); - // Make sure app is allowed if running a foreground service. - assertBackgroundNetworkAccess(false); - startForegroundService(); - assertForegroundServiceState(); - assertBackgroundNetworkAccess(true); - - // Should always have access when running on foreground - launchApp2Activity(); + // Make sure foreground app doesn't lose access upon enabling it. + setRestrictBackground(false); + launchActivity(); assertForegroundNetworkAccess(); + setRestrictBackground(true); + assertForegroundNetworkAccess(); + finishActivity(); + assertBackgroundNetworkAccess(false); + + // Same for foreground service. + setRestrictBackground(false); + startForegroundService(); + assertForegroundNetworkAccess(); + setRestrictBackground(true); + assertForegroundNetworkAccess(); + stopForegroundService(); + assertBackgroundNetworkAccess(false); } public void testGetRestrictBackgroundStatus_blacklisted() throws Exception { @@ -112,6 +112,9 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertRestrictBackgroundChangedReceived(1); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); + assertsForegroundAlwaysHasNetworkAccess(); + assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); + // Make sure blacklist prevails over whitelist. setRestrictBackground(true); assertRestrictBackgroundChangedReceived(2); @@ -128,12 +131,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertRestrictBackgroundChangedReceived(5); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED); - // Should always have access when running on foreground - addRestrictBackgroundBlacklist(mUid); - assertRestrictBackgroundChangedReceived(6); - assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); - launchApp2Activity(); - assertForegroundNetworkAccess(); + assertsForegroundAlwaysHasNetworkAccess(); + assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED); } public void testGetRestrictBackgroundStatus_requiredWhitelistedPackages() throws Exception { diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java new file mode 100644 index 0000000000..140d1354bf --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2016 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.cts.net.hostside; + +import android.util.Log; + +/** + * Test cases for the more complex scenarios where multiple restrictions (like Battery Saver Mode + * and Data Saver Mode) are applied simultaneously. + *

+ * NOTE: it might sound like the test methods on this class are testing too much, + * which would make it harder to diagnose individual failures, but the assumption is that such + * failure most likely will happen when the restriction is tested individually as well. + */ +public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { + private static final String TAG = "MixedModesTest"; + + @Override + public void setUp() throws Exception { + super.setUp(); + + // Set initial state. + removeRestrictBackgroundWhitelist(mUid); + removeRestrictBackgroundBlacklist(mUid); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + + registerBroadcastReceiver(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + + try { + setRestrictBackground(false); + } finally { + setPowerSaveMode(false); + } + } + + /** + * Tests all DS ON and BS ON scenarios from network-policy-restrictions.md on metered networks. + */ + public void testDataAndBatterySaverModes_meteredNetwork() throws Exception { + Log.i(TAG, "testDataAndBatterySaverModes_meteredNetwork() tests"); + setMeteredNetwork(); + + try { + setRestrictBackground(true); + setPowerSaveMode(true); + + Log.v(TAG, "Not whitelisted for any."); + assertBackgroundNetworkAccess(false); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + + Log.v(TAG, "Whitelisted for Data Saver but not for Battery Saver."); + addRestrictBackgroundWhitelist(mUid); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + removeRestrictBackgroundWhitelist(mUid); + + Log.v(TAG, "Whitelisted for Battery Saver but not for Data Saver."); + addPowerSaveModeWhitelist(TEST_APP2_PKG); + removeRestrictBackgroundWhitelist(mUid); + assertBackgroundNetworkAccess(false); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + + Log.v(TAG, "Whitelisted for both."); + addRestrictBackgroundWhitelist(mUid); + addPowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(true); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(true); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + removeRestrictBackgroundWhitelist(mUid); + + Log.v(TAG, "Blacklisted for Data Saver, not whitelisted for Battery Saver."); + addRestrictBackgroundBlacklist(mUid); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + removeRestrictBackgroundBlacklist(mUid); + + Log.v(TAG, "Blacklisted for Data Saver, whitelisted for Battery Saver."); + addRestrictBackgroundBlacklist(mUid); + addPowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + removeRestrictBackgroundBlacklist(mUid); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + } finally { + resetMeteredNetwork(); + } + } + + /** + * Tests all DS ON and BS ON scenarios from network-policy-restrictions.md on non-metered + * networks. + */ + public void testDataAndBatterySaverModes_nonMeteredNetwork() throws Exception { + if (mCm.isActiveNetworkMetered()) { + Log.w(TAG, "testDataAndBatterySaverModes_nonMeteredNetwork() skipped because network" + + " is metered"); + return; + } + Log.i(TAG, "testDataAndBatterySaverModes_nonMeteredNetwork() tests"); + setRestrictBackground(true); + setPowerSaveMode(true); + + Log.v(TAG, "Not whitelisted for any."); + assertBackgroundNetworkAccess(false); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + + Log.v(TAG, "Whitelisted for Data Saver but not for Battery Saver."); + addRestrictBackgroundWhitelist(mUid); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + removeRestrictBackgroundWhitelist(mUid); + + Log.v(TAG, "Whitelisted for Battery Saver but not for Data Saver."); + addPowerSaveModeWhitelist(TEST_APP2_PKG); + removeRestrictBackgroundWhitelist(mUid); + assertBackgroundNetworkAccess(true); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(true); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + + Log.v(TAG, "Whitelisted for both."); + addRestrictBackgroundWhitelist(mUid); + addPowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(true); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(true); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + removeRestrictBackgroundWhitelist(mUid); + + Log.v(TAG, "Blacklisted for Data Saver, not whitelisted for Battery Saver."); + addRestrictBackgroundBlacklist(mUid); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + removeRestrictBackgroundBlacklist(mUid); + + Log.v(TAG, "Blacklisted for Data Saver, whitelisted for Battery Saver."); + addRestrictBackgroundBlacklist(mUid); + addPowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(true); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(true); + removeRestrictBackgroundBlacklist(mUid); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + } +} diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java index ed58184576..d827921654 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java @@ -34,10 +34,11 @@ public final class Common { "com.android.cts.net.hostside.app2.action.CHECK_NETWORK"; static final String ACTION_RECEIVER_READY = "com.android.cts.net.hostside.app2.action.RECEIVER_READY"; + static final String ACTION_FINISH_ACTIVITY = + "com.android.cts.net.hostside.app2.action.FINISH_ACTIVITY"; static final String EXTRA_ACTION = "com.android.cts.net.hostside.app2.extra.ACTION"; static final String EXTRA_RECEIVER_NAME = "com.android.cts.net.hostside.app2.extra.RECEIVER_NAME"; - static final char RESULT_SEPARATOR = ';'; static int getUid(Context context) { final String packageName = context.getPackageName(); diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java index 7c6b50494d..444b696962 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java @@ -15,8 +15,15 @@ */ package com.android.cts.net.hostside.app2; +import static com.android.cts.net.hostside.app2.Common.ACTION_FINISH_ACTIVITY; import static com.android.cts.net.hostside.app2.Common.TAG; + import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Bundle; import android.util.Log; /** @@ -24,6 +31,18 @@ import android.util.Log; */ public class MyActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + registerReceiver(new BroadcastReceiver() { + + @Override + public void onReceive(Context context, Intent intent) { + Log.d(TAG, "Finishing MyActivity"); + MyActivity.this.finish(); + }}, new IntentFilter(ACTION_FINISH_ACTIVITY)); + } + @Override protected void onStart() { super.onStart(); diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java index b876276899..114d5c11d9 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java @@ -17,6 +17,7 @@ package com.android.cts.net.hostside.app2; import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; + import static com.android.cts.net.hostside.app2.Common.ACTION_CHECK_NETWORK; import static com.android.cts.net.hostside.app2.Common.ACTION_GET_COUNTERS; import static com.android.cts.net.hostside.app2.Common.ACTION_GET_RESTRICT_BACKGROUND_STATUS; @@ -24,7 +25,6 @@ import static com.android.cts.net.hostside.app2.Common.ACTION_RECEIVER_READY; import static com.android.cts.net.hostside.app2.Common.EXTRA_ACTION; import static com.android.cts.net.hostside.app2.Common.EXTRA_RECEIVER_NAME; import static com.android.cts.net.hostside.app2.Common.MANIFEST_RECEIVER; -import static com.android.cts.net.hostside.app2.Common.RESULT_SEPARATOR; import static com.android.cts.net.hostside.app2.Common.TAG; import static com.android.cts.net.hostside.app2.Common.getUid; diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java index bbafd4c274..1afc3d6c41 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java @@ -35,7 +35,7 @@ public class MyForegroundService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { - Log.d(TAG, "MyForegroundService.onStartCommand: " + intent); + Log.d(TAG, "MyForegroundService.onStartCommand(): " + intent); startForeground(42, new Notification.Builder(this) .setSmallIcon(R.drawable.ic_dialog_alert) // any icon is fine .build()); diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java index 38802d7549..ec375d6a47 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java @@ -121,6 +121,16 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC "testBackgroundNetworkAccess_enabled"); } + public void testDataAndBatterySaverModes_meteredNetwork() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".MixedModesTest", + "testDataAndBatterySaverModes_meteredNetwork"); + } + + public void testDataAndBatterySaverModes_nonMeteredNetwork() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".MixedModesTest", + "testDataAndBatterySaverModes_nonMeteredNetwork"); + } + private void assertRestrictBackgroundWhitelist(int uid, boolean expected) throws Exception { final int max_tries = 5; boolean actual = false; From 3361c861477020ec85d230fe8d342627e4352f4b Mon Sep 17 00:00:00 2001 From: Aaron Holden Date: Tue, 10 May 2016 15:58:46 -0700 Subject: [PATCH 0250/1109] Remove module-level WifiCheck preparers As WifiCheck is now declared in the CTS config, remove declarations in the module configs. Also downgrade TargetSetupErrors on failure to logged errors bug:28234985 Change-Id: I2e1a369bc26aeca922686c4c3d8c033bb7f9fbc7 --- tests/cts/net/AndroidTest.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/cts/net/AndroidTest.xml b/tests/cts/net/AndroidTest.xml index dc803397d9..5194da37d2 100644 --- a/tests/cts/net/AndroidTest.xml +++ b/tests/cts/net/AndroidTest.xml @@ -13,7 +13,6 @@ limitations under the License. --> -

By default is empty - it's up to subclasses to override. + */ + protected void setUpMeteredNetwork() throws Exception { + } + + /** + * Resets the (non) metered network state. + * + *

By default is empty - it's up to subclasses to override. + */ + protected void tearDownMeteredNetwork() throws Exception { + } + + public void testBackgroundNetworkAccess_enabled() throws Exception { + setAppIdle(true); + assertBackgroundNetworkAccess(false); + + assertsForegroundAlwaysHasNetworkAccess(); + setAppIdle(true); + assertBackgroundNetworkAccess(false); + + // Make sure foreground app doesn't lose access upon enabling it. + setAppIdle(true); + launchActivity(); + assertAppIdle(false); // Sanity check - not idle anymore, since activity was launched... + assertForegroundNetworkAccess(); + finishActivity(); + assertAppIdle(false); // Sanity check - not idle anymore, since activity was launched... + assertBackgroundNetworkAccess(true); + setAppIdle(true); + assertBackgroundNetworkAccess(false); + + // Same for foreground service. + setAppIdle(true); + startForegroundService(); + assertAppIdle(true); // Sanity check - still idle + assertForegroundServiceNetworkAccess(); + stopForegroundService(); + assertAppIdle(true); + assertBackgroundNetworkAccess(false); + } + + public void testBackgroundNetworkAccess_whitelisted() throws Exception { + setAppIdle(true); + assertBackgroundNetworkAccess(false); + + addPowerSaveModeWhitelist(TEST_APP2_PKG); + assertAppIdle(false); // Sanity check - not idle anymore, since whitelisted + assertBackgroundNetworkAccess(true); + + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertAppIdle(true); // Sanity check - idle again, once whitelisted was removed + assertBackgroundNetworkAccess(false); + + assertsForegroundAlwaysHasNetworkAccess(); + + // Sanity check - no whitelist, no access! + setAppIdle(true); + assertBackgroundNetworkAccess(false); + } + + public void testBackgroundNetworkAccess_disabled() throws Exception { + assertBackgroundNetworkAccess(true); + + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(true); + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java similarity index 68% rename from tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java rename to tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java index 22b876ac3f..2acc670800 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java @@ -16,60 +16,78 @@ package com.android.cts.net.hostside; -//TODO: move this and BatterySaverModeNonMeteredTest's logic into a common superclass -public class BatterySaverModeTest extends AbstractRestrictBackgroundNetworkTestCase { +/** + * Base class for metered and non-metered Battery Saver Mode tests. + */ +abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgroundNetworkTestCase { @Override - public void setUp() throws Exception { + protected final void setUp() throws Exception { super.setUp(); // Set initial state. - setMeteredNetwork(); + setUpMeteredNetwork(); removePowerSaveModeWhitelist(TEST_APP2_PKG); - setPowerSaveMode(false); + setBatterySaverMode(false); registerBroadcastReceiver(); } @Override - protected void tearDown() throws Exception { + protected final void tearDown() throws Exception { super.tearDown(); try { - resetMeteredNetwork(); + tearDownMeteredNetwork(); } finally { - setPowerSaveMode(false); + setBatterySaverMode(false); } } + /** + * Sets the initial (non) metered network state. + * + *

By default is empty - it's up to subclasses to override. + */ + protected void setUpMeteredNetwork() throws Exception { + } + + /** + * Resets the (non) metered network state. + * + *

By default is empty - it's up to subclasses to override. + */ + protected void tearDownMeteredNetwork() throws Exception { + } + public void testBackgroundNetworkAccess_enabled() throws Exception { - setPowerSaveMode(true); + setBatterySaverMode(true); assertBackgroundNetworkAccess(false); assertsForegroundAlwaysHasNetworkAccess(); assertBackgroundNetworkAccess(false); // Make sure foreground app doesn't lose access upon enabling it. - setPowerSaveMode(false); + setBatterySaverMode(false); launchActivity(); assertForegroundNetworkAccess(); - setPowerSaveMode(true); + setBatterySaverMode(true); assertForegroundNetworkAccess(); finishActivity(); assertBackgroundNetworkAccess(false); // Same for foreground service. - setPowerSaveMode(false); + setBatterySaverMode(false); startForegroundService(); assertForegroundNetworkAccess(); - setPowerSaveMode(true); + setBatterySaverMode(true); assertForegroundNetworkAccess(); stopForegroundService(); assertBackgroundNetworkAccess(false); } public void testBackgroundNetworkAccess_whitelisted() throws Exception { - setPowerSaveMode(true); + setBatterySaverMode(true); assertBackgroundNetworkAccess(false); addPowerSaveModeWhitelist(TEST_APP2_PKG); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java new file mode 100644 index 0000000000..f3c49353f6 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2016 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.cts.net.hostside; + +/** + * Base class for metered and non-metered Doze Mode tests. + */ +abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetworkTestCase { + + @Override + protected final void setUp() throws Exception { + super.setUp(); + + // Set initial state. + setUpMeteredNetwork(); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + setDozeMode(false); + + registerBroadcastReceiver(); + } + + @Override + protected final void tearDown() throws Exception { + super.tearDown(); + + try { + tearDownMeteredNetwork(); + } finally { + setDozeMode(false); + } + } + + /** + * Sets the initial (non) metered network state. + * + *

By default is empty - it's up to subclasses to override. + */ + protected void setUpMeteredNetwork() throws Exception { + } + + /** + * Resets the (non) metered network state. + * + *

By default is empty - it's up to subclasses to override. + */ + protected void tearDownMeteredNetwork() throws Exception { + } + + public void testBackgroundNetworkAccess_enabled() throws Exception { + setDozeMode(true); + assertBackgroundNetworkAccess(false); + + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + + // Make sure foreground service doesn't lose network access upon enabling doze. + setDozeMode(false); + startForegroundService(); + assertForegroundNetworkAccess(); + setDozeMode(true); + assertForegroundNetworkAccess(); + stopForegroundService(); + assertBackgroundState(); + assertBackgroundNetworkAccess(false); + } + + public void testBackgroundNetworkAccess_whitelisted() throws Exception { + setDozeMode(true); + assertBackgroundNetworkAccess(false); + + addPowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(true); + + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + } + + public void testBackgroundNetworkAccess_disabled() throws Exception { + assertBackgroundNetworkAccess(true); + + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(true); + } + + // Must override so it only tests foreground service - once an app goes to foreground, device + // leaves Doze Mode. + @Override + protected void assertsForegroundAlwaysHasNetworkAccess() throws Exception { + startForegroundService(); + assertForegroundServiceNetworkAccess(); + stopForegroundService(); + assertBackgroundState(); + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index f2a69f2f14..17480e2efe 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -80,7 +80,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation private String mMeteredWifi; @Override - public void setUp() throws Exception { + protected void setUp() throws Exception { super.setUp(); mInstrumentation = getInstrumentation(); @@ -329,7 +329,12 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation */ protected void assertDelayedShellCommand(String command, final String expectedResult) throws Exception { - assertDelayedShellCommand(command, new ExpectResultChecker() { + assertDelayedShellCommand(command, 5, 1, expectedResult); + } + + protected void assertDelayedShellCommand(String command, int maxTries, int napTimeSeconds, + final String expectedResult) throws Exception { + assertDelayedShellCommand(command, maxTries, napTimeSeconds, new ExpectResultChecker() { @Override public boolean isExpected(String result) { @@ -345,21 +350,28 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected void assertDelayedShellCommand(String command, ExpectResultChecker checker) throws Exception { - final int maxTries = 5; + assertDelayedShellCommand(command, 5, 1, checker); + } + protected void assertDelayedShellCommand(String command, int maxTries, int napTimeSeconds, + ExpectResultChecker checker) throws Exception { String result = ""; for (int i = 1; i <= maxTries; i++) { result = executeShellCommand(command).trim(); if (checker.isExpected(result)) return; Log.v(TAG, "Command '" + command + "' returned '" + result + " instead of '" + checker.getExpected() + "' on attempt #" + i - + "; sleeping 1s before trying again"); - Thread.sleep(SECOND_IN_MS); + + "; sleeping " + napTimeSeconds + "s before trying again"); + Thread.sleep(napTimeSeconds * SECOND_IN_MS); } fail("Command '" + command + "' did not return '" + checker.getExpected() + "' after " + maxTries + " attempts. Last result: '" + result + "'"); } + /** + * Puts the device in a state where the active network is metered, or fail if it can't achieve + * that state. + */ protected void setMeteredNetwork() throws Exception { final NetworkInfo info = mCm.getActiveNetworkInfo(); final boolean metered = mCm.isActiveNetworkMetered(); @@ -375,17 +387,37 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation mMeteredWifi = netId; // Sanity check. assertWifiMeteredStatus(netId, true); - assertTrue("Could not set wifi '" + netId + "' as metered (" - + mCm.getActiveNetworkInfo() +")", mCm.isActiveNetworkMetered()); + assertActiveNetworkMetered(true); } + /** + * Puts the device in a state where the active network is not metered, or fail if it can't + * achieve that state. + *

It assumes the device has a valid WI-FI connection. + */ protected void resetMeteredNetwork() throws Exception { - if (mMeteredWifi == null) { - Log.d(TAG, "resetMeteredNetwork(): wifi not set as metered"); - return; + if (mMeteredWifi != null) { + Log.i(TAG, "resetMeteredNetwork(): SID '" + mMeteredWifi + + "' was set as metered by test case; resetting it"); + setWifiMeteredStatus(mMeteredWifi, false); + } else { + final NetworkInfo info = mCm.getActiveNetworkInfo(); + assertNotNull("Could not get active network", info); + if (!info.isMetered()) { + Log.d(TAG, "Active network is not metered: " + info); + } else if (info.getType() == ConnectivityManager.TYPE_WIFI) { + Log.i(TAG, "Setting active WI-FI network as metered: " + info ); + setWifiMeteredStatus(false); + } else { + fail("Active network is not WI-FI hence cannot be set as non-metered: " + info); + } } - Log.i(TAG, "resetMeteredNetwork(): resetting " + mMeteredWifi); - setWifiMeteredStatus(mMeteredWifi, false); + assertActiveNetworkMetered(false); // Sanity check. + } + + private void assertActiveNetworkMetered(boolean expected) { + final NetworkInfo info = mCm.getActiveNetworkInfo(); + assertEquals("Wrong metered status for active network " + info, expected, info.isMetered()); } private String setWifiMeteredStatus(boolean metered) throws Exception { @@ -512,16 +544,63 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation assertPowerSaveModeWhitelist(packageName, false); // Sanity check } - protected void setPowerSaveMode(boolean enabled) throws Exception { - Log.i(TAG, "Setting power mode to " + enabled); + protected void turnBatteryOff() throws Exception { + executeSilentShellCommand("cmd battery unplug"); + } + + protected void turnBatteryOn() throws Exception { + executeSilentShellCommand("cmd battery reset"); + } + + protected void turnScreenOff() throws Exception { + executeSilentShellCommand("input keyevent KEYCODE_SLEEP"); + } + + protected void turnScreenOn() throws Exception { + executeSilentShellCommand("input keyevent KEYCODE_WAKEUP"); + executeSilentShellCommand("wm dismiss-keyguard"); + } + + protected void setBatterySaverMode(boolean enabled) throws Exception { + Log.i(TAG, "Setting Battery Saver Mode to " + enabled); if (enabled) { + turnBatteryOff(); executeSilentShellCommand("cmd battery unplug"); executeSilentShellCommand("settings put global low_power 1"); } else { - executeSilentShellCommand("cmd battery reset"); + turnBatteryOn(); } } + protected void setDozeMode(boolean enabled) throws Exception { + Log.i(TAG, "Setting Doze Mode to " + enabled); + if (enabled) { + turnBatteryOff(); + turnScreenOff(); + executeShellCommand("dumpsys deviceidle force-idle deep"); + } else { + turnScreenOn(); + turnBatteryOn(); + executeShellCommand("dumpsys deviceidle unforce"); + } + // Sanity check. + assertDozeMode(enabled); + } + + protected void assertDozeMode(boolean enabled) throws Exception { + assertDelayedShellCommand("dumpsys deviceidle get deep", enabled ? "IDLE" : "ACTIVE"); + } + + protected void setAppIdle(boolean enabled) throws Exception { + Log.i(TAG, "Setting app idle to " + enabled); + executeSilentShellCommand("am set-inactive " + TEST_APP2_PKG + " " + enabled ); + assertAppIdle(enabled); // Sanity check + } + + protected void assertAppIdle(boolean enabled) throws Exception { + assertDelayedShellCommand("am get-inactive " + TEST_APP2_PKG, 10, 2, "Idle=" + enabled); + } + /** * Starts a service that will register a broadcast receiver to receive * {@code RESTRICT_BACKGROUND_CHANGE} intents. @@ -548,19 +627,23 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected void startForegroundService() throws Exception { executeShellCommand( - "am startservice com.android.cts.net.hostside.app2/.MyForegroundService"); + "am startservice -f 1 com.android.cts.net.hostside.app2/.MyForegroundService"); + assertForegroundServiceState(); } protected void stopForegroundService() throws Exception { executeShellCommand( - "am stopservice com.android.cts.net.hostside.app2/.MyForegroundService"); + "am startservice -f 2 com.android.cts.net.hostside.app2/.MyForegroundService"); + // NOTE: cannot assert state because it depends on whether activity was on top before. } /** * Launches an activity on app2 so its process is elevated to foreground status. */ protected void launchActivity() throws Exception { + turnScreenOn(); executeShellCommand("am start com.android.cts.net.hostside.app2/.MyActivity"); + assertForegroundState(); } /** @@ -608,8 +691,17 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation } } + /** + * Helper class used to assert the result of a Shell command. + */ protected static interface ExpectResultChecker { + /** + * Checkes whether the result of the command matched the expectation. + */ boolean isExpected(String result); + /** + * Gets the expected result so it's displayed on log and failure messages. + */ String getExpected(); } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java new file mode 100644 index 0000000000..e008c695bb --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2016 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.cts.net.hostside; + +public class AppIdleMeteredTest extends AbstractAppIdleTestCase { + + @Override + protected void setUpMeteredNetwork() throws Exception { + setMeteredNetwork(); + } + + @Override + protected void tearDownMeteredNetwork() throws Exception { + resetMeteredNetwork(); + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java new file mode 100644 index 0000000000..633dc81c95 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2016 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.cts.net.hostside; + +public class AppIdleNonMeteredTest extends AbstractAppIdleTestCase { + + @Override + protected void setUpMeteredNetwork() throws Exception { + resetMeteredNetwork(); + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java new file mode 100644 index 0000000000..3a88bbd1ad --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2016 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.cts.net.hostside; + +public class BatterySaverModeMeteredTest extends AbstractBatterySaverModeTestCase { + + @Override + protected void setUpMeteredNetwork() throws Exception { + setMeteredNetwork(); + } + + @Override + protected void tearDownMeteredNetwork() throws Exception { + resetMeteredNetwork(); + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java index d1db01c3b2..646c4b993a 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java @@ -16,71 +16,10 @@ package com.android.cts.net.hostside; -//TODO: move this and BatterySaverModeTest's logic into a common superclass -public class BatterySaverModeNonMeteredTest extends AbstractRestrictBackgroundNetworkTestCase { +public class BatterySaverModeNonMeteredTest extends AbstractBatterySaverModeTestCase { @Override - public void setUp() throws Exception { - super.setUp(); - - // Set initial state. - removePowerSaveModeWhitelist(TEST_APP2_PKG); - setPowerSaveMode(false); - - registerBroadcastReceiver(); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - - setPowerSaveMode(false); - } - - public void testBackgroundNetworkAccess_enabled() throws Exception { - setPowerSaveMode(true); - assertBackgroundNetworkAccess(false); - - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(false); - - // Make sure foreground app doesn't lose access upon enabling it. - setPowerSaveMode(false); - launchActivity(); - assertForegroundNetworkAccess(); - setPowerSaveMode(true); - assertForegroundNetworkAccess(); - finishActivity(); - assertBackgroundNetworkAccess(false); - - // Same for foreground service. - setPowerSaveMode(false); - startForegroundService(); - assertForegroundNetworkAccess(); - setPowerSaveMode(true); - assertForegroundNetworkAccess(); - stopForegroundService(); - assertBackgroundNetworkAccess(false); - } - - public void testBackgroundNetworkAccess_whitelisted() throws Exception { - setPowerSaveMode(true); - assertBackgroundNetworkAccess(false); - - addPowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(true); - - removePowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(false); - - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(false); - } - - public void testBackgroundNetworkAccess_disabled() throws Exception { - assertBackgroundNetworkAccess(true); - - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(true); + protected void setUpMeteredNetwork() throws Exception { + resetMeteredNetwork(); } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java new file mode 100644 index 0000000000..656d274c52 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2016 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.cts.net.hostside; + +public class DozeModeMeteredTest extends AbstractDozeModeTestCase { + + @Override + protected void setUpMeteredNetwork() throws Exception { + setMeteredNetwork(); + } + + @Override + protected void tearDownMeteredNetwork() throws Exception { + resetMeteredNetwork(); + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java new file mode 100644 index 0000000000..c76123822f --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2016 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.cts.net.hostside; + +public class DozeModeNonMeteredTest extends AbstractDozeModeTestCase { + + @Override + protected void setUpMeteredNetwork() throws Exception { + resetMeteredNetwork(); + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java index 140d1354bf..c97a0f91f3 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java @@ -47,7 +47,7 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { try { setRestrictBackground(false); } finally { - setPowerSaveMode(false); + setBatterySaverMode(false); } } @@ -60,7 +60,7 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { try { setRestrictBackground(true); - setPowerSaveMode(true); + setBatterySaverMode(true); Log.v(TAG, "Not whitelisted for any."); assertBackgroundNetworkAccess(false); @@ -126,7 +126,7 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } Log.i(TAG, "testDataAndBatterySaverModes_nonMeteredNetwork() tests"); setRestrictBackground(true); - setPowerSaveMode(true); + setBatterySaverMode(true); Log.v(TAG, "Not whitelisted for any."); assertBackgroundNetworkAccess(false); diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java index 1afc3d6c41..b88c45dbb4 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java @@ -28,6 +28,9 @@ import android.util.Log; */ public class MyForegroundService extends Service { + private static final int FLAG_START_FOREGROUND = 1; + private static final int FLAG_STOP_FOREGROUND = 2; + @Override public IBinder onBind(Intent intent) { return null; @@ -35,10 +38,21 @@ public class MyForegroundService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { - Log.d(TAG, "MyForegroundService.onStartCommand(): " + intent); - startForeground(42, new Notification.Builder(this) - .setSmallIcon(R.drawable.ic_dialog_alert) // any icon is fine - .build()); + Log.v(TAG, "MyForegroundService.onStartCommand(): " + intent); + switch (intent.getFlags()) { + case FLAG_START_FOREGROUND: + Log.d(TAG, "Starting foreground"); + startForeground(42, new Notification.Builder(this) + .setSmallIcon(R.drawable.ic_dialog_alert) // any icon is fine + .build()); + break; + case FLAG_STOP_FOREGROUND: + Log.d(TAG, "Stopping foreground"); + stopForeground(true); + break; + default: + Log.wtf(TAG, "Invalid flag on intent " + intent); + } return START_STICKY; } } diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java index ec375d6a47..04a02ea90b 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java @@ -39,6 +39,10 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC uninstallPackage(TEST_APP2_PKG, true); } + /************************** + * Data Saver Mode tests. * + **************************/ + public void testDataSaverMode_disabled() throws Exception { runDeviceTests(TEST_PKG, TEST_PKG + ".DataSaverModeTest", "testGetRestrictBackgroundStatus_disabled"); @@ -80,18 +84,22 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC "testGetRestrictBackgroundStatus_requiredWhitelistedPackages"); } - public void testBatterySaverMode_disabled() throws Exception { - runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeTest", + /***************************** + * Battery Saver Mode tests. * + *****************************/ + + public void testBatterySaverModeMetered_disabled() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeMeteredTest", "testBackgroundNetworkAccess_disabled"); } - public void testBatterySaverMode_whitelisted() throws Exception { - runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeTest", + public void testBatterySaverModeMetered_whitelisted() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeMeteredTest", "testBackgroundNetworkAccess_whitelisted"); } - public void testBatterySaverMode_enabled() throws Exception { - runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeTest", + public void testBatterySaverModeMetered_enabled() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeMeteredTest", "testBackgroundNetworkAccess_enabled"); } @@ -121,6 +129,88 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC "testBackgroundNetworkAccess_enabled"); } + /******************* + * App idle tests. * + *******************/ + + public void testAppIdleMetered_disabled() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleMeteredTest", + "testBackgroundNetworkAccess_disabled"); + } + + public void testAppIdleMetered_whitelisted() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleMeteredTest", + "testBackgroundNetworkAccess_whitelisted"); + } + + public void testAppIdleMetered_enabled() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleMeteredTest", + "testBackgroundNetworkAccess_enabled"); + } + + // TODO: currently power-save mode and idle uses the same whitelist, so this test would be + // redundant (as it would be testing the same as testBatterySaverMode_reinstall()) + // public void testAppIdle_reinstall() throws Exception { + // } + + public void testAppIdleNonMetered_disabled() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleNonMeteredTest", + "testBackgroundNetworkAccess_disabled"); + } + + public void testAppIdleNonMetered_whitelisted() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleNonMeteredTest", + "testBackgroundNetworkAccess_whitelisted"); + } + + public void testAppIdleNonMetered_enabled() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleNonMeteredTest", + "testBackgroundNetworkAccess_enabled"); + } + + /******************** + * Doze Mode tests. * + ********************/ + + public void testDozeModeMetered_disabled() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".DozeModeMeteredTest", + "testBackgroundNetworkAccess_disabled"); + } + + public void testDozeModeMetered_whitelisted() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".DozeModeMeteredTest", + "testBackgroundNetworkAccess_whitelisted"); + } + + public void testDozeModeMetered_enabled() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".DozeModeMeteredTest", + "testBackgroundNetworkAccess_enabled"); + } + + // TODO: currently power-save mode and idle uses the same whitelist, so this test would be + // redundant (as it would be testing the same as testBatterySaverMode_reinstall()) + // public void testDozeMode_reinstall() throws Exception { + // } + + public void testDozeModeNonMetered_disabled() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".DozeModeNonMeteredTest", + "testBackgroundNetworkAccess_disabled"); + } + + public void testDozeModeNonMetered_whitelisted() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".DozeModeNonMeteredTest", + "testBackgroundNetworkAccess_whitelisted"); + } + + public void testDozeModeNonMetered_enabled() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".DozeModeNonMeteredTest", + "testBackgroundNetworkAccess_enabled"); + } + + /********************** + * Mixed modes tests. * + **********************/ + public void testDataAndBatterySaverModes_meteredNetwork() throws Exception { runDeviceTests(TEST_PKG, TEST_PKG + ".MixedModesTest", "testDataAndBatterySaverModes_meteredNetwork"); @@ -131,6 +221,10 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC "testDataAndBatterySaverModes_nonMeteredNetwork"); } + /******************* + * Helper methods. * + *******************/ + private void assertRestrictBackgroundWhitelist(int uid, boolean expected) throws Exception { final int max_tries = 5; boolean actual = false; From cbcfb98dd8c062ddb4c5c85d8e2d7525532b383d Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Fri, 15 Apr 2016 16:27:49 +0900 Subject: [PATCH 0252/1109] Add a test for closing sockets when a VPN comes up. Bug: 28251576 Change-Id: Iab0a8643cff3c54eb04168a7cdfa116c0b8e30b1 --- tests/cts/hostside/aidl/Android.mk | 22 +++++ .../net/hostside/IRemoteSocketFactory.aidl | 25 +++++ tests/cts/hostside/app/Android.mk | 3 +- .../hostside/RemoteSocketFactoryClient.java | 91 +++++++++++++++++++ .../com/android/cts/net/hostside/VpnTest.java | 91 ++++++++++++++++++- tests/cts/hostside/app2/Android.mk | 1 + tests/cts/hostside/app2/AndroidManifest.xml | 6 +- .../app2/RemoteSocketFactoryService.java | 63 +++++++++++++ .../cts/net/HostsideNetworkTestCase.java | 2 + ...ostsideRestrictBackgroundNetworkTests.java | 3 - .../com/android/cts/net/HostsideVpnTests.java | 27 +++++- 11 files changed, 323 insertions(+), 11 deletions(-) create mode 100644 tests/cts/hostside/aidl/Android.mk create mode 100644 tests/cts/hostside/aidl/com/android/cts/net/hostside/IRemoteSocketFactory.aidl create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/RemoteSocketFactoryClient.java create mode 100644 tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/RemoteSocketFactoryService.java diff --git a/tests/cts/hostside/aidl/Android.mk b/tests/cts/hostside/aidl/Android.mk new file mode 100644 index 0000000000..a7ec6efb31 --- /dev/null +++ b/tests/cts/hostside/aidl/Android.mk @@ -0,0 +1,22 @@ +# Copyright (C) 2016 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. + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_MODULE_TAGS := tests +LOCAL_SDK_VERSION := current +LOCAL_SRC_FILES := com/android/cts/net/hostside/IRemoteSocketFactory.aidl +LOCAL_MODULE := CtsHostsideNetworkTestsAidl +include $(BUILD_JAVA_LIBRARY) diff --git a/tests/cts/hostside/aidl/com/android/cts/net/hostside/IRemoteSocketFactory.aidl b/tests/cts/hostside/aidl/com/android/cts/net/hostside/IRemoteSocketFactory.aidl new file mode 100644 index 0000000000..68176ad80d --- /dev/null +++ b/tests/cts/hostside/aidl/com/android/cts/net/hostside/IRemoteSocketFactory.aidl @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2016 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.cts.net.hostside; + +import android.os.ParcelFileDescriptor; + +interface IRemoteSocketFactory { + ParcelFileDescriptor openSocketFd(String host, int port, int timeoutMs); + String getPackageName(); + int getUid(); +} diff --git a/tests/cts/hostside/app/Android.mk b/tests/cts/hostside/app/Android.mk index 7f8da07943..9519ec5242 100644 --- a/tests/cts/hostside/app/Android.mk +++ b/tests/cts/hostside/app/Android.mk @@ -20,7 +20,8 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests LOCAL_SDK_VERSION := current -LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner ub-uiautomator +LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner ub-uiautomator \ + CtsHostsideNetworkTestsAidl LOCAL_SRC_FILES := $(call all-java-files-under, src) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RemoteSocketFactoryClient.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RemoteSocketFactoryClient.java new file mode 100644 index 0000000000..799fe50ebe --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RemoteSocketFactoryClient.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2016 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.cts.net.hostside; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.ConditionVariable; +import android.os.IBinder; +import android.os.RemoteException; + +import com.android.cts.net.hostside.IRemoteSocketFactory; + +import java.io.FileDescriptor; + +public class RemoteSocketFactoryClient { + private static final int TIMEOUT_MS = 5000; + private static final String PACKAGE = RemoteSocketFactoryClient.class.getPackage().getName(); + private static final String APP2_PACKAGE = PACKAGE + ".app2"; + private static final String SERVICE_NAME = APP2_PACKAGE + ".RemoteSocketFactoryService"; + + private Context mContext; + private ServiceConnection mServiceConnection; + private IRemoteSocketFactory mService; + + public RemoteSocketFactoryClient(Context context) { + mContext = context; + } + + public void bind() { + if (mService != null) { + throw new IllegalStateException("Already bound"); + } + + final ConditionVariable cv = new ConditionVariable(); + mServiceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + mService = IRemoteSocketFactory.Stub.asInterface(service); + cv.open(); + } + @Override + public void onServiceDisconnected(ComponentName name) { + mService = null; + } + }; + + final Intent intent = new Intent(); + intent.setComponent(new ComponentName(APP2_PACKAGE, SERVICE_NAME)); + mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); + cv.block(TIMEOUT_MS); + if (mService == null) { + throw new IllegalStateException( + "Could not bind to RemoteSocketFactory service after " + TIMEOUT_MS + "ms"); + } + } + + public void unbind() { + if (mService != null) { + mContext.unbindService(mServiceConnection); + } + } + + public FileDescriptor openSocketFd( + String host, int port, int timeoutMs) throws RemoteException { + return mService.openSocketFd(host, port, timeoutMs).getFileDescriptor(); + } + + public String getPackageName() throws RemoteException { + return mService.getPackageName(); + } + + public int getUid() throws RemoteException { + return mService.getUid(); + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java index 5045cc26b4..12fe625370 100755 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java @@ -27,6 +27,8 @@ import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkRequest; import android.net.VpnService; +import android.os.ParcelFileDescriptor; +import android.os.Process; import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiObject; import android.support.test.uiautomator.UiObjectNotFoundException; @@ -40,11 +42,18 @@ import android.test.MoreAsserts; import android.text.TextUtils; import android.util.Log; +import com.android.cts.net.hostside.IRemoteSocketFactory; + +import java.io.BufferedReader; import java.io.Closeable; import java.io.FileDescriptor; +import java.io.FileOutputStream; +import java.io.FileInputStream; +import java.io.InputStreamReader; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.PrintWriter; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.Inet6Address; @@ -52,6 +61,8 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; +import java.net.SocketException; +import java.nio.charset.StandardCharsets; import java.util.Random; /** @@ -79,11 +90,14 @@ public class VpnTest extends InstrumentationTestCase { public static String TAG = "VpnTest"; public static int TIMEOUT_MS = 3 * 1000; public static int SOCKET_TIMEOUT_MS = 100; + public static String TEST_HOST = "connectivitycheck.gstatic.com"; private UiDevice mDevice; private MyActivity mActivity; private String mPackageName; private ConnectivityManager mCM; + private RemoteSocketFactoryClient mRemoteSocketFactoryClient; + Network mNetwork; NetworkCallback mCallback; final Object mLock = new Object(); @@ -107,11 +121,14 @@ public class VpnTest extends InstrumentationTestCase { MyActivity.class, null); mPackageName = mActivity.getPackageName(); mCM = (ConnectivityManager) mActivity.getSystemService(mActivity.CONNECTIVITY_SERVICE); + mRemoteSocketFactoryClient = new RemoteSocketFactoryClient(mActivity); + mRemoteSocketFactoryClient.bind(); mDevice.waitForIdle(); } @Override public void tearDown() throws Exception { + mRemoteSocketFactoryClient.unbind(); if (mCallback != null) { mCM.unregisterNetworkCallback(mCallback); } @@ -441,7 +458,7 @@ public class VpnTest extends InstrumentationTestCase { } } - private void checkTrafficOnVpn() throws IOException, ErrnoException { + private void checkTrafficOnVpn() throws Exception { checkUdpEcho("192.0.2.251", "192.0.2.2"); checkUdpEcho("2001:db8:dead:beef::f00", "2001:db8:1:2::ffe"); checkPing("2001:db8:dead:beef::f00"); @@ -449,29 +466,88 @@ public class VpnTest extends InstrumentationTestCase { checkTcpReflection("2001:db8:dead:beef::f00", "2001:db8:1:2::ffe"); } - private void checkNoTrafficOnVpn() throws IOException, ErrnoException { + private void checkNoTrafficOnVpn() throws Exception { checkUdpEcho("192.0.2.251", null); checkUdpEcho("2001:db8:dead:beef::f00", null); checkTcpReflection("192.0.2.252", null); checkTcpReflection("2001:db8:dead:beef::f00", null); } + private FileDescriptor openSocketFd(String host, int port, int timeoutMs) throws Exception { + Socket s = new Socket(host, port); + s.setSoTimeout(timeoutMs); + return ParcelFileDescriptor.fromSocket(s).getFileDescriptor(); + } + + private FileDescriptor openSocketFdInOtherApp( + String host, int port, int timeoutMs) throws Exception { + Log.d(TAG, String.format("Creating test socket in UID=%d, my UID=%d", + mRemoteSocketFactoryClient.getUid(), Os.getuid())); + FileDescriptor fd = mRemoteSocketFactoryClient.openSocketFd(host, port, TIMEOUT_MS); + return fd; + } + + private void sendRequest(FileDescriptor fd, String host) throws Exception { + String request = "GET /generate_204 HTTP/1.1\r\n" + + "Host: " + host + "\r\n" + + "Connection: keep-alive\r\n\r\n"; + byte[] requestBytes = request.getBytes(StandardCharsets.UTF_8); + int ret = Os.write(fd, requestBytes, 0, requestBytes.length); + Log.d(TAG, "Wrote " + ret + "bytes"); + + String expected = "HTTP/1.1 204 No Content\r\n"; + byte[] response = new byte[expected.length()]; + Os.read(fd, response, 0, response.length); + + String actual = new String(response, StandardCharsets.UTF_8); + assertEquals(expected, actual); + Log.d(TAG, "Got response: " + actual); + } + + private void assertSocketStillOpen(FileDescriptor fd, String host) throws Exception { + try { + sendRequest(fd, host); + } finally { + Os.close(fd); + } + } + + private void assertSocketClosed(FileDescriptor fd, String host) throws Exception { + try { + sendRequest(fd, host); + fail("Socket opened before VPN connects should be closed when VPN connects"); + } catch (ErrnoException expected) { + assertEquals(ECONNABORTED, expected.errno); + } finally { + Os.close(fd); + } + } + public void testDefault() throws Exception { if (!supportedHardware()) return; + FileDescriptor fd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS); + startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"}, new String[] {"0.0.0.0/0", "::/0"}, "", ""); + assertSocketClosed(fd, TEST_HOST); + checkTrafficOnVpn(); } public void testAppAllowed() throws Exception { if (!supportedHardware()) return; + FileDescriptor fd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS); + + String allowedApps = mRemoteSocketFactoryClient.getPackageName() + "," + mPackageName; startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"}, new String[] {"192.0.2.0/24", "2001:db8::/32"}, - mPackageName, ""); + allowedApps, ""); + + assertSocketClosed(fd, TEST_HOST); checkTrafficOnVpn(); } @@ -479,9 +555,16 @@ public class VpnTest extends InstrumentationTestCase { public void testAppDisallowed() throws Exception { if (!supportedHardware()) return; + FileDescriptor localFd = openSocketFd(TEST_HOST, 80, TIMEOUT_MS); + FileDescriptor remoteFd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS); + + String disallowedApps = mRemoteSocketFactoryClient.getPackageName() + "," + mPackageName; startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"}, new String[] {"192.0.2.0/24", "2001:db8::/32"}, - "", mPackageName); + "", disallowedApps); + + assertSocketStillOpen(localFd, TEST_HOST); + assertSocketStillOpen(remoteFd, TEST_HOST); checkNoTrafficOnVpn(); } diff --git a/tests/cts/hostside/app2/Android.mk b/tests/cts/hostside/app2/Android.mk index 3b59f8f6ce..706455d563 100644 --- a/tests/cts/hostside/app2/Android.mk +++ b/tests/cts/hostside/app2/Android.mk @@ -20,6 +20,7 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests LOCAL_SDK_VERSION := current +LOCAL_STATIC_JAVA_LIBRARIES := CtsHostsideNetworkTestsAidl LOCAL_SRC_FILES := $(call all-java-files-under, src) diff --git a/tests/cts/hostside/app2/AndroidManifest.xml b/tests/cts/hostside/app2/AndroidManifest.xml index 9c4884b525..80b669d4eb 100644 --- a/tests/cts/hostside/app2/AndroidManifest.xml +++ b/tests/cts/hostside/app2/AndroidManifest.xml @@ -29,11 +29,15 @@ The manifest-defined listener also handles ordered broadcasts used to share data with the test app. + + This application also provides a service, RemoteSocketFactoryService, that the test app can + use to open sockets to remote hosts as a different user ID. --> + @@ -45,4 +49,4 @@ - \ No newline at end of file + diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/RemoteSocketFactoryService.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/RemoteSocketFactoryService.java new file mode 100644 index 0000000000..b1b7d77ae1 --- /dev/null +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/RemoteSocketFactoryService.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2016 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.cts.net.hostside.app2; + +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.os.IBinder; +import android.os.ParcelFileDescriptor; +import android.os.Process; +import android.util.Log; + +import com.android.cts.net.hostside.IRemoteSocketFactory; + +import java.net.Socket; + + +public class RemoteSocketFactoryService extends Service { + + private static final String TAG = RemoteSocketFactoryService.class.getSimpleName(); + + private IRemoteSocketFactory.Stub mBinder = new IRemoteSocketFactory.Stub() { + @Override + public ParcelFileDescriptor openSocketFd(String host, int port, int timeoutMs) { + try { + Socket s = new Socket(host, port); + s.setSoTimeout(timeoutMs); + return ParcelFileDescriptor.fromSocket(s); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } + + @Override + public String getPackageName() { + return RemoteSocketFactoryService.this.getPackageName(); + } + + @Override + public int getUid() { + return Process.myUid(); + } + }; + + @Override + public IBinder onBind(Intent intent) { + return mBinder; + } +} diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java index 39b5652c76..6642512758 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java @@ -42,6 +42,8 @@ abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiRec protected static final String TAG = "HostsideNetworkTests"; protected static final String TEST_PKG = "com.android.cts.net.hostside"; protected static final String TEST_APK = "CtsHostsideNetworkTestsApp.apk"; + protected static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2"; + protected static final String TEST_APP2_APK = "CtsHostsideNetworkTestsApp2.apk"; private IAbi mAbi; private IBuildInfo mCtsBuild; diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java index ec375d6a47..1a8634e584 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java @@ -21,9 +21,6 @@ import com.android.tradefed.device.DeviceNotAvailableException; public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestCase { - private static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2"; - private static final String TEST_APP2_APK = "CtsHostsideNetworkTestsApp2.apk"; - @Override protected void setUp() throws Exception { super.setUp(); diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java index dc965c50f8..69b07af193 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java @@ -18,7 +18,30 @@ package com.android.cts.net; public class HostsideVpnTests extends HostsideNetworkTestCase { - public void testVpn() throws Exception { - runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest"); + @Override + protected void setUp() throws Exception { + super.setUp(); + + uninstallPackage(TEST_APP2_PKG, false); + installPackage(TEST_APP2_APK); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + + uninstallPackage(TEST_APP2_PKG, true); + } + + public void testDefault() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testDefault"); + } + + public void testAppAllowed() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testAppAllowed"); + } + + public void testAppDisallowed() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testAppDisallowed"); } } From 36f05df51f4ce35069fc80f19d66f961838c4211 Mon Sep 17 00:00:00 2001 From: Phil Weaver Date: Tue, 17 May 2016 14:40:21 -0700 Subject: [PATCH 0253/1109] CTS coverage: connectivity change, photo, + video Confirming that connectivity change broadcasts can be received when explicitly registering for them in N, and via the manifest pre-N. Confirming that new_photo and new_video broadcasts are not received. Bug: 28122277 Change-Id: Icfc27364a41ee8f4a55920e295ba658a367bb7d2 --- tests/cts/net/AndroidTest.xml | 1 + tests/cts/net/appForApi23/Android.mk | 38 ++++++++ tests/cts/net/appForApi23/AndroidManifest.xml | 47 +++++++++ .../ConnectivityListeningActivity.java | 22 +++++ .../cts/appForApi23/ConnectivityReceiver.java | 38 ++++++++ .../net/cts/ConnectivityManagerTest.java | 97 ++++++++++++++----- 6 files changed, 218 insertions(+), 25 deletions(-) create mode 100644 tests/cts/net/appForApi23/Android.mk create mode 100644 tests/cts/net/appForApi23/AndroidManifest.xml create mode 100644 tests/cts/net/appForApi23/src/android/net/cts/appForApi23/ConnectivityListeningActivity.java create mode 100644 tests/cts/net/appForApi23/src/android/net/cts/appForApi23/ConnectivityReceiver.java diff --git a/tests/cts/net/AndroidTest.xml b/tests/cts/net/AndroidTest.xml index 5194da37d2..389b926f83 100644 --- a/tests/cts/net/AndroidTest.xml +++ b/tests/cts/net/AndroidTest.xml @@ -16,6 +16,7 @@

    @@ -85,6 +90,9 @@ public class MyBroadcastReceiver extends BroadcastReceiver { Log.d(TAG, message); setResultData(message); break; + case ACTION_SEND_NOTIFICATION: + sendNotification(context, intent); + break; default: Log.e(TAG, "received unexpected action: " + action); } @@ -213,4 +221,23 @@ public class MyBroadcastReceiver extends BroadcastReceiver { final int counter = getCounter(context, action, receiverName); setResultData(String.valueOf(counter)); } + + /** + * Sends a system notification containing actions with pending intents to launch the app's + * main activitiy or service. + */ + private void sendNotification(Context context, Intent intent) { + final int notificationId = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1); + final Intent serviceIntent = new Intent(context, MyService.class); + final PendingIntent pendingIntent = PendingIntent.getService(context, 0, serviceIntent, 0); + + final Notification notification = new Notification.Builder(context) + .setSmallIcon(R.drawable.ic_notification) + .setContentTitle("Light, Cameras...") + .setContentIntent(pendingIntent) + .addAction(R.drawable.ic_notification, "ACTION", pendingIntent) + .build(); + ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE)) + .notify(notificationId, notification); + } } diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java index 8152e55297..c741b12fd0 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java @@ -184,6 +184,11 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC "testBackgroundNetworkAccess_enabled"); } + public void testDozeModeMetered_enabledButWhitelistedOnNotificationAction() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".DozeModeMeteredTest", + "testBackgroundNetworkAccess_enabledButWhitelistedOnNotificationAction"); + } + // TODO: currently power-save mode and idle uses the same whitelist, so this test would be // redundant (as it would be testing the same as testBatterySaverMode_reinstall()) // public void testDozeMode_reinstall() throws Exception { @@ -204,6 +209,12 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC "testBackgroundNetworkAccess_enabled"); } + public void testDozeModeNonMetered_enabledButWhitelistedOnNotificationAction() + throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".DozeModeNonMeteredTest", + "testBackgroundNetworkAccess_enabledButWhitelistedOnNotificationAction"); + } + /********************** * Mixed modes tests. * **********************/ From b9b85ce0cd8126e63445d13f94fd3a7732f39c83 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Thu, 2 Jun 2016 09:08:49 -0700 Subject: [PATCH 0258/1109] Add flakyness check when a valid connection is expected. BUG: 29082308 Change-Id: Iadb9a0bd7fbd307d799af7a7a5dabc0ed000bc6d --- ...stractRestrictBackgroundNetworkTestCase.java | 17 ++++++++++++----- .../net/hostside/app2/MyBroadcastReceiver.java | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index ba383a88b7..3125dfa50b 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -269,8 +269,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation private void assertNetworkAccess(boolean expectAvailable) throws Exception { final Intent intent = new Intent(ACTION_CHECK_NETWORK); - // When the network info state change, it's possible the app still get the previous value, - // so we need to retry a couple times. final int maxTries = 5; String resultData = null; for (int i = 1; i <= maxTries; i++) { @@ -287,8 +285,14 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation final String networkInfo = parts[4]; if (expectAvailable) { - assertTrue("should be connected: " + connectionCheckDetails - + " (network info: " + networkInfo + ")", connected); + if (!connected) { + // Since it's establishing a connection to an external site, it could be flaky. + Log.w(TAG, "Failed to connect to an external site on attempt #" + i + + " (error: " + connectionCheckDetails + ", NetworkInfo: " + networkInfo + + "); sleeping " + NETWORK_TIMEOUT_MS + "ms before trying again"); + SystemClock.sleep(NETWORK_TIMEOUT_MS); + continue; + } if (state != State.CONNECTED) { Log.d(TAG, "State (" + state + ") not set to CONNECTED on attempt #" + i + "; sleeping 1s before trying again"); @@ -303,6 +307,8 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation assertFalse("should not be connected: " + connectionCheckDetails + " (network info: " + networkInfo + ")", connected); if (state != State.DISCONNECTED) { + // When the network info state change, it's possible the app still get the + // previous value, so we need to retry a couple times. Log.d(TAG, "State (" + state + ") not set to DISCONNECTED on attempt #" + i + "; sleeping 1s before trying again"); SystemClock.sleep(SECOND_IN_MS); @@ -313,7 +319,8 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation } } } - fail("Invalid state after " + maxTries + " attempts. Last data: " + resultData); + fail("Invalid state for expectAvailable=" + expectAvailable + " after " + maxTries + + " attempts. Last data: " + resultData); } protected String executeShellCommand(String command) throws Exception { diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java index 96e9d2bab4..0eff6abdf8 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java @@ -174,7 +174,7 @@ public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void run() { // TODO: connect to a hostside server instead - final String address = "http://example.com"; + final String address = "http://google.com"; final NetworkInfo networkInfo = cm.getActiveNetworkInfo(); Log.d(TAG, "Running checkNetworkStatus() on thread " + Thread.currentThread().getName() + " for UID " + getUid(context) From d1f3d68694f49339397a3046c77bf0ee30d8d14f Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Thu, 2 Jun 2016 12:01:26 -0700 Subject: [PATCH 0259/1109] Skip Doze Mode-related tests when device does not support it. Fixes: 29072117 Change-Id: I7ca37eae58258c021ed6297a9f1ee3b2749da7d7 --- .../net/hostside/AbstractAppIdleTestCase.java | 22 +++++++++++++++++ .../AbstractBatterySaverModeTestCase.java | 22 +++++++++++++++++ .../hostside/AbstractDozeModeTestCase.java | 23 ++++++++++++++++++ ...ractRestrictBackgroundNetworkTestCase.java | 24 +++++++++++++++++++ .../cts/net/hostside/DataSaverModeTest.java | 14 +++++++++++ .../cts/net/hostside/MixedModesTest.java | 20 ++++++++++++++++ ...ostsideRestrictBackgroundNetworkTests.java | 11 +++++++++ 7 files changed, 136 insertions(+) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java index 13ce6cee0a..ba56665fbc 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java @@ -16,6 +16,8 @@ package com.android.cts.net.hostside; +import android.util.Log; + /** * Base class for metered and non-metered tests on idle apps. */ @@ -25,6 +27,8 @@ abstract class AbstractAppIdleTestCase extends AbstractRestrictBackgroundNetwork protected final void setUp() throws Exception { super.setUp(); + if (!isSupported()) return; + // Set initial state. setUpMeteredNetwork(); removePowerSaveModeWhitelist(TEST_APP2_PKG); @@ -38,6 +42,8 @@ abstract class AbstractAppIdleTestCase extends AbstractRestrictBackgroundNetwork protected final void tearDown() throws Exception { super.tearDown(); + if (!isSupported()) return; + try { tearDownMeteredNetwork(); } finally { @@ -46,6 +52,16 @@ abstract class AbstractAppIdleTestCase extends AbstractRestrictBackgroundNetwork } } + @Override + protected boolean isSupported() throws Exception { + boolean supported = isDozeModeEnabled(); + if (!supported) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Doze Mode"); + } + return supported; + } + /** * Sets the initial (non) metered network state. * @@ -63,6 +79,8 @@ abstract class AbstractAppIdleTestCase extends AbstractRestrictBackgroundNetwork } public void testBackgroundNetworkAccess_enabled() throws Exception { + if (!isSupported()) return; + setAppIdle(true); assertBackgroundNetworkAccess(false); @@ -92,6 +110,8 @@ abstract class AbstractAppIdleTestCase extends AbstractRestrictBackgroundNetwork } public void testBackgroundNetworkAccess_whitelisted() throws Exception { + if (!isSupported()) return; + setAppIdle(true); assertBackgroundNetworkAccess(false); @@ -111,6 +131,8 @@ abstract class AbstractAppIdleTestCase extends AbstractRestrictBackgroundNetwork } public void testBackgroundNetworkAccess_disabled() throws Exception { + if (!isSupported()) return; + assertBackgroundNetworkAccess(true); assertsForegroundAlwaysHasNetworkAccess(); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java index 2acc670800..c1c91dac80 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java @@ -16,6 +16,8 @@ package com.android.cts.net.hostside; +import android.util.Log; + /** * Base class for metered and non-metered Battery Saver Mode tests. */ @@ -25,6 +27,8 @@ abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgrou protected final void setUp() throws Exception { super.setUp(); + if (!isSupported()) return; + // Set initial state. setUpMeteredNetwork(); removePowerSaveModeWhitelist(TEST_APP2_PKG); @@ -37,6 +41,8 @@ abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgrou protected final void tearDown() throws Exception { super.tearDown(); + if (!isSupported()) return; + try { tearDownMeteredNetwork(); } finally { @@ -44,6 +50,16 @@ abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgrou } } + @Override + protected boolean isSupported() throws Exception { + boolean supported = isDozeModeEnabled(); + if (!supported) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Doze Mode"); + } + return supported; + } + /** * Sets the initial (non) metered network state. * @@ -61,6 +77,8 @@ abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgrou } public void testBackgroundNetworkAccess_enabled() throws Exception { + if (!isSupported()) return; + setBatterySaverMode(true); assertBackgroundNetworkAccess(false); @@ -87,6 +105,8 @@ abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgrou } public void testBackgroundNetworkAccess_whitelisted() throws Exception { + if (!isSupported()) return; + setBatterySaverMode(true); assertBackgroundNetworkAccess(false); @@ -101,6 +121,8 @@ abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgrou } public void testBackgroundNetworkAccess_disabled() throws Exception { + if (!isSupported()) return; + assertBackgroundNetworkAccess(true); assertsForegroundAlwaysHasNetworkAccess(); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java index e0ba76b866..b89cf93b99 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java @@ -17,6 +17,7 @@ package com.android.cts.net.hostside; import android.os.SystemClock; +import android.util.Log; /** * Base class for metered and non-metered Doze Mode tests. @@ -27,6 +28,8 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor protected final void setUp() throws Exception { super.setUp(); + if (!isSupported()) return; + // Set initial state. setUpMeteredNetwork(); removePowerSaveModeWhitelist(TEST_APP2_PKG); @@ -39,6 +42,8 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor protected final void tearDown() throws Exception { super.tearDown(); + if (!isSupported()) return; + try { tearDownMeteredNetwork(); } finally { @@ -46,6 +51,16 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor } } + @Override + protected boolean isSupported() throws Exception { + boolean supported = isDozeModeEnabled(); + if (!supported) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Doze Mode"); + } + return supported; + } + /** * Sets the initial (non) metered network state. * @@ -63,6 +78,8 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor } public void testBackgroundNetworkAccess_enabled() throws Exception { + if (!isSupported()) return; + setDozeMode(true); assertBackgroundNetworkAccess(false); @@ -81,6 +98,8 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor } public void testBackgroundNetworkAccess_whitelisted() throws Exception { + if (!isSupported()) return; + setDozeMode(true); assertBackgroundNetworkAccess(false); @@ -95,6 +114,8 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor } public void testBackgroundNetworkAccess_disabled() throws Exception { + if (!isSupported()) return; + assertBackgroundNetworkAccess(true); assertsForegroundAlwaysHasNetworkAccess(); @@ -103,6 +124,8 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor public void testBackgroundNetworkAccess_enabledButWhitelistedOnNotificationAction() throws Exception { + if (!isSupported()) return; + setPendingIntentWhitelistDuration(NETWORK_TIMEOUT_MS); try { registerNotificationListenerService(); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 3125dfa50b..439fbbe0c9 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -187,6 +187,22 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation assertNetworkAccess(true); } + /** + * Whether this device suport this type of test. + * + *

    Should be overridden when necessary, and explicitly used before each test. Example: + * + *

    
    +     * public void testSomething() {
    +     *    if (!isSupported()) return;
    +     * 
    + * + * @return {@code true} by default. + */ + protected boolean isSupported() throws Exception { + return true; + } + /** * Asserts that an app always have access while on foreground or running a foreground service. * @@ -598,6 +614,9 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation } protected void setDozeMode(boolean enabled) throws Exception { + // Sanity check, since tests should check beforehand.... + assertTrue("Device does not support Doze Mode", isDozeModeEnabled()); + Log.i(TAG, "Setting Doze Mode to " + enabled); if (enabled) { turnBatteryOff(); @@ -616,6 +635,11 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation assertDelayedShellCommand("dumpsys deviceidle get deep", enabled ? "IDLE" : "ACTIVE"); } + protected boolean isDozeModeEnabled() throws Exception { + final String result = executeShellCommand("cmd deviceidle enabled deep").trim(); + return result.equals("1"); + } + protected void setAppIdle(boolean enabled) throws Exception { Log.i(TAG, "Setting app idle to " + enabled); executeSilentShellCommand("am set-inactive " + TEST_APP2_PKG + " " + enabled ); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index 189515683c..3e6bd3320a 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -30,6 +30,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase public void setUp() throws Exception { super.setUp(); + if (!isSupported()) return; + // Set initial state. setMeteredNetwork(); setRestrictBackground(false); @@ -44,6 +46,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase protected void tearDown() throws Exception { super.tearDown(); + if (!isSupported()) return; + try { resetMeteredNetwork(); } finally { @@ -52,6 +56,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase } public void testGetRestrictBackgroundStatus_disabled() throws Exception { + if (!isSupported()) return; + assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED); // Sanity check: make sure status is always disabled, never whitelisted @@ -64,6 +70,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase } public void testGetRestrictBackgroundStatus_whitelisted() throws Exception { + if (!isSupported()) return; + setRestrictBackground(true); assertRestrictBackgroundChangedReceived(1); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); @@ -81,6 +89,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase } public void testGetRestrictBackgroundStatus_enabled() throws Exception { + if (!isSupported()) return; + setRestrictBackground(true); assertRestrictBackgroundChangedReceived(1); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); @@ -108,6 +118,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase } public void testGetRestrictBackgroundStatus_blacklisted() throws Exception { + if (!isSupported()) return; + addRestrictBackgroundBlacklist(mUid); assertRestrictBackgroundChangedReceived(1); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); @@ -136,6 +148,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase } public void testGetRestrictBackgroundStatus_requiredWhitelistedPackages() throws Exception { + if (!isSupported()) return; + final StringBuilder error = new StringBuilder(); for (String packageName : REQUIRED_WHITELISTED_PACKAGES) { int uid = -1; diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java index c97a0f91f3..af52eeece4 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java @@ -32,6 +32,8 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { public void setUp() throws Exception { super.setUp(); + if (!isSupported()) return; + // Set initial state. removeRestrictBackgroundWhitelist(mUid); removeRestrictBackgroundBlacklist(mUid); @@ -44,6 +46,8 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { protected void tearDown() throws Exception { super.tearDown(); + if (!isSupported()) return; + try { setRestrictBackground(false); } finally { @@ -55,6 +59,14 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { * Tests all DS ON and BS ON scenarios from network-policy-restrictions.md on metered networks. */ public void testDataAndBatterySaverModes_meteredNetwork() throws Exception { + if (!isSupported()) return; + + if (!isDozeModeEnabled()) { + Log.w(TAG, "testDataAndBatterySaverModes_meteredNetwork() skipped because " + + "device does not support Doze Mode"); + return; + } + Log.i(TAG, "testDataAndBatterySaverModes_meteredNetwork() tests"); setMeteredNetwork(); @@ -119,6 +131,14 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { * networks. */ public void testDataAndBatterySaverModes_nonMeteredNetwork() throws Exception { + if (!isSupported()) return; + + if (!isDozeModeEnabled()) { + Log.w(TAG, "testDataAndBatterySaverModes_nonMeteredNetwork() skipped because " + + "device does not support Doze Mode"); + return; + } + if (mCm.isActiveNetworkMetered()) { Log.w(TAG, "testDataAndBatterySaverModes_nonMeteredNetwork() skipped because network" + " is metered"); diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java index c741b12fd0..7d5f817798 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java @@ -101,6 +101,12 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC } public void testBatterySaverMode_reinstall() throws Exception { + if (!isDozeModeEnabled()) { + Log.w(TAG, "testBatterySaverMode_reinstall() skipped because device does not support " + + "Doze Mode"); + return; + } + addPowerSaveModeWhitelist(TEST_APP2_PKG); uninstallPackage(TEST_APP2_PKG, true); @@ -287,4 +293,9 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC runCommand("dumpsys deviceidle whitelist +" + packageName); assertPowerSaveModeWhitelist(packageName, true); // Sanity check } + + protected boolean isDozeModeEnabled() throws Exception { + final String result = runCommand("cmd deviceidle enabled deep").trim(); + return result.equals("1"); + } } From 829443c140d65ab2d352539d3c67dbd9f669f3c3 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Mon, 6 Jun 2016 09:02:09 -0700 Subject: [PATCH 0260/1109] Changed network check URL. It cannot use google.com because it's blocked in some countries where CTS tests are run. BUG: 29082308 Change-Id: I749659ec2cd33248fddbe5b4ab02bd6e90f24a67 --- .../com/android/cts/net/hostside/app2/MyBroadcastReceiver.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java index 0eff6abdf8..96e9d2bab4 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java @@ -174,7 +174,7 @@ public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void run() { // TODO: connect to a hostside server instead - final String address = "http://google.com"; + final String address = "http://example.com"; final NetworkInfo networkInfo = cm.getActiveNetworkInfo(); Log.d(TAG, "Running checkNetworkStatus() on thread " + Thread.currentThread().getName() + " for UID " + getUid(context) From 1d75845bd564bc36171e0f697c8306d65b967229 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Thu, 9 Jun 2016 14:23:21 +0900 Subject: [PATCH 0261/1109] Log the address of the IPv4 address that causes the test to fail. Bug: 29231261 Change-Id: I6aac389d2c234091a284486422ee663119d021a9 --- tests/cts/net/src/android/net/cts/DnsTest.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/DnsTest.java b/tests/cts/net/src/android/net/cts/DnsTest.java index fed0a8dee8..c6a8962748 100644 --- a/tests/cts/net/src/android/net/cts/DnsTest.java +++ b/tests/cts/net/src/android/net/cts/DnsTest.java @@ -89,17 +89,15 @@ public class DnsTest extends AndroidTestCase { addrs = InetAddress.getAllByName("ipv6.google.com"); } catch (UnknownHostException e) {} assertTrue(addrs.length != 0); - foundV4 = false; foundV6 = false; for (InetAddress addr : addrs) { - if (addr instanceof Inet4Address) foundV4 = true; - else if (addr instanceof Inet6Address) foundV6 = true; + assertFalse ("[RERUN] ipv6.google.com returned IPv4 address: " + addr.getHostAddress() + + ", check your network's DNS connection", addr instanceof Inet4Address); + foundV6 |= (addr instanceof Inet6Address); if (DBG) Log.e(TAG, "ipv6.google.com gave " + addr.toString()); } - assertTrue("[RERUN] ipv6.google.com returned an ipv4 address, check your network's DNS connection.", - foundV4 == false); - assertTrue(foundV6 == true); + assertTrue(foundV6); assertTrue(testNativeDns()); } From c3a9008e3d8d45c754a4ad6733984d95fd1c4e2b Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Thu, 16 Jun 2016 10:03:27 -0700 Subject: [PATCH 0262/1109] Add non-parcelable extras to notification to make sure it does not crash the app. BUG: 29402928 Change-Id: I4fc47535ae14e71c50b25285b2fe5375abdb4f11 --- .../cts/net/hostside/app2/MyBroadcastReceiver.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java index 96e9d2bab4..60e5de1b9a 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java @@ -31,6 +31,7 @@ import static com.android.cts.net.hostside.app2.Common.TAG; import static com.android.cts.net.hostside.app2.Common.getUid; import android.app.Notification; +import android.app.Notification.Action; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; @@ -39,6 +40,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.net.ConnectivityManager; import android.net.NetworkInfo; +import android.os.Bundle; import android.util.Log; import java.net.HttpURLConnection; @@ -230,12 +232,18 @@ public class MyBroadcastReceiver extends BroadcastReceiver { final int notificationId = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1); final Intent serviceIntent = new Intent(context, MyService.class); final PendingIntent pendingIntent = PendingIntent.getService(context, 0, serviceIntent, 0); + final Bundle badBundle = new Bundle(); + badBundle.putCharSequence("parcelable", "I am not"); + final Action action = new Action.Builder( + R.drawable.ic_notification, "ACTION", pendingIntent) + .addExtras(badBundle) + .build(); final Notification notification = new Notification.Builder(context) .setSmallIcon(R.drawable.ic_notification) .setContentTitle("Light, Cameras...") .setContentIntent(pendingIntent) - .addAction(R.drawable.ic_notification, "ACTION", pendingIntent) + .addAction(action) .build(); ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE)) .notify(notificationId, notification); From 349f7ed040a1c291a6b32e9112484d1c6636db76 Mon Sep 17 00:00:00 2001 From: Jun Tahara Date: Mon, 20 Jun 2016 14:47:29 +0900 Subject: [PATCH 0263/1109] Remove non-CTS packets assertion code Symptom: testTrafficStatsForLocalhost fails when applications or services except CTS are using network. Root cause: testTrafficStatsForLocalhost can't calculate the number of non-localhost packets for CTS. It includes the all of packets for applications/services except CTS and non-localhost packets for CTS. Solution: Remove this assertion and only logging the number of packets. Change-Id: I49243d59f359f3a543c6bdb46f6a2645cde8f292 --- tests/cts/net/src/android/net/cts/TrafficStatsTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java index a8dd8acecc..930c74255d 100755 --- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java +++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java @@ -214,8 +214,6 @@ public class TrafficStatsTest extends AndroidTestCase { long deltaRxOtherPackets = (totalRxPacketsAfter - totalRxPacketsBefore) - uidRxDeltaPackets; if (deltaTxOtherPackets > 0 || deltaRxOtherPackets > 0) { Log.i(LOG_TAG, "lingering traffic data: " + deltaTxOtherPackets + "/" + deltaRxOtherPackets); - // Make sure that not too many non-localhost packets are accounted for - assertTrue("too many non-localhost packets on the same UID", deltaTxOtherPackets + deltaRxOtherPackets < 20); } assertTrue("uidtxp: " + uidTxPacketsBefore + " -> " + uidTxPacketsAfter + " delta=" + uidTxDeltaPackets + From abc35d5527b1621e4e672768688f1b9461cbe14a Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Tue, 21 Jun 2016 10:53:07 +0900 Subject: [PATCH 0264/1109] Clear local test results across DNS lookups. If InetAddress.getAllByName("ipv6.google.com") throws UnknownHostException, the test silently ignores it. This causes a misleading failure, because the test then reuses the addrs variable that is left over from the previous DNS query for "www.google.com", and fails because it has an IPv4 address. Fixes: 12210306 Bug: 29231261 Change-Id: I1dde945765d40a84eba139055306b07ebc97d0ec --- tests/cts/net/src/android/net/cts/DnsTest.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/DnsTest.java b/tests/cts/net/src/android/net/cts/DnsTest.java index c6a8962748..8575c338dd 100644 --- a/tests/cts/net/src/android/net/cts/DnsTest.java +++ b/tests/cts/net/src/android/net/cts/DnsTest.java @@ -62,8 +62,8 @@ public class DnsTest extends AndroidTestCase { try { addrs = InetAddress.getAllByName("www.google.com"); } catch (UnknownHostException e) {} - assertTrue("[RERUN] DNS could not resolve www.gooogle.com. Check internet connection", - addrs.length != 0); + assertTrue("[RERUN] DNS could not resolve www.google.com. Check internet connection", + addrs.length != 0); boolean foundV4 = false, foundV6 = false; for (InetAddress addr : addrs) { if (addr instanceof Inet4Address) foundV4 = true; @@ -71,11 +71,8 @@ public class DnsTest extends AndroidTestCase { if (DBG) Log.e(TAG, "www.google.com gave " + addr.toString()); } - // assertTrue(foundV4); - // assertTrue(foundV6); - // We should have at least one of the addresses to connect! - assertTrue(foundV4 || foundV6); + assertTrue("www.google.com must have IPv4 and/or IPv6 address", foundV4 || foundV6); // Skip the rest of the test if the active network for watch is PROXY. // TODO: Check NetworkInfo type in addition to type name once ag/601257 is merged. @@ -85,14 +82,17 @@ public class DnsTest extends AndroidTestCase { return; } + // Clear test state so we don't get confused with the previous results. + addrs = new InetAddress[0]; + foundV4 = foundV6 = false; try { addrs = InetAddress.getAllByName("ipv6.google.com"); } catch (UnknownHostException e) {} - assertTrue(addrs.length != 0); - foundV6 = false; + assertTrue("[RERUN] DNS could not resolve ipv6.google.com, check the network supports IPv6", + addrs.length != 0); for (InetAddress addr : addrs) { assertFalse ("[RERUN] ipv6.google.com returned IPv4 address: " + addr.getHostAddress() + - ", check your network's DNS connection", addr instanceof Inet4Address); + ", check your network's DNS server", addr instanceof Inet4Address); foundV6 |= (addr instanceof Inet6Address); if (DBG) Log.e(TAG, "ipv6.google.com gave " + addr.toString()); } From 60bd0b56fb447fa1021f9f48008297479dcc3d4f Mon Sep 17 00:00:00 2001 From: Chih-Hung Hsieh Date: Thu, 9 Jun 2016 13:32:31 -0700 Subject: [PATCH 0265/1109] Fix misc-macro-parentheses warnings in cts. Add parentheses around macro arguments used beside operators. Use 'aoto' type to avoid clang-tidy warnings of missing parentheses of 'TYPE *'. Bug: 28705665 Change-Id: I5d2c3b2bdfb7775200f31a011758b9a35b14794d --- tests/cts/net/jni/NativeMultinetworkJni.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/jni/NativeMultinetworkJni.c b/tests/cts/net/jni/NativeMultinetworkJni.c index ad56b510c3..6990efa452 100644 --- a/tests/cts/net/jni/NativeMultinetworkJni.c +++ b/tests/cts/net/jni/NativeMultinetworkJni.c @@ -30,7 +30,7 @@ #include #include -#define UNUSED(X) ((void) X) +#define UNUSED(X) ((void) (X)) static const char kHostname[] = "connectivitycheck.android.com"; From 0d7d1da50366788ed999c3d28e1ee0d87cfda838 Mon Sep 17 00:00:00 2001 From: Phil Weaver Date: Wed, 22 Jun 2016 16:50:38 -0700 Subject: [PATCH 0266/1109] CTS: Only listen to wifi events when toggling wifi When counting all connectivity changed events, we were failing on devices with sim cards because we were counting both wifi and mobile connectivity changes the same. Since the test only toggles wifi, changing the listener only to pay attention to wifi changes. Bug: 29346253 Change-Id: I1ed3b976bc21419218c780d4afc4a5e73f128496 --- tests/cts/net/appForApi23/AndroidManifest.xml | 2 +- .../net/cts/appForApi23/ConnectivityReceiver.java | 15 +++++++++------ .../android/net/cts/ConnectivityManagerTest.java | 8 ++++---- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/tests/cts/net/appForApi23/AndroidManifest.xml b/tests/cts/net/appForApi23/AndroidManifest.xml index 7203ea553f..ed4cedbc1d 100644 --- a/tests/cts/net/appForApi23/AndroidManifest.xml +++ b/tests/cts/net/appForApi23/AndroidManifest.xml @@ -28,7 +28,7 @@ - + diff --git a/tests/cts/net/appForApi23/src/android/net/cts/appForApi23/ConnectivityReceiver.java b/tests/cts/net/appForApi23/src/android/net/cts/appForApi23/ConnectivityReceiver.java index 5dd77e85dd..8039a4f943 100644 --- a/tests/cts/net/appForApi23/src/android/net/cts/appForApi23/ConnectivityReceiver.java +++ b/tests/cts/net/appForApi23/src/android/net/cts/appForApi23/ConnectivityReceiver.java @@ -21,18 +21,21 @@ import android.content.Intent; import android.net.ConnectivityManager; public class ConnectivityReceiver extends BroadcastReceiver { - public static String GET_CONNECTIVITY_ACTION_COUNT = - "android.net.cts.appForApi23.getConnectivityActionCount"; + public static String GET_WIFI_CONNECTIVITY_ACTION_COUNT = + "android.net.cts.appForApi23.getWifiConnectivityActionCount"; - private static int sConnectivityActionCount = 0; + private static int sWifiConnectivityActionCount = 0; @Override public void onReceive(Context context, Intent intent) { if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) { - sConnectivityActionCount++; + int networkType = intent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, 0); + if (networkType == ConnectivityManager.TYPE_WIFI) { + sWifiConnectivityActionCount++; + } } - if (GET_CONNECTIVITY_ACTION_COUNT.equals(intent.getAction())) { - setResultCode(sConnectivityActionCount); + if (GET_WIFI_CONNECTIVITY_ACTION_COUNT.equals(intent.getAction())) { + setResultCode(sWifiConnectivityActionCount); } } } diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index df2baac17e..b8478d246b 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -77,9 +77,9 @@ public class ConnectivityManagerTest extends AndroidTestCase { private static final String NETWORK_CALLBACK_ACTION = "ConnectivityManagerTest.NetworkCallbackAction"; - // Intent string to get the number of CONNECTIVITY_ACTION callbacks the test app has seen - public static final String GET_CONNECTIVITY_ACTION_COUNT = - "android.net.cts.appForApi23.getConnectivityActionCount"; + // Intent string to get the number of wifi CONNECTIVITY_ACTION callbacks the test app has seen + public static final String GET_WIFI_CONNECTIVITY_ACTION_COUNT = + "android.net.cts.appForApi23.getWifiConnectivityActionCount"; // device could have only one interface: data, wifi. private static final int MIN_NUM_NETWORK_TYPES = 1; @@ -423,7 +423,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { toggleWifi(); - Intent getConnectivityCount = new Intent(GET_CONNECTIVITY_ACTION_COUNT); + Intent getConnectivityCount = new Intent(GET_WIFI_CONNECTIVITY_ACTION_COUNT); assertEquals(2, sendOrderedBroadcastAndReturnResultCode( getConnectivityCount, SEND_BROADCAST_TIMEOUT)); } From e928006e6785b91d8b1e92125536ca979071bb09 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Mon, 27 Jun 2016 16:13:18 -0700 Subject: [PATCH 0267/1109] Cover more PendingIntent whitelist scenarios. BUG: 29480440 Change-Id: I961b765f40135efc06fbb3e5a4a94e8e333453da --- .../hostside/AbstractDozeModeTestCase.java | 23 ++++-- ...ractRestrictBackgroundNetworkTestCase.java | 18 ++++- .../MyNotificationListenerService.java | 72 +++++++++++++++-- .../android/cts/net/hostside/app2/Common.java | 10 +++ .../hostside/app2/MyBroadcastReceiver.java | 80 ++++++++++++++++--- 5 files changed, 175 insertions(+), 28 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java index b89cf93b99..6669af5edd 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java @@ -132,16 +132,29 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor setDozeMode(true); assertBackgroundNetworkAccess(false); - sendNotification(42); - assertBackgroundNetworkAccess(true); - // Make sure access is disabled after it expires - SystemClock.sleep(NETWORK_TIMEOUT_MS); - assertBackgroundNetworkAccess(false); + testNotification(4, NOTIFICATION_TYPE_CONTENT); + testNotification(8, NOTIFICATION_TYPE_DELETE); + testNotification(15, NOTIFICATION_TYPE_FULL_SCREEN); + testNotification(16, NOTIFICATION_TYPE_BUNDLE); + testNotification(23, NOTIFICATION_TYPE_ACTION); + testNotification(42, NOTIFICATION_TYPE_ACTION_BUNDLE); + testNotification(108, NOTIFICATION_TYPE_ACTION_REMOTE_INPUT); } finally { resetDeviceIdleSettings(); } } + private void testNotification(int id, String type) throws Exception { + sendNotification(id, type); + assertBackgroundNetworkAccess(true); + if (type.equals(NOTIFICATION_TYPE_ACTION)) { + // Make sure access is disabled after it expires. Since this check considerably slows + // downs the CTS tests, do it just once. + SystemClock.sleep(NETWORK_TIMEOUT_MS); + assertBackgroundNetworkAccess(false); + } + } + // Must override so it only tests foreground service - once an app goes to foreground, device // leaves Doze Mode. @Override diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 439fbbe0c9..d04aa0f0db 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -69,6 +69,18 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation "com.android.cts.net.hostside.app2.extra.RECEIVER_NAME"; private static final String EXTRA_NOTIFICATION_ID = "com.android.cts.net.hostside.app2.extra.NOTIFICATION_ID"; + private static final String EXTRA_NOTIFICATION_TYPE = + "com.android.cts.net.hostside.app2.extra.NOTIFICATION_TYPE"; + + protected static final String NOTIFICATION_TYPE_CONTENT = "CONTENT"; + protected static final String NOTIFICATION_TYPE_DELETE = "DELETE"; + protected static final String NOTIFICATION_TYPE_FULL_SCREEN = "FULL_SCREEN"; + protected static final String NOTIFICATION_TYPE_BUNDLE = "BUNDLE"; + protected static final String NOTIFICATION_TYPE_ACTION = "ACTION"; + protected static final String NOTIFICATION_TYPE_ACTION_BUNDLE = "ACTION_BUNDLE"; + protected static final String NOTIFICATION_TYPE_ACTION_REMOTE_INPUT = "ACTION_REMOTE_INPUT"; + + private static final String NETWORK_STATUS_SEPARATOR = "\\|"; private static final int SECOND_IN_MS = 1000; static final int NETWORK_TIMEOUT_MS = 15 * SECOND_IN_MS; @@ -735,10 +747,12 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation + "--receiver-foreground --receiver-registered-only"); } - protected void sendNotification(int notificationId) { + protected void sendNotification(int notificationId, String notificationType) { final Intent intent = new Intent(ACTION_SEND_NOTIFICATION); intent.putExtra(EXTRA_NOTIFICATION_ID, notificationId); - Log.d(TAG, "Sending broadcast: " + intent); + intent.putExtra(EXTRA_NOTIFICATION_TYPE, notificationType); + Log.d(TAG, "Sending notification broadcast (id=" + notificationId + ", type=" + + notificationType + ": " + intent); mContext.sendBroadcast(intent); } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyNotificationListenerService.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyNotificationListenerService.java index b9c303107c..0893511071 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyNotificationListenerService.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyNotificationListenerService.java @@ -16,7 +16,10 @@ package com.android.cts.net.hostside; import android.app.Notification; +import android.app.PendingIntent; import android.app.PendingIntent.CanceledException; +import android.app.RemoteInput; +import android.os.Bundle; import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; import android.util.Log; @@ -40,22 +43,75 @@ public class MyNotificationListenerService extends NotificationListenerService { Log.v(TAG, "ignoring notification from a different package"); return; } + final PendingIntentSender sender = new PendingIntentSender(); final Notification notification = sbn.getNotification(); - if (notification.actions == null) { - Log.w(TAG, "ignoring notification without an action"); + if (notification.contentIntent != null) { + sender.send("content", notification.contentIntent); } - for (Notification.Action action : notification.actions) { - Log.i(TAG, "Sending pending intent " + action.actionIntent); - try { - action.actionIntent.send(); - } catch (CanceledException e) { - Log.w(TAG, "Pending Intent canceled"); + if (notification.deleteIntent != null) { + sender.send("delete", notification.deleteIntent); + } + if (notification.fullScreenIntent != null) { + sender.send("full screen", notification.fullScreenIntent); + } + if (notification.actions != null) { + for (Notification.Action action : notification.actions) { + sender.send("action", action.actionIntent); + sender.send("action extras", action.getExtras()); + final RemoteInput[] remoteInputs = action.getRemoteInputs(); + if (remoteInputs != null && remoteInputs.length > 0) { + for (RemoteInput remoteInput : remoteInputs) { + sender.send("remote input extras", remoteInput.getExtras()); + } + } } } + sender.send("notification extras", notification.extras); } static String getId() { return String.format("%s/%s", MyNotificationListenerService.class.getPackage().getName(), MyNotificationListenerService.class.getName()); } + + private static final class PendingIntentSender { + private PendingIntent mSentIntent = null; + private String mReason = null; + + private void send(String reason, PendingIntent pendingIntent) { + if (pendingIntent == null) { + // Could happen on action that only has extras + Log.v(TAG, "Not sending null pending intent for " + reason); + return; + } + if (mSentIntent != null || mReason != null) { + // Sanity check: make sure test case set up just one pending intent in the + // notification, otherwise it could pass because another pending intent caused the + // whitelisting. + throw new IllegalStateException("Already sent a PendingIntent (" + mSentIntent + + ") for reason '" + mReason + "' when requested another for '" + reason + + "' (" + pendingIntent + ")"); + } + Log.i(TAG, "Sending pending intent for " + reason + ":" + pendingIntent); + try { + pendingIntent.send(); + mSentIntent = pendingIntent; + mReason = reason; + } catch (CanceledException e) { + Log.w(TAG, "Pending intent " + pendingIntent + " canceled"); + } + } + + private void send(String reason, Bundle extras) { + if (extras != null) { + for (String key : extras.keySet()) { + Object value = extras.get(key); + if (value instanceof PendingIntent) { + send(reason + " with key '" + key + "'", (PendingIntent) value); + } + } + } + } + + } } diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java index f02f651f06..8806e3b970 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java @@ -43,6 +43,16 @@ public final class Common { "com.android.cts.net.hostside.app2.extra.RECEIVER_NAME"; static final String EXTRA_NOTIFICATION_ID = "com.android.cts.net.hostside.app2.extra.NOTIFICATION_ID"; + static final String EXTRA_NOTIFICATION_TYPE = + "com.android.cts.net.hostside.app2.extra.NOTIFICATION_TYPE"; + + static final String NOTIFICATION_TYPE_CONTENT = "CONTENT"; + static final String NOTIFICATION_TYPE_DELETE = "DELETE"; + static final String NOTIFICATION_TYPE_FULL_SCREEN = "FULL_SCREEN"; + static final String NOTIFICATION_TYPE_BUNDLE = "BUNDLE"; + static final String NOTIFICATION_TYPE_ACTION = "ACTION"; + static final String NOTIFICATION_TYPE_ACTION_BUNDLE = "ACTION_BUNDLE"; + static final String NOTIFICATION_TYPE_ACTION_REMOTE_INPUT = "ACTION_REMOTE_INPUT"; static int getUid(Context context) { final String packageName = context.getPackageName(); diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java index 60e5de1b9a..3b82f42a67 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java @@ -25,8 +25,16 @@ import static com.android.cts.net.hostside.app2.Common.ACTION_RECEIVER_READY; import static com.android.cts.net.hostside.app2.Common.ACTION_SEND_NOTIFICATION; import static com.android.cts.net.hostside.app2.Common.EXTRA_ACTION; import static com.android.cts.net.hostside.app2.Common.EXTRA_NOTIFICATION_ID; +import static com.android.cts.net.hostside.app2.Common.EXTRA_NOTIFICATION_TYPE; import static com.android.cts.net.hostside.app2.Common.EXTRA_RECEIVER_NAME; import static com.android.cts.net.hostside.app2.Common.MANIFEST_RECEIVER; +import static com.android.cts.net.hostside.app2.Common.NOTIFICATION_TYPE_ACTION; +import static com.android.cts.net.hostside.app2.Common.NOTIFICATION_TYPE_ACTION_BUNDLE; +import static com.android.cts.net.hostside.app2.Common.NOTIFICATION_TYPE_ACTION_REMOTE_INPUT; +import static com.android.cts.net.hostside.app2.Common.NOTIFICATION_TYPE_BUNDLE; +import static com.android.cts.net.hostside.app2.Common.NOTIFICATION_TYPE_CONTENT; +import static com.android.cts.net.hostside.app2.Common.NOTIFICATION_TYPE_DELETE; +import static com.android.cts.net.hostside.app2.Common.NOTIFICATION_TYPE_FULL_SCREEN; import static com.android.cts.net.hostside.app2.Common.TAG; import static com.android.cts.net.hostside.app2.Common.getUid; @@ -34,6 +42,7 @@ import android.app.Notification; import android.app.Notification.Action; import android.app.NotificationManager; import android.app.PendingIntent; +import android.app.RemoteInput; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -230,21 +239,66 @@ public class MyBroadcastReceiver extends BroadcastReceiver { */ private void sendNotification(Context context, Intent intent) { final int notificationId = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1); + final String notificationType = intent.getStringExtra(EXTRA_NOTIFICATION_TYPE); + Log.d(TAG, "sendNotification: id=" + notificationId + ", type=" + notificationType + + ", intent=" + intent); final Intent serviceIntent = new Intent(context, MyService.class); - final PendingIntent pendingIntent = PendingIntent.getService(context, 0, serviceIntent, 0); - final Bundle badBundle = new Bundle(); - badBundle.putCharSequence("parcelable", "I am not"); - final Action action = new Action.Builder( - R.drawable.ic_notification, "ACTION", pendingIntent) - .addExtras(badBundle) - .build(); + final PendingIntent pendingIntent = PendingIntent.getService(context, 0, serviceIntent, + notificationId); + final Bundle bundle = new Bundle(); + bundle.putCharSequence("parcelable", "I am not"); - final Notification notification = new Notification.Builder(context) - .setSmallIcon(R.drawable.ic_notification) - .setContentTitle("Light, Cameras...") - .setContentIntent(pendingIntent) - .addAction(action) - .build(); + final Notification.Builder builder = new Notification.Builder(context) + .setSmallIcon(R.drawable.ic_notification); + + Action action = null; + switch (notificationType) { + case NOTIFICATION_TYPE_CONTENT: + builder + .setContentTitle("Light, Cameras...") + .setContentIntent(pendingIntent); + break; + case NOTIFICATION_TYPE_DELETE: + builder.setDeleteIntent(pendingIntent); + break; + case NOTIFICATION_TYPE_FULL_SCREEN: + builder.setFullScreenIntent(pendingIntent, true); + break; + case NOTIFICATION_TYPE_BUNDLE: + bundle.putParcelable("Magnum P.I. (Pending Intent)", pendingIntent); + builder.setExtras(bundle); + break; + case NOTIFICATION_TYPE_ACTION: + action = new Action.Builder( + R.drawable.ic_notification, "ACTION", pendingIntent) + .build(); + builder.addAction(action); + break; + case NOTIFICATION_TYPE_ACTION_BUNDLE: + bundle.putParcelable("Magnum A.P.I. (Action Pending Intent)", pendingIntent); + action = new Action.Builder( + R.drawable.ic_notification, "ACTION WITH BUNDLE", null) + .addExtras(bundle) + .build(); + builder.addAction(action); + break; + case NOTIFICATION_TYPE_ACTION_REMOTE_INPUT: + bundle.putParcelable("Magnum R.I. (Remote Input)", null); + final RemoteInput remoteInput = new RemoteInput.Builder("RI") + .addExtras(bundle) + .build(); + action = new Action.Builder( + R.drawable.ic_notification, "ACTION WITH REMOTE INPUT", pendingIntent) + .addRemoteInput(remoteInput) + .build(); + builder.addAction(action); + break; + default: + Log.e(TAG, "Unknown notification type: " + notificationType); + return; + } + + final Notification notification = builder.build(); ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE)) .notify(notificationId, notification); } From a87e5240cc29979270520dca070b43f54e82c5a6 Mon Sep 17 00:00:00 2001 From: Neil Fuller Date: Tue, 28 Jun 2016 18:24:20 +0100 Subject: [PATCH 0268/1109] Initialize MockWebServer in setUp() not construction time Should be a no-op but makes test suite creation cheaper. Bug: 29820565 Change-Id: Ieee5568a6f477d591436275be4d4e7e3d5dbd322 --- .../net/src/android/net/http/cts/HttpResponseCacheTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java b/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java index 545541d68b..7987a50eb9 100644 --- a/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java +++ b/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java @@ -38,10 +38,11 @@ import java.util.UUID; public final class HttpResponseCacheTest extends TestCase { private File cacheDir; - private MockWebServer server = new MockWebServer(); + private MockWebServer server; @Override public void setUp() throws Exception { super.setUp(); + server = new MockWebServer(); String tmp = System.getProperty("java.io.tmpdir"); cacheDir = new File(tmp, "HttpCache-" + UUID.randomUUID()); cacheDir.mkdirs(); From 9c1322683f2257b311d2ee8d26a05458f32150c7 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Mon, 1 Aug 2016 16:01:09 -0700 Subject: [PATCH 0269/1109] Improvements on retry mechanism on network tests: - Retry on all cases (not only when expecting connected). - Uses exponential back-off for timeout. BUG: 27803922 Fixes: 30509643 Change-Id: I42454f43158598a72e30f290c27c5a02e80ea6d2 --- ...ractRestrictBackgroundNetworkTestCase.java | 111 ++++++++++-------- .../hostside/app2/MyBroadcastReceiver.java | 2 +- 2 files changed, 64 insertions(+), 49 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index d04aa0f0db..ab643a0e81 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -295,60 +295,75 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation * Asserts whether the active network is available or not. */ private void assertNetworkAccess(boolean expectAvailable) throws Exception { - final Intent intent = new Intent(ACTION_CHECK_NETWORK); - final int maxTries = 5; - String resultData = null; + String error = null; + int timeoutMs = 500; + for (int i = 1; i <= maxTries; i++) { - resultData = sendOrderedBroadcast(intent); - assertNotNull("timeout waiting for ordered broadcast", resultData); + error = checkNetworkAccess(expectAvailable); - // Network status format is described on MyBroadcastReceiver.checkNetworkStatus() - final String[] parts = resultData.split(NETWORK_STATUS_SEPARATOR); - assertEquals("Wrong network status: " + resultData, 5, parts.length); // Sanity check - final State state = State.valueOf(parts[0]); - final DetailedState detailedState = DetailedState.valueOf(parts[1]); - final boolean connected = Boolean.valueOf(parts[2]); - final String connectionCheckDetails = parts[3]; - final String networkInfo = parts[4]; + if (error.isEmpty()) return; - if (expectAvailable) { - if (!connected) { - // Since it's establishing a connection to an external site, it could be flaky. - Log.w(TAG, "Failed to connect to an external site on attempt #" + i + - " (error: " + connectionCheckDetails + ", NetworkInfo: " + networkInfo - + "); sleeping " + NETWORK_TIMEOUT_MS + "ms before trying again"); - SystemClock.sleep(NETWORK_TIMEOUT_MS); - continue; - } - if (state != State.CONNECTED) { - Log.d(TAG, "State (" + state + ") not set to CONNECTED on attempt #" + i - + "; sleeping 1s before trying again"); - SystemClock.sleep(SECOND_IN_MS); - } else { - assertEquals("wrong detailed state for " + networkInfo, - DetailedState.CONNECTED, detailedState); - return; - } - return; - } else { - assertFalse("should not be connected: " + connectionCheckDetails - + " (network info: " + networkInfo + ")", connected); - if (state != State.DISCONNECTED) { - // When the network info state change, it's possible the app still get the - // previous value, so we need to retry a couple times. - Log.d(TAG, "State (" + state + ") not set to DISCONNECTED on attempt #" + i - + "; sleeping 1s before trying again"); - SystemClock.sleep(SECOND_IN_MS); - } else { - assertEquals("wrong detailed state for " + networkInfo, - DetailedState.BLOCKED, detailedState); - return; - } - } + // TODO: ideally, it should retry only when it cannot connect to an external site, + // or no retry at all! But, currently, the initial change fails almost always on + // battery saver tests because the netd changes are made asynchronously. + // Once b/27803922 is fixed, this retry mechanism should be revisited. + + Log.w(TAG, "Network status didn't match for expectAvailable=" + expectAvailable + + " on attempt #" + i + ": " + error + "\n" + + "Sleeping " + timeoutMs + "ms before trying again"); + SystemClock.sleep(timeoutMs); + // Exponential back-off. + timeoutMs = Math.min(timeoutMs*2, NETWORK_TIMEOUT_MS); } fail("Invalid state for expectAvailable=" + expectAvailable + " after " + maxTries - + " attempts. Last data: " + resultData); + + " attempts.\nLast error: " + error); + } + + /** + * Checks whether the network is available as expected. + * + * @return error message with the mismatch (or empty if assertion passed). + */ + private String checkNetworkAccess(boolean expectAvailable) throws Exception { + String resultData = sendOrderedBroadcast(new Intent(ACTION_CHECK_NETWORK)); + if (resultData == null) { + return "timeout waiting for ordered broadcast"; + } + // Network status format is described on MyBroadcastReceiver.checkNetworkStatus() + final String[] parts = resultData.split(NETWORK_STATUS_SEPARATOR); + assertEquals("Wrong network status: " + resultData, 5, parts.length); // Sanity check + final State state = State.valueOf(parts[0]); + final DetailedState detailedState = DetailedState.valueOf(parts[1]); + final boolean connected = Boolean.valueOf(parts[2]); + final String connectionCheckDetails = parts[3]; + final String networkInfo = parts[4]; + + final StringBuilder errors = new StringBuilder(); + final State expectedState; + final DetailedState expectedDetailedState; + if (expectAvailable) { + expectedState = State.CONNECTED; + expectedDetailedState = DetailedState.CONNECTED; + } else { + expectedState = State.DISCONNECTED; + expectedDetailedState = DetailedState.BLOCKED; + } + + if (expectAvailable != connected) { + errors.append(String.format("External site connection failed: expected %s, got %s\n", + expectAvailable, connected)); + } + if (expectedState != state || expectedDetailedState != detailedState) { + errors.append(String.format("Connection state mismatch: expected %s/%s, got %s/%s\n", + expectedState, expectedDetailedState, state, detailedState)); + } + + if (errors.length() > 0) { + errors.append("\tnetworkInfo: " + networkInfo + "\n"); + errors.append("\tconnectionCheckDetails: " + connectionCheckDetails + "\n"); + } + return errors.toString(); } protected String executeShellCommand(String command) throws Exception { diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java index 3b82f42a67..6d01b1554b 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java @@ -66,7 +66,7 @@ import java.util.concurrent.TimeUnit; */ public class MyBroadcastReceiver extends BroadcastReceiver { - private static final int NETWORK_TIMEOUT_MS = 15 * 1000; + private static final int NETWORK_TIMEOUT_MS = 5 * 1000; private final String mName; From e9ef06260e28a0a44a0c38d4cfc4d199a2537077 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Wed, 10 Aug 2016 13:16:15 -0700 Subject: [PATCH 0270/1109] Added tests for network restrictions while the screen is off. BUG: 30785671 Change-Id: I1b211e545ff234272ff6acadfda9ce97765695a9 --- .../hostside/AbstractBatterySaverModeTestCase.java | 12 ++++++++++-- .../AbstractRestrictBackgroundNetworkTestCase.java | 2 +- .../android/cts/net/hostside/DataSaverModeTest.java | 12 ++++++++++-- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java index c1c91dac80..50bcc6058e 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java @@ -85,16 +85,24 @@ abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgrou assertsForegroundAlwaysHasNetworkAccess(); assertBackgroundNetworkAccess(false); - // Make sure foreground app doesn't lose access upon enabling it. + // Make sure foreground app doesn't lose access upon Battery Saver. setBatterySaverMode(false); launchActivity(); assertForegroundNetworkAccess(); setBatterySaverMode(true); assertForegroundNetworkAccess(); + + // Although it should not have access while the screen is off. + turnScreenOff(); + assertBackgroundNetworkAccess(false); + turnScreenOn(); + assertForegroundNetworkAccess(); + + // Goes back to background state. finishActivity(); assertBackgroundNetworkAccess(false); - // Same for foreground service. + // Make sure foreground service doesn't lose access upon enabling Battery Saver. setBatterySaverMode(false); startForegroundService(); assertForegroundNetworkAccess(); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index ab643a0e81..157e9f4365 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -243,7 +243,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation if (isBackground(state.state)) { return; } - Log.d(TAG, "App not on background state on attempt #" + i + Log.d(TAG, "App not on background state (" + state + ") on attempt #" + i + "; sleeping 1s before trying again"); SystemClock.sleep(SECOND_IN_MS); } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index 3e6bd3320a..881b3b4759 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -98,16 +98,24 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertsForegroundAlwaysHasNetworkAccess(); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); - // Make sure foreground app doesn't lose access upon enabling it. + // Make sure foreground app doesn't lose access upon enabling Data Saver. setRestrictBackground(false); launchActivity(); assertForegroundNetworkAccess(); setRestrictBackground(true); assertForegroundNetworkAccess(); + + // Although it should not have access while the screen is off. + turnScreenOff(); + assertBackgroundNetworkAccess(false); + turnScreenOn(); + assertForegroundNetworkAccess(); + + // Goes back to background state. finishActivity(); assertBackgroundNetworkAccess(false); - // Same for foreground service. + // Make sure foreground service doesn't lose access upon enabling Data Saver. setRestrictBackground(false); startForegroundService(); assertForegroundNetworkAccess(); From a871a99ebc7834209d029b67b6ea9b27f9d3e9c8 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Mon, 15 Aug 2016 15:28:14 -0700 Subject: [PATCH 0271/1109] Improve check for activity on top after launch. BUG: 30875754 Fixes: 30868243 Change-Id: I8b7624e35caef107743d61f312e220f8bc21b9b8 --- .../AbstractRestrictBackgroundNetworkTestCase.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 439fbbe0c9..9980327bbe 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -73,6 +73,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation private static final int SECOND_IN_MS = 1000; static final int NETWORK_TIMEOUT_MS = 15 * SECOND_IN_MS; private static final int PROCESS_STATE_FOREGROUND_SERVICE = 4; + private static final int PROCESS_STATE_TOP = 2; // Must be higher than NETWORK_TIMEOUT_MS @@ -723,7 +724,17 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected void launchActivity() throws Exception { turnScreenOn(); executeShellCommand("am start com.android.cts.net.hostside.app2/.MyActivity"); - assertForegroundState(); + final int maxTries = 30; + ProcessState state = null; + for (int i = 1; i <= maxTries; i++) { + state = getProcessStateByUid(mUid); + if (state.state == PROCESS_STATE_TOP) return; + Log.w(TAG, "launchActivity(): uid " + mUid + " not on TOP state on attempt #" + i + + "; turning screen on and sleeping 1s before checking again"); + turnScreenOn(); + SystemClock.sleep(SECOND_IN_MS); + } + fail("App2 is not on foreground state after " + maxTries + " attempts: " + state); } /** From 9d8c5ba97eb55e9ea53f3324f09ad3818fef7526 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Mon, 15 Aug 2016 15:28:14 -0700 Subject: [PATCH 0272/1109] DO NOT MERGE:Improve check for activity on top after launch. BUG: 30875754 Fixes: 30868243 Change-Id: Iad3d6ce80fcf24281e98251799c23abc9b83b52d Change-Id: I8b7624e35caef107743d6 1f312e220f8bc21b9b8 --- .../AbstractRestrictBackgroundNetworkTestCase.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 439fbbe0c9..9980327bbe 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -73,6 +73,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation private static final int SECOND_IN_MS = 1000; static final int NETWORK_TIMEOUT_MS = 15 * SECOND_IN_MS; private static final int PROCESS_STATE_FOREGROUND_SERVICE = 4; + private static final int PROCESS_STATE_TOP = 2; // Must be higher than NETWORK_TIMEOUT_MS @@ -723,7 +724,17 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected void launchActivity() throws Exception { turnScreenOn(); executeShellCommand("am start com.android.cts.net.hostside.app2/.MyActivity"); - assertForegroundState(); + final int maxTries = 30; + ProcessState state = null; + for (int i = 1; i <= maxTries; i++) { + state = getProcessStateByUid(mUid); + if (state.state == PROCESS_STATE_TOP) return; + Log.w(TAG, "launchActivity(): uid " + mUid + " not on TOP state on attempt #" + i + + "; turning screen on and sleeping 1s before checking again"); + turnScreenOn(); + SystemClock.sleep(SECOND_IN_MS); + } + fail("App2 is not on foreground state after " + maxTries + " attempts: " + state); } /** From 2882cd2a7a47d413bde8d891b37fa59d7db05d85 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Wed, 10 Aug 2016 13:16:15 -0700 Subject: [PATCH 0273/1109] Added tests for network restrictions while the screen is off. BUG: 30785671 Change-Id: I1b211e545ff234272ff6acadfda9ce97765695a9 (cherry picked from commit b80a93061aa7d0a19b47a7dbb82f0dc06e3afb7e) --- .../hostside/AbstractBatterySaverModeTestCase.java | 12 ++++++++++-- .../AbstractRestrictBackgroundNetworkTestCase.java | 2 +- .../android/cts/net/hostside/DataSaverModeTest.java | 12 ++++++++++-- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java index c1c91dac80..50bcc6058e 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java @@ -85,16 +85,24 @@ abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgrou assertsForegroundAlwaysHasNetworkAccess(); assertBackgroundNetworkAccess(false); - // Make sure foreground app doesn't lose access upon enabling it. + // Make sure foreground app doesn't lose access upon Battery Saver. setBatterySaverMode(false); launchActivity(); assertForegroundNetworkAccess(); setBatterySaverMode(true); assertForegroundNetworkAccess(); + + // Although it should not have access while the screen is off. + turnScreenOff(); + assertBackgroundNetworkAccess(false); + turnScreenOn(); + assertForegroundNetworkAccess(); + + // Goes back to background state. finishActivity(); assertBackgroundNetworkAccess(false); - // Same for foreground service. + // Make sure foreground service doesn't lose access upon enabling Battery Saver. setBatterySaverMode(false); startForegroundService(); assertForegroundNetworkAccess(); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 8be16214c5..9245a6f3d0 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -244,7 +244,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation if (isBackground(state.state)) { return; } - Log.d(TAG, "App not on background state on attempt #" + i + Log.d(TAG, "App not on background state (" + state + ") on attempt #" + i + "; sleeping 1s before trying again"); SystemClock.sleep(SECOND_IN_MS); } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index 3e6bd3320a..881b3b4759 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -98,16 +98,24 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertsForegroundAlwaysHasNetworkAccess(); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); - // Make sure foreground app doesn't lose access upon enabling it. + // Make sure foreground app doesn't lose access upon enabling Data Saver. setRestrictBackground(false); launchActivity(); assertForegroundNetworkAccess(); setRestrictBackground(true); assertForegroundNetworkAccess(); + + // Although it should not have access while the screen is off. + turnScreenOff(); + assertBackgroundNetworkAccess(false); + turnScreenOn(); + assertForegroundNetworkAccess(); + + // Goes back to background state. finishActivity(); assertBackgroundNetworkAccess(false); - // Same for foreground service. + // Make sure foreground service doesn't lose access upon enabling Data Saver. setRestrictBackground(false); startForegroundService(); assertForegroundNetworkAccess(); From 6784786c0a3c1eef558259cc69624449743afa1a Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Mon, 22 Aug 2016 11:45:21 -0700 Subject: [PATCH 0274/1109] Updated Data Saver blacklist assumptions. On Android N, Data Saver's whitelist and blacklist UIDs were stored separately, hence it would be possible for app to be present in both (although only through adb commands - the UI only allows one state). Now the both lists are stored in the same data structure (UID policies), hence they comply with the Highlander rule: There Can Be Only One. Test: cts-tradefed run commandAndExit cts --skip-device-info --skip-system-status-check com.android.compatibility.common.tradefed.targetprep.NetworkConnectivityChecker --skip-preconditions -m CtsHostsideNetworkTests --abi armeabi-v7a -t com.android.cts.net.HostsideRestrictBackgroundNetworkTests BUG: 28791717 Change-Id: I8649972088b439a2ef87f8630269033f116866bf --- ...bstractRestrictBackgroundNetworkTestCase.java | 6 ++++++ .../cts/net/hostside/DataSaverModeTest.java | 16 +++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 9245a6f3d0..6c0a3c030f 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -541,6 +541,9 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected void addRestrictBackgroundWhitelist(int uid) throws Exception { executeShellCommand("cmd netpolicy add restrict-background-whitelist " + uid); assertRestrictBackgroundWhitelist(uid, true); + // UID policies live by the Highlander rule: "There can be only one". + // Hence, if app is whitelisted, it should not be blacklisted. + assertRestrictBackgroundBlacklist(uid, false); } protected void removeRestrictBackgroundWhitelist(int uid) throws Exception { @@ -555,6 +558,9 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected void addRestrictBackgroundBlacklist(int uid) throws Exception { executeShellCommand("cmd netpolicy add restrict-background-blacklist " + uid); assertRestrictBackgroundBlacklist(uid, true); + // UID policies live by the Highlander rule: "There can be only one". + // Hence, if app is blacklisted, it should not be whitelisted. + assertRestrictBackgroundWhitelist(uid, false); } protected void removeRestrictBackgroundBlacklist(int uid) throws Exception { diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index 881b3b4759..63a66da3a9 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -135,24 +135,30 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertsForegroundAlwaysHasNetworkAccess(); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); - // Make sure blacklist prevails over whitelist. + // UID policies live by the Highlander rule: "There can be only one". + // Hence, if app is whitelisted, it should not be blacklisted anymore. setRestrictBackground(true); assertRestrictBackgroundChangedReceived(2); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); addRestrictBackgroundWhitelist(mUid); assertRestrictBackgroundChangedReceived(3); - assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); + assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_WHITELISTED); // Check status after removing blacklist. + // ...re-enables first + addRestrictBackgroundBlacklist(mUid); + assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); + assertsForegroundAlwaysHasNetworkAccess(); + // ... remove blacklist - access's still rejected because Data Saver is on removeRestrictBackgroundBlacklist(mUid); assertRestrictBackgroundChangedReceived(4); - assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_WHITELISTED); + assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); + assertsForegroundAlwaysHasNetworkAccess(); + // ... finally, disable Data Saver setRestrictBackground(false); assertRestrictBackgroundChangedReceived(5); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED); - assertsForegroundAlwaysHasNetworkAccess(); - assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED); } public void testGetRestrictBackgroundStatus_requiredWhitelistedPackages() throws Exception { From d5f707225cdd4182b31af25d171425e24f29e00f Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Wed, 24 Aug 2016 14:57:57 -0700 Subject: [PATCH 0275/1109] Fixed number wrong number of expected intents. Test: cts-tradefed run commandAndExit cts --skip-device-info --skip-system-status-check com.android.compatibility.common.tradefed.targetprep.NetworkConnectivityChecker --skip-preconditions -m CtsHostsideNetworkTests --abi armeabi-v7a -t com.android.cts.net.HostsideRestrictBackgroundNetworkTests BUG: 28791717 Change-Id: I5f3db14723cc94057715f241579922c5dbf2db8f --- .../src/com/android/cts/net/hostside/DataSaverModeTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index 63a66da3a9..8efea01844 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -151,12 +151,12 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertsForegroundAlwaysHasNetworkAccess(); // ... remove blacklist - access's still rejected because Data Saver is on removeRestrictBackgroundBlacklist(mUid); - assertRestrictBackgroundChangedReceived(4); + assertRestrictBackgroundChangedReceived(3); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); assertsForegroundAlwaysHasNetworkAccess(); // ... finally, disable Data Saver setRestrictBackground(false); - assertRestrictBackgroundChangedReceived(5); + assertRestrictBackgroundChangedReceived(4); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED); assertsForegroundAlwaysHasNetworkAccess(); } From 52376fc1c8ce135fdc6dccf44a6b2770834b0682 Mon Sep 17 00:00:00 2001 From: Neil Fuller Date: Wed, 31 Aug 2016 11:30:13 +0100 Subject: [PATCH 0276/1109] Add CTS tests for LocalSocket read/write timeouts The behavior was not previous covered and broke in N due to commit c80af6d8. There is an associated fix in frameworks/base. Some refactoring of existing tests to reduce duplication and tidy up sockets after tests. Test: Ran the new CTS test (before and after related fix) Bug: 31205169 Change-Id: Ie94335bc535beefcc5301d5469de6b8211af0bab --- .../src/android/net/cts/LocalSocketTest.java | 196 ++++++++++++++---- 1 file changed, 159 insertions(+), 37 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/LocalSocketTest.java b/tests/cts/net/src/android/net/cts/LocalSocketTest.java index 77f0a44705..0ff4a3080b 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketTest.java @@ -22,12 +22,18 @@ import android.net.Credentials; import android.net.LocalServerSocket; import android.net.LocalSocket; import android.net.LocalSocketAddress; +import android.system.Os; +import android.system.OsConstants; import java.io.FileDescriptor; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; public class LocalSocketTest extends TestCase { @@ -177,58 +183,114 @@ public class LocalSocketTest extends TestCase { socket.close(); } + // http://b/31205169 + public void testSetSoTimeout_readTimeout() throws Exception { + String address = ADDRESS_PREFIX + "_testSetSoTimeout_readTimeout"; + + try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) { + final LocalSocket clientSocket = socketPair.clientSocket; + + // Set the timeout in millis. + int timeoutMillis = 1000; + clientSocket.setSoTimeout(timeoutMillis); + + // Avoid blocking the test run if timeout doesn't happen by using a separate thread. + Callable reader = () -> { + try { + clientSocket.getInputStream().read(); + return Result.noException("Did not block"); + } catch (IOException e) { + return Result.exception(e); + } + }; + // Allow the configured timeout, plus some slop. + int allowedTime = timeoutMillis + 2000; + Result result = runInSeparateThread(allowedTime, reader); + + // Check the message was a timeout, it's all we have to go on. + String expectedMessage = Os.strerror(OsConstants.EAGAIN); + result.assertThrewIOException(expectedMessage); + } + } + + // http://b/31205169 + public void testSetSoTimeout_writeTimeout() throws Exception { + String address = ADDRESS_PREFIX + "_testSetSoTimeout_writeTimeout"; + + try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) { + final LocalSocket clientSocket = socketPair.clientSocket; + + // Set the timeout in millis. + int timeoutMillis = 1000; + clientSocket.setSoTimeout(timeoutMillis); + + // Set a small buffer size so we know we can flood it. + clientSocket.setSendBufferSize(100); + final int bufferSize = clientSocket.getSendBufferSize(); + + // Avoid blocking the test run if timeout doesn't happen by using a separate thread. + Callable writer = () -> { + try { + byte[] toWrite = new byte[bufferSize * 2]; + clientSocket.getOutputStream().write(toWrite); + return Result.noException("Did not block"); + } catch (IOException e) { + return Result.exception(e); + } + }; + // Allow the configured timeout, plus some slop. + int allowedTime = timeoutMillis + 2000; + + Result result = runInSeparateThread(allowedTime, writer); + + // Check the message was a timeout, it's all we have to go on. + String expectedMessage = Os.strerror(OsConstants.EAGAIN); + result.assertThrewIOException(expectedMessage); + } + } + public void testAvailable() throws Exception { String address = ADDRESS_PREFIX + "_testAvailable"; - LocalServerSocket localServerSocket = new LocalServerSocket(address); - LocalSocket clientSocket = new LocalSocket(); - // establish connection between client and server - LocalSocketAddress locSockAddr = new LocalSocketAddress(address); - clientSocket.connect(locSockAddr); - assertTrue(clientSocket.isConnected()); - LocalSocket serverSocket = localServerSocket.accept(); + try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) { + LocalSocket clientSocket = socketPair.clientSocket; + LocalSocket serverSocket = socketPair.serverSocket.accept(); - OutputStream clientOutputStream = clientSocket.getOutputStream(); - InputStream serverInputStream = serverSocket.getInputStream(); - assertEquals(0, serverInputStream.available()); + OutputStream clientOutputStream = clientSocket.getOutputStream(); + InputStream serverInputStream = serverSocket.getInputStream(); + assertEquals(0, serverInputStream.available()); - byte[] buffer = new byte[50]; - clientOutputStream.write(buffer); - assertEquals(50, serverInputStream.available()); + byte[] buffer = new byte[50]; + clientOutputStream.write(buffer); + assertEquals(50, serverInputStream.available()); - InputStream clientInputStream = clientSocket.getInputStream(); - OutputStream serverOutputStream = serverSocket.getOutputStream(); - assertEquals(0, clientInputStream.available()); - serverOutputStream.write(buffer); - assertEquals(50, serverInputStream.available()); + InputStream clientInputStream = clientSocket.getInputStream(); + OutputStream serverOutputStream = serverSocket.getOutputStream(); + assertEquals(0, clientInputStream.available()); + serverOutputStream.write(buffer); + assertEquals(50, serverInputStream.available()); - clientSocket.close(); - serverSocket.close(); - localServerSocket.close(); + serverSocket.close(); + } } public void testFlush() throws Exception { String address = ADDRESS_PREFIX + "_testFlush"; - LocalServerSocket localServerSocket = new LocalServerSocket(address); - LocalSocket clientSocket = new LocalSocket(); - // establish connection between client and server - LocalSocketAddress locSockAddr = new LocalSocketAddress(address); - clientSocket.connect(locSockAddr); - assertTrue(clientSocket.isConnected()); - LocalSocket serverSocket = localServerSocket.accept(); + try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) { + LocalSocket clientSocket = socketPair.clientSocket; + LocalSocket serverSocket = socketPair.serverSocket.accept(); - OutputStream clientOutputStream = clientSocket.getOutputStream(); - InputStream serverInputStream = serverSocket.getInputStream(); - testFlushWorks(clientOutputStream, serverInputStream); + OutputStream clientOutputStream = clientSocket.getOutputStream(); + InputStream serverInputStream = serverSocket.getInputStream(); + testFlushWorks(clientOutputStream, serverInputStream); - OutputStream serverOutputStream = serverSocket.getOutputStream(); - InputStream clientInputStream = clientSocket.getInputStream(); - testFlushWorks(serverOutputStream, clientInputStream); + OutputStream serverOutputStream = serverSocket.getOutputStream(); + InputStream clientInputStream = clientSocket.getInputStream(); + testFlushWorks(serverOutputStream, clientInputStream); - clientSocket.close(); - serverSocket.close(); - localServerSocket.close(); + serverSocket.close(); + } } private void testFlushWorks(OutputStream outputStream, InputStream inputStream) @@ -296,4 +358,64 @@ public class LocalSocketTest extends TestCase { assertEquals(expected, bytesRead); } } + + private static class Result { + private final String type; + private final Exception e; + + private Result(String type, Exception e) { + this.type = type; + this.e = e; + } + + static Result noException(String description) { + return new Result(description, null); + } + + static Result exception(Exception e) { + return new Result(e.getClass().getName(), e); + } + + void assertThrewIOException(String expectedMessage) { + assertEquals("Unexpected result type", IOException.class.getName(), type); + assertEquals("Unexpected exception message", expectedMessage, e.getMessage()); + } + } + + private static Result runInSeparateThread(int allowedTime, final Callable callable) + throws Exception { + ExecutorService service = Executors.newSingleThreadScheduledExecutor(); + Future future = service.submit(callable); + Result result = future.get(allowedTime, TimeUnit.MILLISECONDS); + if (!future.isDone()) { + fail("Worker thread appears blocked"); + } + return result; + } + + private static class LocalSocketPair implements AutoCloseable { + static LocalSocketPair createConnectedSocketPair(String address) throws Exception { + LocalServerSocket localServerSocket = new LocalServerSocket(address); + final LocalSocket clientSocket = new LocalSocket(); + + // Establish connection between client and server + LocalSocketAddress locSockAddr = new LocalSocketAddress(address); + clientSocket.connect(locSockAddr); + assertTrue(clientSocket.isConnected()); + return new LocalSocketPair(localServerSocket, clientSocket); + } + + final LocalServerSocket serverSocket; + final LocalSocket clientSocket; + + LocalSocketPair(LocalServerSocket serverSocket, LocalSocket clientSocket) { + this.serverSocket = serverSocket; + this.clientSocket = clientSocket; + } + + public void close() throws Exception { + serverSocket.close(); + clientSocket.close(); + } + } } From a8574413edaaa9bd6bf6eb57cf6fcab68b75529c Mon Sep 17 00:00:00 2001 From: Neil Fuller Date: Wed, 31 Aug 2016 11:30:13 +0100 Subject: [PATCH 0277/1109] Add CTS tests for LocalSocket read/write timeouts The behavior was not previous covered and broke in N due to commit c80af6d8. There is an associated fix in frameworks/base. Some refactoring of existing tests to reduce duplication and tidy up sockets after tests. Test: Ran the new CTS test (before and after related fix) Bug: 31205169 (cherry picked from commit 52376fc1c8ce135fdc6dccf44a6b2770834b0682) Change-Id: I9ee96a91abbdaaba64c2f6daf49c92d1b23352e2 --- .../src/android/net/cts/LocalSocketTest.java | 196 ++++++++++++++---- 1 file changed, 159 insertions(+), 37 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/LocalSocketTest.java b/tests/cts/net/src/android/net/cts/LocalSocketTest.java index 77f0a44705..0ff4a3080b 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketTest.java @@ -22,12 +22,18 @@ import android.net.Credentials; import android.net.LocalServerSocket; import android.net.LocalSocket; import android.net.LocalSocketAddress; +import android.system.Os; +import android.system.OsConstants; import java.io.FileDescriptor; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; public class LocalSocketTest extends TestCase { @@ -177,58 +183,114 @@ public class LocalSocketTest extends TestCase { socket.close(); } + // http://b/31205169 + public void testSetSoTimeout_readTimeout() throws Exception { + String address = ADDRESS_PREFIX + "_testSetSoTimeout_readTimeout"; + + try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) { + final LocalSocket clientSocket = socketPair.clientSocket; + + // Set the timeout in millis. + int timeoutMillis = 1000; + clientSocket.setSoTimeout(timeoutMillis); + + // Avoid blocking the test run if timeout doesn't happen by using a separate thread. + Callable reader = () -> { + try { + clientSocket.getInputStream().read(); + return Result.noException("Did not block"); + } catch (IOException e) { + return Result.exception(e); + } + }; + // Allow the configured timeout, plus some slop. + int allowedTime = timeoutMillis + 2000; + Result result = runInSeparateThread(allowedTime, reader); + + // Check the message was a timeout, it's all we have to go on. + String expectedMessage = Os.strerror(OsConstants.EAGAIN); + result.assertThrewIOException(expectedMessage); + } + } + + // http://b/31205169 + public void testSetSoTimeout_writeTimeout() throws Exception { + String address = ADDRESS_PREFIX + "_testSetSoTimeout_writeTimeout"; + + try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) { + final LocalSocket clientSocket = socketPair.clientSocket; + + // Set the timeout in millis. + int timeoutMillis = 1000; + clientSocket.setSoTimeout(timeoutMillis); + + // Set a small buffer size so we know we can flood it. + clientSocket.setSendBufferSize(100); + final int bufferSize = clientSocket.getSendBufferSize(); + + // Avoid blocking the test run if timeout doesn't happen by using a separate thread. + Callable writer = () -> { + try { + byte[] toWrite = new byte[bufferSize * 2]; + clientSocket.getOutputStream().write(toWrite); + return Result.noException("Did not block"); + } catch (IOException e) { + return Result.exception(e); + } + }; + // Allow the configured timeout, plus some slop. + int allowedTime = timeoutMillis + 2000; + + Result result = runInSeparateThread(allowedTime, writer); + + // Check the message was a timeout, it's all we have to go on. + String expectedMessage = Os.strerror(OsConstants.EAGAIN); + result.assertThrewIOException(expectedMessage); + } + } + public void testAvailable() throws Exception { String address = ADDRESS_PREFIX + "_testAvailable"; - LocalServerSocket localServerSocket = new LocalServerSocket(address); - LocalSocket clientSocket = new LocalSocket(); - // establish connection between client and server - LocalSocketAddress locSockAddr = new LocalSocketAddress(address); - clientSocket.connect(locSockAddr); - assertTrue(clientSocket.isConnected()); - LocalSocket serverSocket = localServerSocket.accept(); + try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) { + LocalSocket clientSocket = socketPair.clientSocket; + LocalSocket serverSocket = socketPair.serverSocket.accept(); - OutputStream clientOutputStream = clientSocket.getOutputStream(); - InputStream serverInputStream = serverSocket.getInputStream(); - assertEquals(0, serverInputStream.available()); + OutputStream clientOutputStream = clientSocket.getOutputStream(); + InputStream serverInputStream = serverSocket.getInputStream(); + assertEquals(0, serverInputStream.available()); - byte[] buffer = new byte[50]; - clientOutputStream.write(buffer); - assertEquals(50, serverInputStream.available()); + byte[] buffer = new byte[50]; + clientOutputStream.write(buffer); + assertEquals(50, serverInputStream.available()); - InputStream clientInputStream = clientSocket.getInputStream(); - OutputStream serverOutputStream = serverSocket.getOutputStream(); - assertEquals(0, clientInputStream.available()); - serverOutputStream.write(buffer); - assertEquals(50, serverInputStream.available()); + InputStream clientInputStream = clientSocket.getInputStream(); + OutputStream serverOutputStream = serverSocket.getOutputStream(); + assertEquals(0, clientInputStream.available()); + serverOutputStream.write(buffer); + assertEquals(50, serverInputStream.available()); - clientSocket.close(); - serverSocket.close(); - localServerSocket.close(); + serverSocket.close(); + } } public void testFlush() throws Exception { String address = ADDRESS_PREFIX + "_testFlush"; - LocalServerSocket localServerSocket = new LocalServerSocket(address); - LocalSocket clientSocket = new LocalSocket(); - // establish connection between client and server - LocalSocketAddress locSockAddr = new LocalSocketAddress(address); - clientSocket.connect(locSockAddr); - assertTrue(clientSocket.isConnected()); - LocalSocket serverSocket = localServerSocket.accept(); + try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) { + LocalSocket clientSocket = socketPair.clientSocket; + LocalSocket serverSocket = socketPair.serverSocket.accept(); - OutputStream clientOutputStream = clientSocket.getOutputStream(); - InputStream serverInputStream = serverSocket.getInputStream(); - testFlushWorks(clientOutputStream, serverInputStream); + OutputStream clientOutputStream = clientSocket.getOutputStream(); + InputStream serverInputStream = serverSocket.getInputStream(); + testFlushWorks(clientOutputStream, serverInputStream); - OutputStream serverOutputStream = serverSocket.getOutputStream(); - InputStream clientInputStream = clientSocket.getInputStream(); - testFlushWorks(serverOutputStream, clientInputStream); + OutputStream serverOutputStream = serverSocket.getOutputStream(); + InputStream clientInputStream = clientSocket.getInputStream(); + testFlushWorks(serverOutputStream, clientInputStream); - clientSocket.close(); - serverSocket.close(); - localServerSocket.close(); + serverSocket.close(); + } } private void testFlushWorks(OutputStream outputStream, InputStream inputStream) @@ -296,4 +358,64 @@ public class LocalSocketTest extends TestCase { assertEquals(expected, bytesRead); } } + + private static class Result { + private final String type; + private final Exception e; + + private Result(String type, Exception e) { + this.type = type; + this.e = e; + } + + static Result noException(String description) { + return new Result(description, null); + } + + static Result exception(Exception e) { + return new Result(e.getClass().getName(), e); + } + + void assertThrewIOException(String expectedMessage) { + assertEquals("Unexpected result type", IOException.class.getName(), type); + assertEquals("Unexpected exception message", expectedMessage, e.getMessage()); + } + } + + private static Result runInSeparateThread(int allowedTime, final Callable callable) + throws Exception { + ExecutorService service = Executors.newSingleThreadScheduledExecutor(); + Future future = service.submit(callable); + Result result = future.get(allowedTime, TimeUnit.MILLISECONDS); + if (!future.isDone()) { + fail("Worker thread appears blocked"); + } + return result; + } + + private static class LocalSocketPair implements AutoCloseable { + static LocalSocketPair createConnectedSocketPair(String address) throws Exception { + LocalServerSocket localServerSocket = new LocalServerSocket(address); + final LocalSocket clientSocket = new LocalSocket(); + + // Establish connection between client and server + LocalSocketAddress locSockAddr = new LocalSocketAddress(address); + clientSocket.connect(locSockAddr); + assertTrue(clientSocket.isConnected()); + return new LocalSocketPair(localServerSocket, clientSocket); + } + + final LocalServerSocket serverSocket; + final LocalSocket clientSocket; + + LocalSocketPair(LocalServerSocket serverSocket, LocalSocket clientSocket) { + this.serverSocket = serverSocket; + this.clientSocket = clientSocket; + } + + public void close() throws Exception { + serverSocket.close(); + clientSocket.close(); + } + } } From 0118f0329c1df2853a55291bb0a936085779d468 Mon Sep 17 00:00:00 2001 From: "sj.cha" Date: Mon, 29 Aug 2016 16:21:54 +0900 Subject: [PATCH 0278/1109] Add some failure comments in VpnTest Symptom : Sockets are not instantly destroyed during VpnTest. Root Cause : If CONFIG_INET_DIAG_DESTROY kernel config is not set in Android N, when network interface going to down, sockets are not instantly destroyed. Solution : Enable CONFIG_INET_DIAG_DESTROY kernel feature. But developer cannot check all of configurations on kernel, so adding some comments in VpnTest. Signed-off-by: SangJin Cha Change-Id: Ib97b93dfbfb62fe61bd3688ea7545708ec3ea2a2 --- .../app/src/com/android/cts/net/hostside/VpnTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java index 12fe625370..a8ad2b868e 100755 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java @@ -84,6 +84,11 @@ import java.util.Random; * https://android-review.googlesource.com/#/c/99225/ * https://android-review.googlesource.com/#/c/100557/ * + * To ensure that the kernel has the required commits, run the kernel unit + * tests described at: + * + * https://source.android.com/devices/tech/config/kernel_network_tests.html + * */ public class VpnTest extends InstrumentationTestCase { From f1bb48635dfbed57d74c342942eff50a207610eb Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Wed, 7 Sep 2016 08:56:45 -0700 Subject: [PATCH 0279/1109] CtsNetTests: Fix WifiInfoTest According to the public documentation of WifiInfo.getSSID(), the returned value can be one of the following: 1. Hex digits if the SSID cannot be decoded as UTF-8. 2. String surrounded by double quotes if the SSID can be decoded as UTF-8. 3. , if not connected. Fix the test to check for all these 3 string values. BUG: 31272462 TEST: The failing CTS test passes now. Change-Id: I26e12d28994e3cdb4cd1bd9e999633b327ad5830 --- tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java index 8719b6b029..696d215649 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java @@ -26,6 +26,7 @@ import android.net.wifi.SupplicantState; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.WifiLock; +import android.net.wifi.WifiSsid; import android.test.AndroidTestCase; import java.util.concurrent.Callable; @@ -123,7 +124,7 @@ public class WifiInfoTest extends AndroidTestCase { SupplicantState.isValidState(wifiInfo.getSupplicantState()); WifiInfo.getDetailedStateOf(SupplicantState.DISCONNECTED); String ssid = wifiInfo.getSSID(); - if (ssid.startsWith("0x") == false) { + if (!ssid.startsWith("0x") && !ssid.equals(WifiSsid.NONE)) { // Non-hex string should be quoted assertTrue(ssid.charAt(0) == '"'); assertTrue(ssid.charAt(ssid.length() - 1) == '"'); From 03ee9869ac7ef7cc5e6f854e09e9a8f8ff7519b3 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 26 May 2016 11:57:41 -0700 Subject: [PATCH 0280/1109] Fix to CtsHostsideNetworkTestsAidl Java library kind. Fixes Error Prone build. Bug: 27723540 (cherry picked from commit ad015ac64d0e510cc040a83b1d545e3a1405b1f7) Change-Id: I150aefde61615023e86e19645a46e432a0183705 --- tests/cts/hostside/aidl/Android.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/hostside/aidl/Android.mk b/tests/cts/hostside/aidl/Android.mk index a7ec6efb31..4aa55b6a08 100644 --- a/tests/cts/hostside/aidl/Android.mk +++ b/tests/cts/hostside/aidl/Android.mk @@ -19,4 +19,4 @@ LOCAL_MODULE_TAGS := tests LOCAL_SDK_VERSION := current LOCAL_SRC_FILES := com/android/cts/net/hostside/IRemoteSocketFactory.aidl LOCAL_MODULE := CtsHostsideNetworkTestsAidl -include $(BUILD_JAVA_LIBRARY) +include $(BUILD_STATIC_JAVA_LIBRARY) From 0e42d0c0adf3e7e9bf72474e0a869e4bb586635e Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Thu, 8 Sep 2016 09:50:50 -0700 Subject: [PATCH 0281/1109] Restore right number of expected intents. They were changed during a refactoring, which is now finished. Test: cts-tradefed run commandAndExit cts -m CtsHostsideNetworkTests -t com.android.cts.net.HostsideRestrictBackgroundNetworkTests#testDataSaverMode_enabled Fixes: 28791717 Change-Id: Ia5e99c0c3d421b7d3b58e11ddde4da222d5f8c15 --- .../src/com/android/cts/net/hostside/DataSaverModeTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index 8efea01844..7ca302f52a 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -133,6 +133,7 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); assertsForegroundAlwaysHasNetworkAccess(); + assertRestrictBackgroundChangedReceived(1); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); // UID policies live by the Highlander rule: "There can be only one". @@ -147,16 +148,17 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase // Check status after removing blacklist. // ...re-enables first addRestrictBackgroundBlacklist(mUid); + assertRestrictBackgroundChangedReceived(4); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); assertsForegroundAlwaysHasNetworkAccess(); // ... remove blacklist - access's still rejected because Data Saver is on removeRestrictBackgroundBlacklist(mUid); - assertRestrictBackgroundChangedReceived(3); + assertRestrictBackgroundChangedReceived(4); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); assertsForegroundAlwaysHasNetworkAccess(); // ... finally, disable Data Saver setRestrictBackground(false); - assertRestrictBackgroundChangedReceived(4); + assertRestrictBackgroundChangedReceived(5); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED); assertsForegroundAlwaysHasNetworkAccess(); } From 36c0f02d94b46950fbfb5ab7525e5d02183cf77d Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Tue, 13 Sep 2016 13:52:20 +0800 Subject: [PATCH 0282/1109] PacketReflector: Ignore IPv6 flow labels in ICMPv6 test Since Linux kernel 4.2, net.ipv6.auto_flowlabels is set by default, and therefore the request and reply may have different IPv6 flow label. Bug: 31444338 Test: On a kernel 4.4 board, run com.android.cts.net.HostsideNetworkTests#testVpn Test: On a kernel 3.18 board, run echo 1 > /proc/sys/net/ipv6/auto_flowlabels, then com.android.cts.net.HostsideNetworkTests#testVpn Change-Id: I913bbf91574239a24cb32ae908834eb951ea2010 --- .../com/android/cts/net/hostside/PacketReflector.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/PacketReflector.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/PacketReflector.java index dd0f792b21..a4a2956d3a 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/PacketReflector.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/PacketReflector.java @@ -151,6 +151,15 @@ public class PacketReflector extends Thread { request[hdrLen] = buf[hdrLen]; // Type. request[hdrLen + 2] = buf[hdrLen + 2]; // Checksum byte 1. request[hdrLen + 3] = buf[hdrLen + 3]; // Checksum byte 2. + + // Since Linux kernel 4.2, net.ipv6.auto_flowlabels is set by default, and therefore + // the request and reply may have different IPv6 flow label: ignore that as well. + if (version == 6) { + request[1] = (byte)(request[1] & 0xf0 | buf[1] & 0x0f); + request[2] = buf[2]; + request[3] = buf[3]; + } + for (int i = 0; i < len; i++) { if (buf[i] != request[i]) { Log.i(TAG, "Received non-matching packet when expecting ping response."); From 07f9388e4fe84f13fd3f345e4db9dc9b49d982ed Mon Sep 17 00:00:00 2001 From: Stephen Li Date: Wed, 14 Sep 2016 22:25:06 +0000 Subject: [PATCH 0283/1109] Revert "Manually merge commit '9be9d5865ba2584a251642359710c074061dee5e' into nyc-dev" This reverts commit 253fdc667a18ec0cfdc511c7d21e3b308ecb9cfb. Change-Id: If8862e289eb6693650713ff819c8b05f65cdeda5 --- tests/cts/net/jni/NativeDnsJni.c | 2 +- tests/cts/net/jni/NativeMultinetworkJni.c | 2 +- .../src/android/net/cts/LocalSocketTest.java | 196 ++++-------------- .../net/http/cts/HttpResponseCacheTest.java | 3 +- 4 files changed, 40 insertions(+), 163 deletions(-) diff --git a/tests/cts/net/jni/NativeDnsJni.c b/tests/cts/net/jni/NativeDnsJni.c index 352c0c52cc..4eb3c7aebc 100644 --- a/tests/cts/net/jni/NativeDnsJni.c +++ b/tests/cts/net/jni/NativeDnsJni.c @@ -126,7 +126,7 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas return JNI_FALSE; } - memset(buf, 0, sizeof(buf)); + memset(buf, sizeof(buf), 0); res = getnameinfo((const struct sockaddr*)&sa6, sizeof(sa6), buf, sizeof(buf), NULL, 0, flags); if (res != 0) { ALOGD("getnameinfo(%s (GoogleDNS) ) gave error %d (%s)", GoogleDNSIpV6Address2, diff --git a/tests/cts/net/jni/NativeMultinetworkJni.c b/tests/cts/net/jni/NativeMultinetworkJni.c index 6990efa452..ad56b510c3 100644 --- a/tests/cts/net/jni/NativeMultinetworkJni.c +++ b/tests/cts/net/jni/NativeMultinetworkJni.c @@ -30,7 +30,7 @@ #include #include -#define UNUSED(X) ((void) (X)) +#define UNUSED(X) ((void) X) static const char kHostname[] = "connectivitycheck.android.com"; diff --git a/tests/cts/net/src/android/net/cts/LocalSocketTest.java b/tests/cts/net/src/android/net/cts/LocalSocketTest.java index 0ff4a3080b..77f0a44705 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketTest.java @@ -22,18 +22,12 @@ import android.net.Credentials; import android.net.LocalServerSocket; import android.net.LocalSocket; import android.net.LocalSocketAddress; -import android.system.Os; -import android.system.OsConstants; import java.io.FileDescriptor; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; public class LocalSocketTest extends TestCase { @@ -183,114 +177,58 @@ public class LocalSocketTest extends TestCase { socket.close(); } - // http://b/31205169 - public void testSetSoTimeout_readTimeout() throws Exception { - String address = ADDRESS_PREFIX + "_testSetSoTimeout_readTimeout"; - - try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) { - final LocalSocket clientSocket = socketPair.clientSocket; - - // Set the timeout in millis. - int timeoutMillis = 1000; - clientSocket.setSoTimeout(timeoutMillis); - - // Avoid blocking the test run if timeout doesn't happen by using a separate thread. - Callable reader = () -> { - try { - clientSocket.getInputStream().read(); - return Result.noException("Did not block"); - } catch (IOException e) { - return Result.exception(e); - } - }; - // Allow the configured timeout, plus some slop. - int allowedTime = timeoutMillis + 2000; - Result result = runInSeparateThread(allowedTime, reader); - - // Check the message was a timeout, it's all we have to go on. - String expectedMessage = Os.strerror(OsConstants.EAGAIN); - result.assertThrewIOException(expectedMessage); - } - } - - // http://b/31205169 - public void testSetSoTimeout_writeTimeout() throws Exception { - String address = ADDRESS_PREFIX + "_testSetSoTimeout_writeTimeout"; - - try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) { - final LocalSocket clientSocket = socketPair.clientSocket; - - // Set the timeout in millis. - int timeoutMillis = 1000; - clientSocket.setSoTimeout(timeoutMillis); - - // Set a small buffer size so we know we can flood it. - clientSocket.setSendBufferSize(100); - final int bufferSize = clientSocket.getSendBufferSize(); - - // Avoid blocking the test run if timeout doesn't happen by using a separate thread. - Callable writer = () -> { - try { - byte[] toWrite = new byte[bufferSize * 2]; - clientSocket.getOutputStream().write(toWrite); - return Result.noException("Did not block"); - } catch (IOException e) { - return Result.exception(e); - } - }; - // Allow the configured timeout, plus some slop. - int allowedTime = timeoutMillis + 2000; - - Result result = runInSeparateThread(allowedTime, writer); - - // Check the message was a timeout, it's all we have to go on. - String expectedMessage = Os.strerror(OsConstants.EAGAIN); - result.assertThrewIOException(expectedMessage); - } - } - public void testAvailable() throws Exception { String address = ADDRESS_PREFIX + "_testAvailable"; + LocalServerSocket localServerSocket = new LocalServerSocket(address); + LocalSocket clientSocket = new LocalSocket(); - try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) { - LocalSocket clientSocket = socketPair.clientSocket; - LocalSocket serverSocket = socketPair.serverSocket.accept(); + // establish connection between client and server + LocalSocketAddress locSockAddr = new LocalSocketAddress(address); + clientSocket.connect(locSockAddr); + assertTrue(clientSocket.isConnected()); + LocalSocket serverSocket = localServerSocket.accept(); - OutputStream clientOutputStream = clientSocket.getOutputStream(); - InputStream serverInputStream = serverSocket.getInputStream(); - assertEquals(0, serverInputStream.available()); + OutputStream clientOutputStream = clientSocket.getOutputStream(); + InputStream serverInputStream = serverSocket.getInputStream(); + assertEquals(0, serverInputStream.available()); - byte[] buffer = new byte[50]; - clientOutputStream.write(buffer); - assertEquals(50, serverInputStream.available()); + byte[] buffer = new byte[50]; + clientOutputStream.write(buffer); + assertEquals(50, serverInputStream.available()); - InputStream clientInputStream = clientSocket.getInputStream(); - OutputStream serverOutputStream = serverSocket.getOutputStream(); - assertEquals(0, clientInputStream.available()); - serverOutputStream.write(buffer); - assertEquals(50, serverInputStream.available()); + InputStream clientInputStream = clientSocket.getInputStream(); + OutputStream serverOutputStream = serverSocket.getOutputStream(); + assertEquals(0, clientInputStream.available()); + serverOutputStream.write(buffer); + assertEquals(50, serverInputStream.available()); - serverSocket.close(); - } + clientSocket.close(); + serverSocket.close(); + localServerSocket.close(); } public void testFlush() throws Exception { String address = ADDRESS_PREFIX + "_testFlush"; + LocalServerSocket localServerSocket = new LocalServerSocket(address); + LocalSocket clientSocket = new LocalSocket(); - try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) { - LocalSocket clientSocket = socketPair.clientSocket; - LocalSocket serverSocket = socketPair.serverSocket.accept(); + // establish connection between client and server + LocalSocketAddress locSockAddr = new LocalSocketAddress(address); + clientSocket.connect(locSockAddr); + assertTrue(clientSocket.isConnected()); + LocalSocket serverSocket = localServerSocket.accept(); - OutputStream clientOutputStream = clientSocket.getOutputStream(); - InputStream serverInputStream = serverSocket.getInputStream(); - testFlushWorks(clientOutputStream, serverInputStream); + OutputStream clientOutputStream = clientSocket.getOutputStream(); + InputStream serverInputStream = serverSocket.getInputStream(); + testFlushWorks(clientOutputStream, serverInputStream); - OutputStream serverOutputStream = serverSocket.getOutputStream(); - InputStream clientInputStream = clientSocket.getInputStream(); - testFlushWorks(serverOutputStream, clientInputStream); + OutputStream serverOutputStream = serverSocket.getOutputStream(); + InputStream clientInputStream = clientSocket.getInputStream(); + testFlushWorks(serverOutputStream, clientInputStream); - serverSocket.close(); - } + clientSocket.close(); + serverSocket.close(); + localServerSocket.close(); } private void testFlushWorks(OutputStream outputStream, InputStream inputStream) @@ -358,64 +296,4 @@ public class LocalSocketTest extends TestCase { assertEquals(expected, bytesRead); } } - - private static class Result { - private final String type; - private final Exception e; - - private Result(String type, Exception e) { - this.type = type; - this.e = e; - } - - static Result noException(String description) { - return new Result(description, null); - } - - static Result exception(Exception e) { - return new Result(e.getClass().getName(), e); - } - - void assertThrewIOException(String expectedMessage) { - assertEquals("Unexpected result type", IOException.class.getName(), type); - assertEquals("Unexpected exception message", expectedMessage, e.getMessage()); - } - } - - private static Result runInSeparateThread(int allowedTime, final Callable callable) - throws Exception { - ExecutorService service = Executors.newSingleThreadScheduledExecutor(); - Future future = service.submit(callable); - Result result = future.get(allowedTime, TimeUnit.MILLISECONDS); - if (!future.isDone()) { - fail("Worker thread appears blocked"); - } - return result; - } - - private static class LocalSocketPair implements AutoCloseable { - static LocalSocketPair createConnectedSocketPair(String address) throws Exception { - LocalServerSocket localServerSocket = new LocalServerSocket(address); - final LocalSocket clientSocket = new LocalSocket(); - - // Establish connection between client and server - LocalSocketAddress locSockAddr = new LocalSocketAddress(address); - clientSocket.connect(locSockAddr); - assertTrue(clientSocket.isConnected()); - return new LocalSocketPair(localServerSocket, clientSocket); - } - - final LocalServerSocket serverSocket; - final LocalSocket clientSocket; - - LocalSocketPair(LocalServerSocket serverSocket, LocalSocket clientSocket) { - this.serverSocket = serverSocket; - this.clientSocket = clientSocket; - } - - public void close() throws Exception { - serverSocket.close(); - clientSocket.close(); - } - } } diff --git a/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java b/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java index 7987a50eb9..545541d68b 100644 --- a/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java +++ b/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java @@ -38,11 +38,10 @@ import java.util.UUID; public final class HttpResponseCacheTest extends TestCase { private File cacheDir; - private MockWebServer server; + private MockWebServer server = new MockWebServer(); @Override public void setUp() throws Exception { super.setUp(); - server = new MockWebServer(); String tmp = System.getProperty("java.io.tmpdir"); cacheDir = new File(tmp, "HttpCache-" + UUID.randomUUID()); cacheDir.mkdirs(); From 2855028c8ec28b263e495c22d12f3781ae586a99 Mon Sep 17 00:00:00 2001 From: Amith Yamasani Date: Mon, 19 Sep 2016 09:27:06 -0700 Subject: [PATCH 0284/1109] Tests for idle parole when charging Make sure that when switching between idle, paroled and battery saver, the network availability of the app is correctly updated. Bug: 31399882 Test: cts-tradefed run commandAndExit cts -m CtsHostsideNetworkTests -t com.android.cts.net.HostsideRestrictBackgroundNetworkTests#testAppIdleNonMetered_whenCharging Test: cts-tradefed run commandAndExit cts -m CtsHostsideNetworkTests -t com.android.cts.net.HostsideRestrictBackgroundNetworkTests#testAppIdleMetered_whenCharging Change-Id: I060a0d5f9c3297430b5b623b389c1afdf6abde87 --- .../net/hostside/AbstractAppIdleTestCase.java | 24 +++++++++++++++++++ ...ostsideRestrictBackgroundNetworkTests.java | 10 ++++++++ 2 files changed, 34 insertions(+) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java index ba56665fbc..e7e551cdbb 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java @@ -138,4 +138,28 @@ abstract class AbstractAppIdleTestCase extends AbstractRestrictBackgroundNetwork assertsForegroundAlwaysHasNetworkAccess(); assertBackgroundNetworkAccess(true); } + + public void testAppIdleNetworkAccess_whenCharging() throws Exception { + if (!isSupported()) return; + + // Check that app is paroled when charging + setAppIdle(true); + assertBackgroundNetworkAccess(false); + turnBatteryOn(); + assertBackgroundNetworkAccess(true); + turnBatteryOff(); + assertBackgroundNetworkAccess(false); + + // Check that app is restricted when not idle but power-save is on + setAppIdle(false); + assertBackgroundNetworkAccess(true); + setBatterySaverMode(true); + assertBackgroundNetworkAccess(false); + turnBatteryOn(); + assertBackgroundNetworkAccess(true); + + // And when no longer charging, it still has network access, since it's not idle + turnBatteryOff(); + assertBackgroundNetworkAccess(true); + } } diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java index 7d5f817798..dbf8acabea 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java @@ -171,6 +171,16 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC "testBackgroundNetworkAccess_enabled"); } + public void testAppIdleNonMetered_whenCharging() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleNonMeteredTest", + "testAppIdleNetworkAccess_whenCharging"); + } + + public void testAppIdleMetered_whenCharging() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleMeteredTest", + "testAppIdleNetworkAccess_whenCharging"); + } + /******************** * Doze Mode tests. * ********************/ From 4a0758045c63c50a34f90d3eccd69133b03697da Mon Sep 17 00:00:00 2001 From: Dan Willemsen Date: Mon, 19 Sep 2016 21:27:59 -0700 Subject: [PATCH 0285/1109] DO NOT MERGE ANYWHERE Actually fix cts in nyc-dev-plus-aosp I did this manually first, but came up with a much better way that produced a slightly better result (verified the diffs against the next branch). Sequence of commands: # Checkout the last good commit (right before the first bad merge) git checkout aa76e8b6fc8515bfc65d4b75456b74c26ee32f1e^ # Reset the HEAD pointer to the last bad merge, but not the worktree git reset 3c197891b50d9ac5e5016f55551b6dff82f62f33 # Update the index git add -A # Apply all the changes that mattered between the above to commits git cherry-pick -n 29cb19b774b6e0cb73851feb6877da5e42bba78e git cherry-pick -n 0e9d107fcfbd3421b7988a4252a9965896019aba git cherry-pick -n f19496887beb974c3bc9df9a57f6214a696417b1 git cherry-pick -n 939e2b253b798386ce53954626fd8044ecb18db6 git cherry-pick -n 02f07b5d5994b8345ebc86546e5f66524ac04dac # Commit the changes git commit # Rebase the diffs on top of the latest nyc-dev-plus-aosp, since some # changes have been manually applied, there will be a few merge # conflicts git rebase goog/nyc-dev-plus-aosp All the SHA-1s above were discovered using a combination of this command to find the changes actually submitted into nyc-dev-plus-aosp itself: git log --oneline --first-parent goog/nyc-dev-plus-aosp and then to find the original commits (that weren't marked as DO NOT MERGE ANYWHERE): git log --oneline --no-merges --stat aa76e8b..goog/nyc-dev-plus-aosp Change-Id: Iec12619678cb8d011d2c6df26a34ce26e042b854 --- tests/cts/net/jni/NativeDnsJni.c | 2 +- tests/cts/net/jni/NativeMultinetworkJni.c | 2 +- .../src/android/net/cts/LocalSocketTest.java | 196 ++++++++++++++---- .../net/http/cts/HttpResponseCacheTest.java | 3 +- 4 files changed, 163 insertions(+), 40 deletions(-) diff --git a/tests/cts/net/jni/NativeDnsJni.c b/tests/cts/net/jni/NativeDnsJni.c index 4eb3c7aebc..352c0c52cc 100644 --- a/tests/cts/net/jni/NativeDnsJni.c +++ b/tests/cts/net/jni/NativeDnsJni.c @@ -126,7 +126,7 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas return JNI_FALSE; } - memset(buf, sizeof(buf), 0); + memset(buf, 0, sizeof(buf)); res = getnameinfo((const struct sockaddr*)&sa6, sizeof(sa6), buf, sizeof(buf), NULL, 0, flags); if (res != 0) { ALOGD("getnameinfo(%s (GoogleDNS) ) gave error %d (%s)", GoogleDNSIpV6Address2, diff --git a/tests/cts/net/jni/NativeMultinetworkJni.c b/tests/cts/net/jni/NativeMultinetworkJni.c index ad56b510c3..6990efa452 100644 --- a/tests/cts/net/jni/NativeMultinetworkJni.c +++ b/tests/cts/net/jni/NativeMultinetworkJni.c @@ -30,7 +30,7 @@ #include #include -#define UNUSED(X) ((void) X) +#define UNUSED(X) ((void) (X)) static const char kHostname[] = "connectivitycheck.android.com"; diff --git a/tests/cts/net/src/android/net/cts/LocalSocketTest.java b/tests/cts/net/src/android/net/cts/LocalSocketTest.java index 77f0a44705..0ff4a3080b 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketTest.java @@ -22,12 +22,18 @@ import android.net.Credentials; import android.net.LocalServerSocket; import android.net.LocalSocket; import android.net.LocalSocketAddress; +import android.system.Os; +import android.system.OsConstants; import java.io.FileDescriptor; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; public class LocalSocketTest extends TestCase { @@ -177,58 +183,114 @@ public class LocalSocketTest extends TestCase { socket.close(); } + // http://b/31205169 + public void testSetSoTimeout_readTimeout() throws Exception { + String address = ADDRESS_PREFIX + "_testSetSoTimeout_readTimeout"; + + try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) { + final LocalSocket clientSocket = socketPair.clientSocket; + + // Set the timeout in millis. + int timeoutMillis = 1000; + clientSocket.setSoTimeout(timeoutMillis); + + // Avoid blocking the test run if timeout doesn't happen by using a separate thread. + Callable reader = () -> { + try { + clientSocket.getInputStream().read(); + return Result.noException("Did not block"); + } catch (IOException e) { + return Result.exception(e); + } + }; + // Allow the configured timeout, plus some slop. + int allowedTime = timeoutMillis + 2000; + Result result = runInSeparateThread(allowedTime, reader); + + // Check the message was a timeout, it's all we have to go on. + String expectedMessage = Os.strerror(OsConstants.EAGAIN); + result.assertThrewIOException(expectedMessage); + } + } + + // http://b/31205169 + public void testSetSoTimeout_writeTimeout() throws Exception { + String address = ADDRESS_PREFIX + "_testSetSoTimeout_writeTimeout"; + + try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) { + final LocalSocket clientSocket = socketPair.clientSocket; + + // Set the timeout in millis. + int timeoutMillis = 1000; + clientSocket.setSoTimeout(timeoutMillis); + + // Set a small buffer size so we know we can flood it. + clientSocket.setSendBufferSize(100); + final int bufferSize = clientSocket.getSendBufferSize(); + + // Avoid blocking the test run if timeout doesn't happen by using a separate thread. + Callable writer = () -> { + try { + byte[] toWrite = new byte[bufferSize * 2]; + clientSocket.getOutputStream().write(toWrite); + return Result.noException("Did not block"); + } catch (IOException e) { + return Result.exception(e); + } + }; + // Allow the configured timeout, plus some slop. + int allowedTime = timeoutMillis + 2000; + + Result result = runInSeparateThread(allowedTime, writer); + + // Check the message was a timeout, it's all we have to go on. + String expectedMessage = Os.strerror(OsConstants.EAGAIN); + result.assertThrewIOException(expectedMessage); + } + } + public void testAvailable() throws Exception { String address = ADDRESS_PREFIX + "_testAvailable"; - LocalServerSocket localServerSocket = new LocalServerSocket(address); - LocalSocket clientSocket = new LocalSocket(); - // establish connection between client and server - LocalSocketAddress locSockAddr = new LocalSocketAddress(address); - clientSocket.connect(locSockAddr); - assertTrue(clientSocket.isConnected()); - LocalSocket serverSocket = localServerSocket.accept(); + try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) { + LocalSocket clientSocket = socketPair.clientSocket; + LocalSocket serverSocket = socketPair.serverSocket.accept(); - OutputStream clientOutputStream = clientSocket.getOutputStream(); - InputStream serverInputStream = serverSocket.getInputStream(); - assertEquals(0, serverInputStream.available()); + OutputStream clientOutputStream = clientSocket.getOutputStream(); + InputStream serverInputStream = serverSocket.getInputStream(); + assertEquals(0, serverInputStream.available()); - byte[] buffer = new byte[50]; - clientOutputStream.write(buffer); - assertEquals(50, serverInputStream.available()); + byte[] buffer = new byte[50]; + clientOutputStream.write(buffer); + assertEquals(50, serverInputStream.available()); - InputStream clientInputStream = clientSocket.getInputStream(); - OutputStream serverOutputStream = serverSocket.getOutputStream(); - assertEquals(0, clientInputStream.available()); - serverOutputStream.write(buffer); - assertEquals(50, serverInputStream.available()); + InputStream clientInputStream = clientSocket.getInputStream(); + OutputStream serverOutputStream = serverSocket.getOutputStream(); + assertEquals(0, clientInputStream.available()); + serverOutputStream.write(buffer); + assertEquals(50, serverInputStream.available()); - clientSocket.close(); - serverSocket.close(); - localServerSocket.close(); + serverSocket.close(); + } } public void testFlush() throws Exception { String address = ADDRESS_PREFIX + "_testFlush"; - LocalServerSocket localServerSocket = new LocalServerSocket(address); - LocalSocket clientSocket = new LocalSocket(); - // establish connection between client and server - LocalSocketAddress locSockAddr = new LocalSocketAddress(address); - clientSocket.connect(locSockAddr); - assertTrue(clientSocket.isConnected()); - LocalSocket serverSocket = localServerSocket.accept(); + try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) { + LocalSocket clientSocket = socketPair.clientSocket; + LocalSocket serverSocket = socketPair.serverSocket.accept(); - OutputStream clientOutputStream = clientSocket.getOutputStream(); - InputStream serverInputStream = serverSocket.getInputStream(); - testFlushWorks(clientOutputStream, serverInputStream); + OutputStream clientOutputStream = clientSocket.getOutputStream(); + InputStream serverInputStream = serverSocket.getInputStream(); + testFlushWorks(clientOutputStream, serverInputStream); - OutputStream serverOutputStream = serverSocket.getOutputStream(); - InputStream clientInputStream = clientSocket.getInputStream(); - testFlushWorks(serverOutputStream, clientInputStream); + OutputStream serverOutputStream = serverSocket.getOutputStream(); + InputStream clientInputStream = clientSocket.getInputStream(); + testFlushWorks(serverOutputStream, clientInputStream); - clientSocket.close(); - serverSocket.close(); - localServerSocket.close(); + serverSocket.close(); + } } private void testFlushWorks(OutputStream outputStream, InputStream inputStream) @@ -296,4 +358,64 @@ public class LocalSocketTest extends TestCase { assertEquals(expected, bytesRead); } } + + private static class Result { + private final String type; + private final Exception e; + + private Result(String type, Exception e) { + this.type = type; + this.e = e; + } + + static Result noException(String description) { + return new Result(description, null); + } + + static Result exception(Exception e) { + return new Result(e.getClass().getName(), e); + } + + void assertThrewIOException(String expectedMessage) { + assertEquals("Unexpected result type", IOException.class.getName(), type); + assertEquals("Unexpected exception message", expectedMessage, e.getMessage()); + } + } + + private static Result runInSeparateThread(int allowedTime, final Callable callable) + throws Exception { + ExecutorService service = Executors.newSingleThreadScheduledExecutor(); + Future future = service.submit(callable); + Result result = future.get(allowedTime, TimeUnit.MILLISECONDS); + if (!future.isDone()) { + fail("Worker thread appears blocked"); + } + return result; + } + + private static class LocalSocketPair implements AutoCloseable { + static LocalSocketPair createConnectedSocketPair(String address) throws Exception { + LocalServerSocket localServerSocket = new LocalServerSocket(address); + final LocalSocket clientSocket = new LocalSocket(); + + // Establish connection between client and server + LocalSocketAddress locSockAddr = new LocalSocketAddress(address); + clientSocket.connect(locSockAddr); + assertTrue(clientSocket.isConnected()); + return new LocalSocketPair(localServerSocket, clientSocket); + } + + final LocalServerSocket serverSocket; + final LocalSocket clientSocket; + + LocalSocketPair(LocalServerSocket serverSocket, LocalSocket clientSocket) { + this.serverSocket = serverSocket; + this.clientSocket = clientSocket; + } + + public void close() throws Exception { + serverSocket.close(); + clientSocket.close(); + } + } } diff --git a/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java b/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java index 545541d68b..7987a50eb9 100644 --- a/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java +++ b/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java @@ -38,10 +38,11 @@ import java.util.UUID; public final class HttpResponseCacheTest extends TestCase { private File cacheDir; - private MockWebServer server = new MockWebServer(); + private MockWebServer server; @Override public void setUp() throws Exception { super.setUp(); + server = new MockWebServer(); String tmp = System.getProperty("java.io.tmpdir"); cacheDir = new File(tmp, "HttpCache-" + UUID.randomUUID()); cacheDir.mkdirs(); From 87c10012b4c7ba76c6d5ae87edba359ee873a096 Mon Sep 17 00:00:00 2001 From: Amith Yamasani Date: Wed, 21 Sep 2016 11:45:30 -0700 Subject: [PATCH 0286/1109] Test to ensure a toast doesn't affect app standby Put an app in standby, make it show a toast and ensure that it doesn't come out of standby. This is to test for a bug fix for the same behavior. Bug: 31544592 Test: cts-tradefed run commandAndExit cts -m CtsHostsideNetworkTests -t com.android.cts.net.HostsideRestrictBackgroundNetworkTests#testAppIdle_toast Change-Id: I796ecde8e346c308a27969d873e3ce384414fee3 --- .../cts/net/hostside/AbstractAppIdleTestCase.java | 13 +++++++++++++ .../AbstractRestrictBackgroundNetworkTestCase.java | 13 +++++++++++++ tests/cts/hostside/app2/AndroidManifest.xml | 1 + .../com/android/cts/net/hostside/app2/Common.java | 2 ++ .../cts/net/hostside/app2/MyBroadcastReceiver.java | 10 ++++++++++ .../net/HostsideRestrictBackgroundNetworkTests.java | 6 ++++++ 6 files changed, 45 insertions(+) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java index e7e551cdbb..78ba4b9514 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java @@ -16,6 +16,7 @@ package com.android.cts.net.hostside; +import android.os.SystemClock; import android.util.Log; /** @@ -162,4 +163,16 @@ abstract class AbstractAppIdleTestCase extends AbstractRestrictBackgroundNetwork turnBatteryOff(); assertBackgroundNetworkAccess(true); } + + public void testAppIdle_toast() throws Exception { + if (!isSupported()) return; + + setAppIdle(true); + assertAppIdle(true); + assertEquals("Shown", showToast()); + assertAppIdle(true); + // Wait for a couple of seconds for the toast to actually be shown + SystemClock.sleep(2000); + assertAppIdle(true); + } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 9245a6f3d0..9c9ec0b021 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -64,6 +64,8 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation "com.android.cts.net.hostside.app2.action.RECEIVER_READY"; static final String ACTION_SEND_NOTIFICATION = "com.android.cts.net.hostside.app2.action.SEND_NOTIFICATION"; + static final String ACTION_SHOW_TOAST = + "com.android.cts.net.hostside.app2.action.SHOW_TOAST"; private static final String EXTRA_ACTION = "com.android.cts.net.hostside.app2.extra.ACTION"; private static final String EXTRA_RECEIVER_NAME = "com.android.cts.net.hostside.app2.extra.RECEIVER_NAME"; @@ -782,6 +784,17 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation mContext.sendBroadcast(intent); } + protected String showToast() { + final Intent intent = new Intent(ACTION_SHOW_TOAST); + intent.setPackage(TEST_APP2_PKG); + Log.d(TAG, "Sending request to show toast"); + try { + return sendOrderedBroadcast(intent, 3 * SECOND_IN_MS); + } catch (Exception e) { + return ""; + } + } + private String toString(int status) { switch (status) { case RESTRICT_BACKGROUND_STATUS_DISABLED: diff --git a/tests/cts/hostside/app2/AndroidManifest.xml b/tests/cts/hostside/app2/AndroidManifest.xml index 1fa49ba837..adf0045d9f 100644 --- a/tests/cts/hostside/app2/AndroidManifest.xml +++ b/tests/cts/hostside/app2/AndroidManifest.xml @@ -46,6 +46,7 @@ + diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java index 8806e3b970..e07c0f50d5 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java @@ -38,6 +38,8 @@ public final class Common { "com.android.cts.net.hostside.app2.action.FINISH_ACTIVITY"; static final String ACTION_SEND_NOTIFICATION = "com.android.cts.net.hostside.app2.action.SEND_NOTIFICATION"; + static final String ACTION_SHOW_TOAST = + "com.android.cts.net.hostside.app2.action.SHOW_TOAST"; static final String EXTRA_ACTION = "com.android.cts.net.hostside.app2.extra.ACTION"; static final String EXTRA_RECEIVER_NAME = "com.android.cts.net.hostside.app2.extra.RECEIVER_NAME"; diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java index 6d01b1554b..733c3aa6a0 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java @@ -23,6 +23,7 @@ import static com.android.cts.net.hostside.app2.Common.ACTION_GET_COUNTERS; import static com.android.cts.net.hostside.app2.Common.ACTION_GET_RESTRICT_BACKGROUND_STATUS; import static com.android.cts.net.hostside.app2.Common.ACTION_RECEIVER_READY; import static com.android.cts.net.hostside.app2.Common.ACTION_SEND_NOTIFICATION; +import static com.android.cts.net.hostside.app2.Common.ACTION_SHOW_TOAST; import static com.android.cts.net.hostside.app2.Common.EXTRA_ACTION; import static com.android.cts.net.hostside.app2.Common.EXTRA_NOTIFICATION_ID; import static com.android.cts.net.hostside.app2.Common.EXTRA_NOTIFICATION_TYPE; @@ -51,6 +52,7 @@ import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Bundle; import android.util.Log; +import android.widget.Toast; import java.net.HttpURLConnection; import java.net.URL; @@ -104,6 +106,9 @@ public class MyBroadcastReceiver extends BroadcastReceiver { case ACTION_SEND_NOTIFICATION: sendNotification(context, intent); break; + case ACTION_SHOW_TOAST: + showToast(context); + break; default: Log.e(TAG, "received unexpected action: " + action); } @@ -302,4 +307,9 @@ public class MyBroadcastReceiver extends BroadcastReceiver { ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE)) .notify(notificationId, notification); } + + private void showToast(Context context) { + Toast.makeText(context, "Toast from CTS test", Toast.LENGTH_SHORT).show(); + setResultData("Shown"); + } } diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java index dbf8acabea..faf75d9d32 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java @@ -181,6 +181,12 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC "testAppIdleNetworkAccess_whenCharging"); } + public void testAppIdle_toast() throws Exception { + // Check that showing a toast doesn't bring an app out of standby + runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleNonMeteredTest", + "testAppIdle_toast"); + } + /******************** * Doze Mode tests. * ********************/ From af7c4201f988357beb1f0720c23c1fd6ba6981fe Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Thu, 6 Oct 2016 17:17:10 -0700 Subject: [PATCH 0287/1109] Uses bound service instead of ordered broadcast for IPC. BUG: 32017623 Test: m -j 32 cts && cts-tradefed run commandAndExit cts -m CtsHostsideNetworkTests Change-Id: Ibdb84048b04405f234aa5ad9124eb70e9e592498 --- tests/cts/hostside/aidl/Android.mk | 4 +- .../android/cts/net/hostside/IMyService.aidl | 25 +++ ...ractRestrictBackgroundNetworkTestCase.java | 64 +++----- .../cts/net/hostside/MyServiceClient.java | 101 ++++++++++++ .../android/cts/net/hostside/app2/Common.java | 16 +- .../hostside/app2/MyBroadcastReceiver.java | 151 ++++++------------ .../cts/net/hostside/app2/MyService.java | 65 ++++++-- 7 files changed, 263 insertions(+), 163 deletions(-) create mode 100644 tests/cts/hostside/aidl/com/android/cts/net/hostside/IMyService.aidl create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/MyServiceClient.java diff --git a/tests/cts/hostside/aidl/Android.mk b/tests/cts/hostside/aidl/Android.mk index 4aa55b6a08..58be21f608 100644 --- a/tests/cts/hostside/aidl/Android.mk +++ b/tests/cts/hostside/aidl/Android.mk @@ -17,6 +17,8 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests LOCAL_SDK_VERSION := current -LOCAL_SRC_FILES := com/android/cts/net/hostside/IRemoteSocketFactory.aidl +LOCAL_SRC_FILES := \ + com/android/cts/net/hostside/IMyService.aidl \ + com/android/cts/net/hostside/IRemoteSocketFactory.aidl LOCAL_MODULE := CtsHostsideNetworkTestsAidl include $(BUILD_STATIC_JAVA_LIBRARY) diff --git a/tests/cts/hostside/aidl/com/android/cts/net/hostside/IMyService.aidl b/tests/cts/hostside/aidl/com/android/cts/net/hostside/IMyService.aidl new file mode 100644 index 0000000000..72d105990e --- /dev/null +++ b/tests/cts/hostside/aidl/com/android/cts/net/hostside/IMyService.aidl @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2016 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.cts.net.hostside; + +interface IMyService { + void registerBroadcastReceiver(); + int getCounters(String receiverName, String action); + String checkNetworkStatus(); + String getRestrictBackgroundStatus(); + void sendNotification(int notificationId, String notificationType); +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 6db9877463..7497758a70 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -54,25 +54,11 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation // Constants below must match values defined on app2's Common.java private static final String MANIFEST_RECEIVER = "ManifestReceiver"; private static final String DYNAMIC_RECEIVER = "DynamicReceiver"; - private static final String ACTION_GET_COUNTERS = - "com.android.cts.net.hostside.app2.action.GET_COUNTERS"; - private static final String ACTION_GET_RESTRICT_BACKGROUND_STATUS = - "com.android.cts.net.hostside.app2.action.GET_RESTRICT_BACKGROUND_STATUS"; - private static final String ACTION_CHECK_NETWORK = - "com.android.cts.net.hostside.app2.action.CHECK_NETWORK"; + private static final String ACTION_RECEIVER_READY = "com.android.cts.net.hostside.app2.action.RECEIVER_READY"; - static final String ACTION_SEND_NOTIFICATION = - "com.android.cts.net.hostside.app2.action.SEND_NOTIFICATION"; static final String ACTION_SHOW_TOAST = "com.android.cts.net.hostside.app2.action.SHOW_TOAST"; - private static final String EXTRA_ACTION = "com.android.cts.net.hostside.app2.extra.ACTION"; - private static final String EXTRA_RECEIVER_NAME = - "com.android.cts.net.hostside.app2.extra.RECEIVER_NAME"; - private static final String EXTRA_NOTIFICATION_ID = - "com.android.cts.net.hostside.app2.extra.NOTIFICATION_ID"; - private static final String EXTRA_NOTIFICATION_TYPE = - "com.android.cts.net.hostside.app2.extra.NOTIFICATION_TYPE"; protected static final String NOTIFICATION_TYPE_CONTENT = "CONTENT"; protected static final String NOTIFICATION_TYPE_DELETE = "DELETE"; @@ -99,6 +85,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected WifiManager mWfm; protected int mUid; private String mMeteredWifi; + private MyServiceClient mServiceClient; @Override protected void setUp() throws Exception { @@ -110,12 +97,21 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation mWfm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); mUid = getUid(TEST_APP2_PKG); final int myUid = getUid(mContext.getPackageName()); + mServiceClient = new MyServiceClient(mContext); + mServiceClient.bind(); Log.i(TAG, "Apps status on " + getName() + ":\n" + "\ttest app: uid=" + myUid + ", state=" + getProcessStateByUid(myUid) + "\n" + "\tapp2: uid=" + mUid + ", state=" + getProcessStateByUid(mUid)); } + @Override + protected void tearDown() throws Exception { + mServiceClient.unbind(); + + super.tearDown(); + } + protected int getUid(String packageName) throws Exception { return mContext.getPackageManager().getPackageUid(packageName, 0); } @@ -171,19 +167,13 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation } protected int getNumberBroadcastsReceived(String receiverName, String action) throws Exception { - final Intent intent = new Intent(ACTION_GET_COUNTERS); - intent.putExtra(EXTRA_ACTION, ACTION_RESTRICT_BACKGROUND_CHANGED); - intent.putExtra(EXTRA_RECEIVER_NAME, receiverName); - final String resultData = sendOrderedBroadcast(intent); - assertNotNull("timeout waiting for ordered broadcast result", resultData); - return Integer.valueOf(resultData); + return mServiceClient.getCounters(receiverName, action); } protected void assertRestrictBackgroundStatus(int expectedStatus) throws Exception { - final Intent intent = new Intent(ACTION_GET_RESTRICT_BACKGROUND_STATUS); - final String resultData = sendOrderedBroadcast(intent); - assertNotNull("timeout waiting for ordered broadcast result", resultData); - final String actualStatus = toString(Integer.parseInt(resultData)); + final String status = mServiceClient.getRestrictBackgroundStatus(); + assertNotNull("didn't get API status from app2", status); + final String actualStatus = toString(Integer.parseInt(status)); assertEquals("wrong status", toString(expectedStatus), actualStatus); } @@ -329,15 +319,15 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation * @return error message with the mismatch (or empty if assertion passed). */ private String checkNetworkAccess(boolean expectAvailable) throws Exception { - String resultData = sendOrderedBroadcast(new Intent(ACTION_CHECK_NETWORK)); + final String resultData = mServiceClient.checkNetworkStatus(); if (resultData == null) { - return "timeout waiting for ordered broadcast"; + return "did not get network status from app2"; } // Network status format is described on MyBroadcastReceiver.checkNetworkStatus() final String[] parts = resultData.split(NETWORK_STATUS_SEPARATOR); assertEquals("Wrong network status: " + resultData, 5, parts.length); // Sanity check - final State state = State.valueOf(parts[0]); - final DetailedState detailedState = DetailedState.valueOf(parts[1]); + final State state = parts[0].equals("null") ? null : State.valueOf(parts[0]); + final DetailedState detailedState = parts[1].equals("null") ? null : DetailedState.valueOf(parts[1]); final boolean connected = Boolean.valueOf(parts[2]); final String connectionCheckDetails = parts[3]; final String networkInfo = parts[4]; @@ -694,9 +684,10 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation * {@link #runDeviceTests(String, String)} is executed. */ protected void registerBroadcastReceiver() throws Exception { - executeShellCommand("am startservice com.android.cts.net.hostside.app2/.MyService"); + mServiceClient.registerBroadcastReceiver(); + // Wait until receiver is ready. - final int maxTries = 5; + final int maxTries = 10; for (int i = 1; i <= maxTries; i++) { final String message = sendOrderedBroadcast(new Intent(ACTION_RECEIVER_READY), SECOND_IN_MS); @@ -781,13 +772,10 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation + "--receiver-foreground --receiver-registered-only"); } - protected void sendNotification(int notificationId, String notificationType) { - final Intent intent = new Intent(ACTION_SEND_NOTIFICATION); - intent.putExtra(EXTRA_NOTIFICATION_ID, notificationId); - intent.putExtra(EXTRA_NOTIFICATION_TYPE, notificationType); - Log.d(TAG, "Sending notification broadcast (id=" + notificationId + ", type=" - + notificationType + ": " + intent); - mContext.sendBroadcast(intent); + protected void sendNotification(int notificationId, String notificationType) throws Exception { + Log.d(TAG, "Sending notification broadcast (id=" + notificationId + + ", type=" + notificationType); + mServiceClient.sendNotification(notificationId, notificationType); } protected String showToast() { diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyServiceClient.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyServiceClient.java new file mode 100644 index 0000000000..ff05d8c2fc --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyServiceClient.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2016 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.cts.net.hostside; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.ConditionVariable; +import android.os.IBinder; +import android.os.RemoteException; + +import com.android.cts.net.hostside.IMyService; + +import java.io.FileDescriptor; + +public class MyServiceClient { + private static final int TIMEOUT_MS = 5000; + private static final String PACKAGE = MyServiceClient.class.getPackage().getName(); + private static final String APP2_PACKAGE = PACKAGE + ".app2"; + private static final String SERVICE_NAME = APP2_PACKAGE + ".MyService"; + + private Context mContext; + private ServiceConnection mServiceConnection; + private IMyService mService; + + public MyServiceClient(Context context) { + mContext = context; + } + + public void bind() { + if (mService != null) { + throw new IllegalStateException("Already bound"); + } + + final ConditionVariable cv = new ConditionVariable(); + mServiceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + mService = IMyService.Stub.asInterface(service); + cv.open(); + } + @Override + public void onServiceDisconnected(ComponentName name) { + mService = null; + } + }; + + final Intent intent = new Intent(); + intent.setComponent(new ComponentName(APP2_PACKAGE, SERVICE_NAME)); + // Needs to use BIND_ALLOW_OOM_MANAGEMENT and BIND_NOT_FOREGROUND so app2 does not run in + // the same process state as app + mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE + | Context.BIND_ALLOW_OOM_MANAGEMENT | Context.BIND_NOT_FOREGROUND); + cv.block(TIMEOUT_MS); + if (mService == null) { + throw new IllegalStateException( + "Could not bind to MyService service after " + TIMEOUT_MS + "ms"); + } + } + + public void unbind() { + if (mService != null) { + mContext.unbindService(mServiceConnection); + } + } + + public void registerBroadcastReceiver() throws RemoteException { + mService.registerBroadcastReceiver(); + } + + public int getCounters(String receiverName, String action) throws RemoteException { + return mService.getCounters(receiverName, action); + } + + public String checkNetworkStatus() throws RemoteException { + return mService.checkNetworkStatus(); + } + + public String getRestrictBackgroundStatus() throws RemoteException { + return mService.getRestrictBackgroundStatus(); + } + + public void sendNotification(int notificationId, String notificationType) throws RemoteException { + mService.sendNotification(notificationId, notificationType); + } +} diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java index e07c0f50d5..dc9a63036a 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java @@ -26,27 +26,13 @@ public final class Common { // AbstractRestrictBackgroundNetworkTestCase.java static final String MANIFEST_RECEIVER = "ManifestReceiver"; static final String DYNAMIC_RECEIVER = "DynamicReceiver"; - static final String ACTION_GET_COUNTERS = - "com.android.cts.net.hostside.app2.action.GET_COUNTERS"; - static final String ACTION_GET_RESTRICT_BACKGROUND_STATUS = - "com.android.cts.net.hostside.app2.action.GET_RESTRICT_BACKGROUND_STATUS"; - static final String ACTION_CHECK_NETWORK = - "com.android.cts.net.hostside.app2.action.CHECK_NETWORK"; + static final String ACTION_RECEIVER_READY = "com.android.cts.net.hostside.app2.action.RECEIVER_READY"; static final String ACTION_FINISH_ACTIVITY = "com.android.cts.net.hostside.app2.action.FINISH_ACTIVITY"; - static final String ACTION_SEND_NOTIFICATION = - "com.android.cts.net.hostside.app2.action.SEND_NOTIFICATION"; static final String ACTION_SHOW_TOAST = "com.android.cts.net.hostside.app2.action.SHOW_TOAST"; - static final String EXTRA_ACTION = "com.android.cts.net.hostside.app2.extra.ACTION"; - static final String EXTRA_RECEIVER_NAME = - "com.android.cts.net.hostside.app2.extra.RECEIVER_NAME"; - static final String EXTRA_NOTIFICATION_ID = - "com.android.cts.net.hostside.app2.extra.NOTIFICATION_ID"; - static final String EXTRA_NOTIFICATION_TYPE = - "com.android.cts.net.hostside.app2.extra.NOTIFICATION_TYPE"; static final String NOTIFICATION_TYPE_CONTENT = "CONTENT"; static final String NOTIFICATION_TYPE_DELETE = "DELETE"; diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java index 733c3aa6a0..f59cba1252 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java @@ -18,16 +18,8 @@ package com.android.cts.net.hostside.app2; import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; -import static com.android.cts.net.hostside.app2.Common.ACTION_CHECK_NETWORK; -import static com.android.cts.net.hostside.app2.Common.ACTION_GET_COUNTERS; -import static com.android.cts.net.hostside.app2.Common.ACTION_GET_RESTRICT_BACKGROUND_STATUS; import static com.android.cts.net.hostside.app2.Common.ACTION_RECEIVER_READY; -import static com.android.cts.net.hostside.app2.Common.ACTION_SEND_NOTIFICATION; import static com.android.cts.net.hostside.app2.Common.ACTION_SHOW_TOAST; -import static com.android.cts.net.hostside.app2.Common.EXTRA_ACTION; -import static com.android.cts.net.hostside.app2.Common.EXTRA_NOTIFICATION_ID; -import static com.android.cts.net.hostside.app2.Common.EXTRA_NOTIFICATION_TYPE; -import static com.android.cts.net.hostside.app2.Common.EXTRA_RECEIVER_NAME; import static com.android.cts.net.hostside.app2.Common.MANIFEST_RECEIVER; import static com.android.cts.net.hostside.app2.Common.NOTIFICATION_TYPE_ACTION; import static com.android.cts.net.hostside.app2.Common.NOTIFICATION_TYPE_ACTION_BUNDLE; @@ -56,14 +48,12 @@ import android.widget.Toast; import java.net.HttpURLConnection; import java.net.URL; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; /** * Receiver used to: *
      - *
    1. Stored received RESTRICT_BACKGROUND_CHANGED broadcasts in a shared preference. - *
    2. Returned the number of RESTRICT_BACKGROUND_CHANGED broadcasts in an ordered broadcast. + *
    3. Count number of {@code RESTRICT_BACKGROUND_CHANGED} broadcasts received. + *
    4. Show a toast. *
    */ public class MyBroadcastReceiver extends BroadcastReceiver { @@ -89,23 +79,11 @@ public class MyBroadcastReceiver extends BroadcastReceiver { case ACTION_RESTRICT_BACKGROUND_CHANGED: increaseCounter(context, action); break; - case ACTION_GET_COUNTERS: - setResultDataFromCounter(context, intent); - break; - case ACTION_GET_RESTRICT_BACKGROUND_STATUS: - getRestrictBackgroundStatus(context, intent); - break; - case ACTION_CHECK_NETWORK: - checkNetwork(context, intent); - break; case ACTION_RECEIVER_READY: final String message = mName + " is ready to rumble"; Log.d(TAG, message); setResultData(message); break; - case ACTION_SEND_NOTIFICATION: - sendNotification(context, intent); - break; case ACTION_SHOW_TOAST: showToast(context); break; @@ -114,14 +92,20 @@ public class MyBroadcastReceiver extends BroadcastReceiver { } } + @Override + public String toString() { + return "[MyBroadcastReceiver: mName=" + mName + "]"; + } + private void increaseCounter(Context context, String action) { - final SharedPreferences prefs = context.getSharedPreferences(mName, Context.MODE_PRIVATE); + final SharedPreferences prefs = context.getApplicationContext() + .getSharedPreferences(mName, Context.MODE_PRIVATE); final int value = prefs.getInt(action, 0) + 1; Log.d(TAG, "increaseCounter('" + action + "'): setting '" + mName + "' to " + value); prefs.edit().putInt(action, value).apply(); } - private int getCounter(Context context, String action, String receiverName) { + static int getCounter(Context context, String action, String receiverName) { final SharedPreferences prefs = context.getSharedPreferences(receiverName, Context.MODE_PRIVATE); final int value = prefs.getInt(action, 0); @@ -129,29 +113,14 @@ public class MyBroadcastReceiver extends BroadcastReceiver { return value; } - private void getRestrictBackgroundStatus(Context context, Intent intent) { + static String getRestrictBackgroundStatus(Context context) { final ConnectivityManager cm = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); final int apiStatus = cm.getRestrictBackgroundStatus(); Log.d(TAG, "getRestrictBackgroundStatus: returning " + apiStatus); - setResultData(Integer.toString(apiStatus)); + return String.valueOf(apiStatus); } - private void checkNetwork(final Context context, Intent intent) { - final ConnectivityManager cm = (ConnectivityManager) context - .getSystemService(Context.CONNECTIVITY_SERVICE); - - String netStatus = null; - try { - netStatus = checkNetworkStatus(context, cm); - } catch (InterruptedException e) { - Log.e(TAG, "Timeout checking network status"); - } - Log.d(TAG, "checkNetwork(): returning " + netStatus); - setResultData(netStatus); - } - - private static final String NETWORK_STATUS_TEMPLATE = "%s|%s|%s|%s|%s"; /** * Checks whether the network is available and return a string which can then be send as a @@ -182,71 +151,53 @@ public class MyBroadcastReceiver extends BroadcastReceiver { * * */ - private String checkNetworkStatus(final Context context, final ConnectivityManager cm) - throws InterruptedException { - final LinkedBlockingQueue result = new LinkedBlockingQueue<>(1); - new Thread(new Runnable() { - - @Override - public void run() { - // TODO: connect to a hostside server instead - final String address = "http://example.com"; - final NetworkInfo networkInfo = cm.getActiveNetworkInfo(); - Log.d(TAG, "Running checkNetworkStatus() on thread " - + Thread.currentThread().getName() + " for UID " + getUid(context) - + "\n\tactiveNetworkInfo: " + networkInfo + "\n\tURL: " + address); - boolean checkStatus = false; - String checkDetails = "N/A"; - try { - final URL url = new URL(address); - final HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setReadTimeout(NETWORK_TIMEOUT_MS); - conn.setConnectTimeout(NETWORK_TIMEOUT_MS / 2); - conn.setRequestMethod("GET"); - conn.setDoInput(true); - conn.connect(); - final int response = conn.getResponseCode(); - checkStatus = true; - checkDetails = "HTTP response for " + address + ": " + response; - } catch (Exception e) { - checkStatus = false; - checkDetails = "Exception getting " + address + ": " + e; - } - Log.d(TAG, checkDetails); - final String status = String.format(NETWORK_STATUS_TEMPLATE, - networkInfo.getState().name(), networkInfo.getDetailedState().name(), - Boolean.toString(checkStatus), checkDetails, networkInfo); - Log.d(TAG, "Offering " + status); - result.offer(status); - } - }, mName).start(); - return result.poll(NETWORK_TIMEOUT_MS * 2, TimeUnit.MILLISECONDS); - } - - private void setResultDataFromCounter(Context context, Intent intent) { - final String action = intent.getStringExtra(EXTRA_ACTION); - if (action == null) { - Log.e(TAG, "Missing extra '" + EXTRA_ACTION + "' on " + intent); - return; + // TODO: now that it uses Binder, it counl return a Bundle with the data parts instead... + static String checkNetworkStatus(Context context) { + final ConnectivityManager cm = + (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + // TODO: connect to a hostside server instead + final String address = "http://example.com"; + final NetworkInfo networkInfo = cm.getActiveNetworkInfo(); + Log.d(TAG, "Running checkNetworkStatus() on thread " + + Thread.currentThread().getName() + " for UID " + getUid(context) + + "\n\tactiveNetworkInfo: " + networkInfo + "\n\tURL: " + address); + boolean checkStatus = false; + String checkDetails = "N/A"; + try { + final URL url = new URL(address); + final HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setReadTimeout(NETWORK_TIMEOUT_MS); + conn.setConnectTimeout(NETWORK_TIMEOUT_MS / 2); + conn.setRequestMethod("GET"); + conn.setDoInput(true); + conn.connect(); + final int response = conn.getResponseCode(); + checkStatus = true; + checkDetails = "HTTP response for " + address + ": " + response; + } catch (Exception e) { + checkStatus = false; + checkDetails = "Exception getting " + address + ": " + e; } - final String receiverName = intent.getStringExtra(EXTRA_RECEIVER_NAME); - if (receiverName == null) { - Log.e(TAG, "Missing extra '" + EXTRA_RECEIVER_NAME + "' on " + intent); - return; + Log.d(TAG, checkDetails); + final String state, detailedState; + if (networkInfo != null) { + state = networkInfo.getState().name(); + detailedState = networkInfo.getDetailedState().name(); + } else { + state = detailedState = "null"; } - final int counter = getCounter(context, action, receiverName); - setResultData(String.valueOf(counter)); + final String status = String.format(NETWORK_STATUS_TEMPLATE, state, detailedState, + Boolean.valueOf(checkStatus), checkDetails, networkInfo); + Log.d(TAG, "Offering " + status); + return status; } /** * Sends a system notification containing actions with pending intents to launch the app's * main activitiy or service. */ - private void sendNotification(Context context, Intent intent) { - final int notificationId = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1); - final String notificationType = intent.getStringExtra(EXTRA_NOTIFICATION_TYPE); - Log.d(TAG, "sendNotification: id=" + notificationId + ", type=" + notificationType - + ", intent=" + intent); + static void sendNotification(Context context, int notificationId, String notificationType ) { + Log.d(TAG, "sendNotification: id=" + notificationId + ", type=" + notificationType); final Intent serviceIntent = new Intent(context, MyService.class); final PendingIntent pendingIntent = PendingIntent.getService(context, 0, serviceIntent, notificationId); diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java index e6454c7be0..9c19e50238 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java @@ -24,27 +24,74 @@ import android.app.Service; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.SharedPreferences; import android.os.IBinder; +import android.os.Looper; import android.util.Log; +import android.widget.Toast; + +import com.android.cts.net.hostside.IMyService; /** * Service used to dynamically register a broadcast receiver. */ public class MyService extends Service { + private MyBroadcastReceiver mReceiver; + + // TODO: move MyBroadcast static functions here - they were kept there to make git diff easier. + + private IMyService.Stub mBinder = + new IMyService.Stub() { + + @Override + public void registerBroadcastReceiver() { + if (mReceiver != null) { + Log.d(TAG, "receiver already registered: " + mReceiver); + return; + } + final Context context = getApplicationContext(); + mReceiver = new MyBroadcastReceiver(DYNAMIC_RECEIVER); + context.registerReceiver(mReceiver, new IntentFilter(ACTION_RECEIVER_READY)); + context.registerReceiver(mReceiver, + new IntentFilter(ACTION_RESTRICT_BACKGROUND_CHANGED)); + Log.d(TAG, "receiver registered"); + } + + @Override + public int getCounters(String receiverName, String action) { + return MyBroadcastReceiver.getCounter(getApplicationContext(), action, receiverName); + } + + @Override + public String checkNetworkStatus() { + return MyBroadcastReceiver.checkNetworkStatus(getApplicationContext()); + } + + @Override + public String getRestrictBackgroundStatus() { + return MyBroadcastReceiver.getRestrictBackgroundStatus(getApplicationContext()); + } + + @Override + public void sendNotification(int notificationId, String notificationType) { + MyBroadcastReceiver + .sendNotification(getApplicationContext(), notificationId, notificationType); + } + }; + @Override public IBinder onBind(Intent intent) { - return null; + return mBinder; } @Override - public int onStartCommand(Intent intent, int flags, int startId) { - Log.d(TAG, "MyService.onStartCommand: " + intent); - final Context context = getApplicationContext(); - final MyBroadcastReceiver myReceiver = new MyBroadcastReceiver(DYNAMIC_RECEIVER); - context.registerReceiver(myReceiver, new IntentFilter(ACTION_RECEIVER_READY)); - context.registerReceiver(myReceiver, new IntentFilter(ACTION_RESTRICT_BACKGROUND_CHANGED)); - Log.d(TAG, "receiver registered"); - return START_STICKY; + public void onDestroy() { + if (mReceiver != null) { + Log.d(TAG, "onDestroy(): unregistering " + mReceiver); + getApplicationContext().unregisterReceiver(mReceiver); + } + + super.onDestroy(); } } From 2ecad8d87dafed4ff5d671eff8bb811020b744df Mon Sep 17 00:00:00 2001 From: peter_li Date: Tue, 4 Oct 2016 13:36:03 +0800 Subject: [PATCH 0288/1109] =?UTF-8?q?[CTS]It=20should=20be=20more=20reason?= =?UTF-8?q?able=20to=20control=20battery=20saver=20function=20from=20setti?= =?UTF-8?q?ng=20DB=20instead=20of=20plugging/unplugging=20charger=20for=20?= =?UTF-8?q?=E2=80=9CCtsHostsideNetworkTests=E2=80=9D=20test=20case.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Symptom: It should be more reasonable to control battery saver function from setting DB instead of plugging/unplugging charger for “CtsHostsideNetworkTests” test case. Root Cause: The test function “setBatterySaverMode” of “CtsHostsideNetworkTests” use command to set setting DB when trying to turn on battery saver. But while trying to turn off battery saver, it only use charger plug-in event. It should be more reasonable to turn off battery saver through similar DB setting as this function did at turning on. Solution: To control battery saver function from setting DB. Project: Note: Test done by RD: Futher testing need Q team's support: Bug: 31897608 Change-Id: Id70ba458e85f98393d7652bb4e79bd182172c60f --- .../net/hostside/AbstractRestrictBackgroundNetworkTestCase.java | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 9980327bbe..70fc51acfc 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -610,6 +610,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation executeSilentShellCommand("cmd battery unplug"); executeSilentShellCommand("settings put global low_power 1"); } else { + executeSilentShellCommand("settings put global low_power 0"); turnBatteryOn(); } } From 22b355560e02135721fc5799338700145909f59a Mon Sep 17 00:00:00 2001 From: Paul Stewart Date: Wed, 19 Oct 2016 10:41:16 -0700 Subject: [PATCH 0289/1109] CtsNetTests: Add a test for b/25624963 Ensure that password is not output in toString() for an enterprise credential. Bug: 25624963 Test: Run this CTS test: run cts --module CtsNetTestCases --test android.net.wifi.cts.WifiEnterpriseConfigTest#testEnterpriseConfigDoesNotPrintPassword Change-Id: I84a62ae5d37aa7d397203f41362dadb8ceba1e62 --- .../net/wifi/cts/WifiEnterpriseConfigTest.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java index f3eb4e9587..a074f14c8d 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java @@ -532,4 +532,15 @@ public class WifiEnterpriseConfigTest extends AndroidTestCase { } return false; } + + public void testEnterpriseConfigDoesNotPrintPassword() { + WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); + final String identity = "IdentityIsOkayToBeDisplayedHere"; + final String password = "PasswordIsNotOkayToBeDisplayedHere"; + enterpriseConfig.setIdentity(identity); + enterpriseConfig.setPassword(password); + final String stringRepresentation = enterpriseConfig.toString(); + assertTrue(stringRepresentation.contains(identity)); + assertFalse(stringRepresentation.contains(password)); + } } From a84bb771d1f0c46f9505f31c2b18400f6ab9c352 Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Fri, 14 Oct 2016 17:30:15 -0700 Subject: [PATCH 0290/1109] Include Wear device idle settings Certain tests interacting with device idle must set correctly both the normal and wear device idle setting space. Bug: 32183373 Test: Run on wear device and Nexus6P run cts --skip-device-info -m CtsHostsideNetworkTests -t com.android.cts.net.HostsideRestrictBackgroundNetworkTests#testDozeModeMetered_enabledButWhitelistedOnNotificationAction run cts --skip-device-info -m CtsHostsideNetworkTests -t com.android.cts.net.HostsideRestrictBackgroundNetworkTests#testDozeModeNonMetered_enabledButWhitelistedOnNotificationAction Change-Id: I6a53d29021a7d4a257b102a4d3bd5d2cc845c16f --- ...ractRestrictBackgroundNetworkTestCase.java | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index b4d7d9db78..cbd8feaa72 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -29,6 +29,7 @@ import android.app.Instrumentation; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; @@ -99,6 +100,8 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected WifiManager mWfm; protected int mUid; private String mMeteredWifi; + private boolean mHasWatch; + private String mDeviceIdleConstantsSetting; @Override protected void setUp() throws Exception { @@ -110,7 +113,13 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation mWfm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); mUid = getUid(TEST_APP2_PKG); final int myUid = getUid(mContext.getPackageName()); - + mHasWatch = mContext.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_WATCH); + if (mHasWatch) { + mDeviceIdleConstantsSetting = "device_idle_constants_watch"; + } else { + mDeviceIdleConstantsSetting = "device_idle_constants"; + } Log.i(TAG, "Apps status on " + getName() + ":\n" + "\ttest app: uid=" + myUid + ", state=" + getProcessStateByUid(myUid) + "\n" + "\tapp2: uid=" + mUid + ", state=" + getProcessStateByUid(mUid)); @@ -726,14 +735,14 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation } protected void setPendingIntentWhitelistDuration(int durationMs) throws Exception { - final String command = String.format( - "settings put global device_idle_constants %s=%d", - "notification_whitelist_duration", durationMs); - executeSilentShellCommand(command); + executeSilentShellCommand(String.format( + "settings put global %s %s=%d", mDeviceIdleConstantsSetting, + "notification_whitelist_duration", durationMs)); } protected void resetDeviceIdleSettings() throws Exception { - executeShellCommand("settings delete global device_idle_constants"); + executeShellCommand(String.format("settings delete global %s", + mDeviceIdleConstantsSetting)); } protected void startForegroundService() throws Exception { From c6ce1d051ed57281923afb0c64d71ad0f8b0fe2a Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Fri, 14 Oct 2016 17:30:15 -0700 Subject: [PATCH 0291/1109] Include Wear device idle settings Certain tests interacting with device idle must set correctly both the normal and wear device idle setting space. Bug: 32183373 Test: Run on wear device and Nexus6P run cts --skip-device-info -m CtsHostsideNetworkTests -t com.android.cts.net.HostsideRestrictBackgroundNetworkTests#testDozeModeMetered_enabledButWhitelistedOnNotificationAction run cts --skip-device-info -m CtsHostsideNetworkTests -t com.android.cts.net.HostsideRestrictBackgroundNetworkTests#testDozeModeNonMetered_enabledButWhitelistedOnNotificationAction Change-Id: I6a53d29021a7d4a257b102a4d3bd5d2cc845c16f (cherry picked from commit a84bb771d1f0c46f9505f31c2b18400f6ab9c352) --- ...ractRestrictBackgroundNetworkTestCase.java | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index b4d7d9db78..cbd8feaa72 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -29,6 +29,7 @@ import android.app.Instrumentation; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; @@ -99,6 +100,8 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected WifiManager mWfm; protected int mUid; private String mMeteredWifi; + private boolean mHasWatch; + private String mDeviceIdleConstantsSetting; @Override protected void setUp() throws Exception { @@ -110,7 +113,13 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation mWfm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); mUid = getUid(TEST_APP2_PKG); final int myUid = getUid(mContext.getPackageName()); - + mHasWatch = mContext.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_WATCH); + if (mHasWatch) { + mDeviceIdleConstantsSetting = "device_idle_constants_watch"; + } else { + mDeviceIdleConstantsSetting = "device_idle_constants"; + } Log.i(TAG, "Apps status on " + getName() + ":\n" + "\ttest app: uid=" + myUid + ", state=" + getProcessStateByUid(myUid) + "\n" + "\tapp2: uid=" + mUid + ", state=" + getProcessStateByUid(mUid)); @@ -726,14 +735,14 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation } protected void setPendingIntentWhitelistDuration(int durationMs) throws Exception { - final String command = String.format( - "settings put global device_idle_constants %s=%d", - "notification_whitelist_duration", durationMs); - executeSilentShellCommand(command); + executeSilentShellCommand(String.format( + "settings put global %s %s=%d", mDeviceIdleConstantsSetting, + "notification_whitelist_duration", durationMs)); } protected void resetDeviceIdleSettings() throws Exception { - executeShellCommand("settings delete global device_idle_constants"); + executeShellCommand(String.format("settings delete global %s", + mDeviceIdleConstantsSetting)); } protected void startForegroundService() throws Exception { From f705bf695e8e6511940ab1a2fa42ef3ef010213f Mon Sep 17 00:00:00 2001 From: Julien Desprez Date: Fri, 11 Nov 2016 12:11:33 +0000 Subject: [PATCH 0292/1109] Build CTS out of TF source Test: make cts dist, run unit tests Bug: 32819381 Change-Id: I202c2a35e3745a372df8bec4903162d933ae04fb --- tests/cts/hostside/Android.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/hostside/Android.mk b/tests/cts/hostside/Android.mk index ad97ecdc6b..96d735fdca 100644 --- a/tests/cts/hostside/Android.mk +++ b/tests/cts/hostside/Android.mk @@ -21,7 +21,7 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_MODULE := CtsHostsideNetworkTests -LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt +LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed LOCAL_STATIC_JAVA_LIBRARIES := cts-migration-lib From 2bc9c349db402768c05190189987620361d2f06f Mon Sep 17 00:00:00 2001 From: Aaron Holden Date: Tue, 22 Nov 2016 18:44:36 -0800 Subject: [PATCH 0293/1109] Nuke CTS Migration Library, extend CompatibilityBuildHelper bug: 21762834 Test: cts-tradefed run cts -m CtsAppSecurityHostTestCases Change-Id: I72296ca84c76e4af2de0249e4cdb57fed3065e07 --- tests/cts/hostside/Android.mk | 2 -- .../src/com/android/cts/net/HostsideNetworkTestCase.java | 5 +++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/cts/hostside/Android.mk b/tests/cts/hostside/Android.mk index 96d735fdca..1c3f0536c4 100644 --- a/tests/cts/hostside/Android.mk +++ b/tests/cts/hostside/Android.mk @@ -23,8 +23,6 @@ LOCAL_MODULE := CtsHostsideNetworkTests LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed -LOCAL_STATIC_JAVA_LIBRARIES := cts-migration-lib - LOCAL_CTS_TEST_PACKAGE := android.net.hostsidenetwork # Tag this module as a cts test artifact diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java index 6642512758..f3d7dbd4ff 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java @@ -16,7 +16,7 @@ package com.android.cts.net; -import com.android.cts.migration.MigrationHelper; +import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper; import com.android.ddmlib.Log; import com.android.ddmlib.testrunner.RemoteAndroidTestRunner; import com.android.ddmlib.testrunner.TestIdentifier; @@ -80,7 +80,8 @@ abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiRec protected void installPackage(String apk) throws FileNotFoundException, DeviceNotAvailableException { - assertNull(getDevice().installPackage(MigrationHelper.getTestFile(mCtsBuild, apk), false)); + CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild); + assertNull(getDevice().installPackage(buildHelper.getTestFile(apk), false)); } protected void uninstallPackage(String packageName, boolean shouldSucceed) From 68ec71d95415d03d289d2655ba3f66eb1610bd4b Mon Sep 17 00:00:00 2001 From: Bjoern Johansson Date: Wed, 7 Dec 2016 14:42:38 -0800 Subject: [PATCH 0294/1109] Don't require WiFi in CtsHostsideNetworkTests WiFi is not a CDD requirement so these tests should not fail when the device under test does not have WiFi. The behavior is changed so that if there is WiFi then both metered and unmetered tests will run. If there is no WiFi and the current connection is metered then only metered tests will run. If there is no WiFi and the current connection is not metered then only unmetered tests will run. Test: Successfully ran CTS test on both emulator and shamu. BUG: 31648368 Change-Id: Ic643d2490e0a7e69b57a44599f1a4c57c67da873 --- .../net/hostside/AbstractAppIdleTestCase.java | 9 -- .../AbstractBatterySaverModeTestCase.java | 1 - .../hostside/AbstractDozeModeTestCase.java | 1 - ...ractRestrictBackgroundNetworkTestCase.java | 82 ++++++++++++++----- .../cts/net/hostside/AppIdleMeteredTest.java | 4 +- .../net/hostside/AppIdleNonMeteredTest.java | 5 +- .../hostside/BatterySaverModeMeteredTest.java | 4 +- .../BatterySaverModeNonMeteredTest.java | 4 +- .../cts/net/hostside/DataSaverModeTest.java | 6 +- .../cts/net/hostside/DozeModeMeteredTest.java | 4 +- .../net/hostside/DozeModeNonMeteredTest.java | 4 +- .../cts/net/hostside/MixedModesTest.java | 8 +- .../cts/net/HostsideNetworkTestCase.java | 2 - 13 files changed, 84 insertions(+), 50 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java index ba56665fbc..fb773cbef2 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java @@ -30,7 +30,6 @@ abstract class AbstractAppIdleTestCase extends AbstractRestrictBackgroundNetwork if (!isSupported()) return; // Set initial state. - setUpMeteredNetwork(); removePowerSaveModeWhitelist(TEST_APP2_PKG); setAppIdle(false); turnBatteryOff(); @@ -62,14 +61,6 @@ abstract class AbstractAppIdleTestCase extends AbstractRestrictBackgroundNetwork return supported; } - /** - * Sets the initial (non) metered network state. - * - *

    By default is empty - it's up to subclasses to override. - */ - protected void setUpMeteredNetwork() throws Exception { - } - /** * Resets the (non) metered network state. * diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java index c1c91dac80..ed738a6af8 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java @@ -30,7 +30,6 @@ abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgrou if (!isSupported()) return; // Set initial state. - setUpMeteredNetwork(); removePowerSaveModeWhitelist(TEST_APP2_PKG); setBatterySaverMode(false); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java index b89cf93b99..cc05b045ae 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java @@ -31,7 +31,6 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor if (!isSupported()) return; // Set initial state. - setUpMeteredNetwork(); removePowerSaveModeWhitelist(TEST_APP2_PKG); setDozeMode(false); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 70fc51acfc..46d243ee77 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -85,6 +85,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected WifiManager mWfm; protected int mUid; private String mMeteredWifi; + private boolean mSupported; @Override protected void setUp() throws Exception { @@ -96,6 +97,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation mWfm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); mUid = getUid(TEST_APP2_PKG); final int myUid = getUid(mContext.getPackageName()); + mSupported = setUpActiveNetworkMeteringState(); Log.i(TAG, "Apps status on " + getName() + ":\n" + "\ttest app: uid=" + myUid + ", state=" + getProcessStateByUid(myUid) + "\n" @@ -191,7 +193,9 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation /** * Whether this device suport this type of test. * - *

    Should be overridden when necessary, and explicitly used before each test. Example: + *

    Should be overridden when necessary (but always calling + * {@code super.isSupported()} first), and explicitly used before each test + * Example: * *

    
          * public void testSomething() {
    @@ -201,7 +205,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation
          * @return {@code true} by default.
          */
         protected boolean isSupported() throws Exception {
    -        return true;
    +        return mSupported;
         }
     
         /**
    @@ -399,15 +403,61 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation
         }
     
         /**
    -     * Puts the device in a state where the active network is metered, or fail if it can't achieve
    -     * that state.
    +     * Sets the initial metering state for the active network.
    +     *
    +     * 

    It's called on setup and by default does nothing - it's up to the + * subclasses to override. + * + * @return whether the tests in the subclass are supported on this device. */ - protected void setMeteredNetwork() throws Exception { + protected boolean setUpActiveNetworkMeteringState() throws Exception { + return true; + } + + /** + * Makes sure the active network is not metered. + * + *

    If the device does not supoprt un-metered networks (for example if it + * only has cellular data but not wi-fi), it should return {@code false}; + * otherwise, it should return {@code true} (or fail if the un-metered + * network could not be set). + * + * @return {@code true} if the network is now unmetered. + */ + protected boolean setUnmeteredNetwork() throws Exception { + final NetworkInfo info = mCm.getActiveNetworkInfo(); + assertNotNull("Could not get active network", info); + if (!mCm.isActiveNetworkMetered()) { + Log.d(TAG, "Active network is not metered: " + info); + } else if (info.getType() == ConnectivityManager.TYPE_WIFI) { + Log.i(TAG, "Setting active WI-FI network as not metered: " + info ); + setWifiMeteredStatus(false); + } else { + Log.d(TAG, "Active network cannot be set to un-metered: " + info); + return false; + } + assertActiveNetworkMetered(false); // Sanity check. + return true; + } + + /** + * Enables metering on the active network if supported. + * + *

    If the device does not support metered networks it should return + * {@code false}; otherwise, it should return {@code true} (or fail if the + * metered network could not be set). + * + * @return {@code true} if the network is now metered. + */ + protected boolean setMeteredNetwork() throws Exception { final NetworkInfo info = mCm.getActiveNetworkInfo(); final boolean metered = mCm.isActiveNetworkMetered(); if (metered) { Log.d(TAG, "Active network already metered: " + info); - return; + return true; + } else if (info.getType() != ConnectivityManager.TYPE_WIFI) { + Log.w(TAG, "Active network does not support metering: " + info); + return false; } else { Log.w(TAG, "Active network not metered: " + info); } @@ -418,31 +468,21 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation // Sanity check. assertWifiMeteredStatus(netId, true); assertActiveNetworkMetered(true); + return true; } /** - * Puts the device in a state where the active network is not metered, or fail if it can't - * achieve that state. - *

    It assumes the device has a valid WI-FI connection. + * Resets the device metering state to what it was before the test started. + * + *

    This reverts any metering changes made by {@code setMeteredNetwork}. */ protected void resetMeteredNetwork() throws Exception { if (mMeteredWifi != null) { Log.i(TAG, "resetMeteredNetwork(): SID '" + mMeteredWifi + "' was set as metered by test case; resetting it"); setWifiMeteredStatus(mMeteredWifi, false); - } else { - final NetworkInfo info = mCm.getActiveNetworkInfo(); - assertNotNull("Could not get active network", info); - if (!mCm.isActiveNetworkMetered()) { - Log.d(TAG, "Active network is not metered: " + info); - } else if (info.getType() == ConnectivityManager.TYPE_WIFI) { - Log.i(TAG, "Setting active WI-FI network as metered: " + info ); - setWifiMeteredStatus(false); - } else { - fail("Active network is not WI-FI hence cannot be set as non-metered: " + info); - } + assertActiveNetworkMetered(false); // Sanity check. } - assertActiveNetworkMetered(false); // Sanity check. } private void assertActiveNetworkMetered(boolean expected) throws Exception { diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java index e008c695bb..622d99361f 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java @@ -19,8 +19,8 @@ package com.android.cts.net.hostside; public class AppIdleMeteredTest extends AbstractAppIdleTestCase { @Override - protected void setUpMeteredNetwork() throws Exception { - setMeteredNetwork(); + protected boolean setUpActiveNetworkMeteringState() throws Exception { + return setMeteredNetwork(); } @Override diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java index 633dc81c95..bde71f9100 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java @@ -17,9 +17,8 @@ package com.android.cts.net.hostside; public class AppIdleNonMeteredTest extends AbstractAppIdleTestCase { - @Override - protected void setUpMeteredNetwork() throws Exception { - resetMeteredNetwork(); + protected boolean setUpActiveNetworkMeteringState() throws Exception { + return setUnmeteredNetwork(); } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java index 3a88bbd1ad..3071cfe3f1 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java @@ -19,8 +19,8 @@ package com.android.cts.net.hostside; public class BatterySaverModeMeteredTest extends AbstractBatterySaverModeTestCase { @Override - protected void setUpMeteredNetwork() throws Exception { - setMeteredNetwork(); + protected boolean setUpActiveNetworkMeteringState() throws Exception { + return setMeteredNetwork(); } @Override diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java index 646c4b993a..6d3076fe0e 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java @@ -19,7 +19,7 @@ package com.android.cts.net.hostside; public class BatterySaverModeNonMeteredTest extends AbstractBatterySaverModeTestCase { @Override - protected void setUpMeteredNetwork() throws Exception { - resetMeteredNetwork(); + protected boolean setUpActiveNetworkMeteringState() throws Exception { + return setUnmeteredNetwork(); } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index 3e6bd3320a..ac35bd44b6 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -33,7 +33,6 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase if (!isSupported()) return; // Set initial state. - setMeteredNetwork(); setRestrictBackground(false); removeRestrictBackgroundWhitelist(mUid); removeRestrictBackgroundBlacklist(mUid); @@ -55,6 +54,11 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase } } + @Override + protected boolean setUpActiveNetworkMeteringState() throws Exception { + return setMeteredNetwork(); + } + public void testGetRestrictBackgroundStatus_disabled() throws Exception { if (!isSupported()) return; diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java index 656d274c52..e4189af587 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java @@ -19,8 +19,8 @@ package com.android.cts.net.hostside; public class DozeModeMeteredTest extends AbstractDozeModeTestCase { @Override - protected void setUpMeteredNetwork() throws Exception { - setMeteredNetwork(); + protected boolean setUpActiveNetworkMeteringState() throws Exception { + return setMeteredNetwork(); } @Override diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java index c76123822f..edbbb9e1ce 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java @@ -19,7 +19,7 @@ package com.android.cts.net.hostside; public class DozeModeNonMeteredTest extends AbstractDozeModeTestCase { @Override - protected void setUpMeteredNetwork() throws Exception { - resetMeteredNetwork(); + protected boolean setUpActiveNetworkMeteringState() throws Exception { + return setUnmeteredNetwork(); } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java index af52eeece4..ec49eee384 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java @@ -68,7 +68,11 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } Log.i(TAG, "testDataAndBatterySaverModes_meteredNetwork() tests"); - setMeteredNetwork(); + if (!setMeteredNetwork()) { + Log.w(TAG, "testDataAndBatterySaverModes_meteredNetwork() skipped because " + + "device cannot use a metered network"); + return; + } try { setRestrictBackground(true); @@ -139,7 +143,7 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { return; } - if (mCm.isActiveNetworkMetered()) { + if (!setUnmeteredNetwork()) { Log.w(TAG, "testDataAndBatterySaverModes_nonMeteredNetwork() skipped because network" + " is metered"); return; diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java index 6642512758..e96537c308 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java @@ -65,8 +65,6 @@ abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiRec assertNotNull(mAbi); assertNotNull(mCtsBuild); - assertTrue("wi-fi not enabled", getDevice().isWifiEnabled()); - uninstallPackage(TEST_PKG, false); installPackage(TEST_APK); } From 37698cb72bb280dd619f71a7312686a8de26081d Mon Sep 17 00:00:00 2001 From: Aaron Holden Date: Wed, 7 Dec 2016 18:52:10 -0800 Subject: [PATCH 0295/1109] Move libs/deviceutil to device-side/util Test: build cts, run unit tests bug:21762834 Change-Id: Ifd164ced7f040e312e3553f27adf59a648f463ab --- tests/cts/hostside/app/Android.mk | 2 +- .../hostside/AbstractRestrictBackgroundNetworkTestCase.java | 2 +- tests/cts/net/Android.mk | 2 +- .../net/src/android/net/http/cts/HttpResponseCacheTest.java | 3 ++- tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java | 3 ++- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/cts/hostside/app/Android.mk b/tests/cts/hostside/app/Android.mk index 9519ec5242..1c1a798fab 100644 --- a/tests/cts/hostside/app/Android.mk +++ b/tests/cts/hostside/app/Android.mk @@ -20,7 +20,7 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests LOCAL_SDK_VERSION := current -LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner ub-uiautomator \ +LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util ctstestrunner ub-uiautomator \ CtsHostsideNetworkTestsAidl LOCAL_SRC_FILES := $(call all-java-files-under, src) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 5eefcb2ef3..014d7ae6e2 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -16,11 +16,11 @@ package com.android.cts.net.hostside; -import static android.cts.util.SystemUtil.runShellCommand; import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; +import static com.android.compatibility.common.util.SystemUtil.runShellCommand; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index c553a9bb2e..4a776409c7 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -34,7 +34,7 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := CtsNetTestCases -LOCAL_STATIC_JAVA_LIBRARIES := core-tests-support ctsdeviceutil \ +LOCAL_STATIC_JAVA_LIBRARIES := core-tests-support compatibility-device-util \ ctstestrunner ctstestserver mockwebserver # uncomment when b/13249961 is fixed diff --git a/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java b/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java index 7987a50eb9..198f973dfb 100644 --- a/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java +++ b/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java @@ -21,9 +21,10 @@ import com.google.mockwebserver.MockWebServer; import junit.framework.TestCase; -import android.cts.util.FileUtils; import android.net.http.HttpResponseCache; +import com.android.compatibility.common.util.FileUtils; + import java.io.File; import java.io.InputStream; import java.net.CacheRequest; diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java index 696d215649..5983cb72c2 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java @@ -21,7 +21,6 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.cts.util.PollingCheck; import android.net.wifi.SupplicantState; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; @@ -29,6 +28,8 @@ import android.net.wifi.WifiManager.WifiLock; import android.net.wifi.WifiSsid; import android.test.AndroidTestCase; +import com.android.compatibility.common.util.PollingCheck; + import java.util.concurrent.Callable; public class WifiInfoTest extends AndroidTestCase { From d9e98a6688a1f80c61ae0bca3c8bc05150b505c7 Mon Sep 17 00:00:00 2001 From: Neil Fuller Date: Wed, 4 Jan 2017 10:37:34 +0000 Subject: [PATCH 0296/1109] Add more assertions related to LocalServerSocket.accept() The isConnected() / isBound() behavior is new, the behavior when bind() / connect() is called is not. See related frameworks/base changes. Test: Tests run under vogar. Bug: https://code.google.com/p/android/issues/detail?id=35942 Change-Id: I8577212270f3b3e76ea015914eebddc0fe4a6afa --- .../src/android/net/cts/LocalServerSocketTest.java | 3 +++ .../net/src/android/net/cts/LocalSocketTest.java | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java index 103d1da2d6..7c5a1b353d 100644 --- a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java @@ -38,6 +38,9 @@ public class LocalServerSocketTest extends TestCase { clientSocket.connect(new LocalSocketAddress(address)); LocalSocket serverSocket = localServerSocket.accept(); + assertTrue(serverSocket.isConnected()); + assertTrue(serverSocket.isBound()); + // send data from client to server OutputStream clientOutStream = clientSocket.getOutputStream(); clientOutStream.write(12); diff --git a/tests/cts/net/src/android/net/cts/LocalSocketTest.java b/tests/cts/net/src/android/net/cts/LocalSocketTest.java index 0ff4a3080b..8029eb4d67 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketTest.java @@ -50,7 +50,20 @@ public class LocalSocketTest extends TestCase { assertFalse(clientSocket.isConnected()); clientSocket.connect(locSockAddr); assertTrue(clientSocket.isConnected()); + LocalSocket serverSocket = localServerSocket.accept(); + assertTrue(serverSocket.isConnected()); + assertTrue(serverSocket.isBound()); + try { + serverSocket.bind(localServerSocket.getLocalSocketAddress()); + fail("Cannot bind a LocalSocket from accept()"); + } catch (IOException expected) { + } + try { + serverSocket.connect(locSockAddr); + fail("Cannot connect a LocalSocket from accept()"); + } catch (IOException expected) { + } Credentials credent = clientSocket.getPeerCredentials(); assertTrue(0 != credent.getPid()); From a3577f20f2a2efb1fc015bad0145ee935276d305 Mon Sep 17 00:00:00 2001 From: Neil Fuller Date: Fri, 6 Jan 2017 14:05:49 +0000 Subject: [PATCH 0297/1109] Add test for LocalSockets created from a FileDescriptor Adding a test to catch future regressions with this code path. Bug: 34095140 Test: vogar --mode app_process tests/tests/net/src/android/net/cts/LocalSocketTest.java Change-Id: I648ed87d4b9e7fa25787c150f08351c6faf55496 --- .../src/android/net/cts/LocalSocketTest.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/LocalSocketTest.java b/tests/cts/net/src/android/net/cts/LocalSocketTest.java index 8029eb4d67..6e61705b92 100644 --- a/tests/cts/net/src/android/net/cts/LocalSocketTest.java +++ b/tests/cts/net/src/android/net/cts/LocalSocketTest.java @@ -287,6 +287,42 @@ public class LocalSocketTest extends TestCase { } } + // http://b/34095140 + public void testLocalSocketCreatedFromFileDescriptor() throws Exception { + String address = ADDRESS_PREFIX + "_testLocalSocketCreatedFromFileDescriptor"; + + // Establish connection between a local client and server to get a valid client socket file + // descriptor. + try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) { + // Extract the client FileDescriptor we can use. + FileDescriptor fileDescriptor = socketPair.clientSocket.getFileDescriptor(); + assertTrue(fileDescriptor.valid()); + + // Create the LocalSocket we want to test. + LocalSocket clientSocketCreatedFromFileDescriptor = + LocalSocket.createConnectedLocalSocket(fileDescriptor); + assertTrue(clientSocketCreatedFromFileDescriptor.isConnected()); + assertTrue(clientSocketCreatedFromFileDescriptor.isBound()); + + // Test the LocalSocket can be used for communication. + LocalSocket serverSocket = socketPair.serverSocket.accept(); + OutputStream clientOutputStream = + clientSocketCreatedFromFileDescriptor.getOutputStream(); + InputStream serverInputStream = serverSocket.getInputStream(); + + clientOutputStream.write(12); + assertEquals(12, serverInputStream.read()); + + // Closing clientSocketCreatedFromFileDescriptor does not close the file descriptor. + clientSocketCreatedFromFileDescriptor.close(); + assertTrue(fileDescriptor.valid()); + + // .. while closing the LocalSocket that owned the file descriptor does. + socketPair.clientSocket.close(); + assertFalse(fileDescriptor.valid()); + } + } + public void testFlush() throws Exception { String address = ADDRESS_PREFIX + "_testFlush"; From 55e97317e98829706ff77aaac8a4e4908a8b30e2 Mon Sep 17 00:00:00 2001 From: Glen Kuhne Date: Tue, 10 Jan 2017 14:00:20 -0800 Subject: [PATCH 0298/1109] CTS: WifiManager.addNetwork with HttpProxy Added CTS tests verifying, that adding a WifiConfiguration containing an httpProxy will: -Succeed if caller is DeviceOwner -Fail if caller is not DeviceOwner Test: Added two CTS tests Bug: 14669153 Change-Id: I2c81492dba5052117a03a2aa7b3cc8ffb5d52d5f --- .../android/net/wifi/cts/WifiManagerTest.java | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 897e5cfe8e..dcedb18605 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -22,7 +22,6 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; -import android.location.LocationManager; import android.net.NetworkInfo; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; @@ -35,6 +34,8 @@ import android.provider.Settings; import android.test.AndroidTestCase; import android.util.Log; +import com.android.compatibility.common.util.WifiConfigCreator; + import java.net.HttpURLConnection; import java.net.URL; import java.util.HashSet; @@ -68,6 +69,8 @@ public class WifiManagerTest extends AndroidTestCase { private static final String TAG = "WifiManagerTest"; private static final String SSID1 = "\"WifiManagerTest\""; private static final String SSID2 = "\"WifiManagerTestModified\""; + private static final String PROXY_TEST_SSID = "SomeProxyAp"; + private static final String ADD_NETWORK_EXCEPTION_SUBSTR = "addNetwork"; private static final int TIMEOUT_MSEC = 6000; private static final int WAIT_MSEC = 60; private static final int DURATION = 10000; @@ -75,6 +78,8 @@ public class WifiManagerTest extends AndroidTestCase { private static final int WIFI_SCAN_TEST_CACHE_DELAY_MILLIS = 3 * 60 * 1000; private static final int WIFI_SCAN_TEST_ITERATIONS = 5; + private static final String TEST_PAC_URL = "http://www.example.com/proxy.pac"; + private IntentFilter mIntentFilter; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override @@ -405,6 +410,31 @@ public class WifiManagerTest extends AndroidTestCase { } } + /** + * Verifies that addNetwork() fails for WifiConfigurations containing a non-null http proxy when + * the caller doesn't have OVERRIDE_WIFI_CONFIG permission, DeviceOwner or ProfileOwner device + * management policies + */ + public void testSetHttpProxy_PermissionFail() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + WifiConfigCreator configCreator = new WifiConfigCreator(getContext()); + boolean exceptionThrown = false; + try { + configCreator.addHttpProxyNetworkVerifyAndRemove( + PROXY_TEST_SSID, TEST_PAC_URL); + } catch (IllegalStateException e) { + // addHttpProxyNetworkVerifyAndRemove throws three IllegalStateException, + // expect it to throw for the addNetwork operation + if (e.getMessage().contains(ADD_NETWORK_EXCEPTION_SUBSTR)) { + exceptionThrown = true; + } + } + assertTrue(exceptionThrown); + } + private Set getEnabledNetworks(List configuredNetworks) { Set ssids = new HashSet(); for (WifiConfiguration wifiConfig : configuredNetworks) { From 1b93dea624b8f6067a4216646853826162719fe2 Mon Sep 17 00:00:00 2001 From: Glen Kuhne Date: Tue, 10 Jan 2017 14:00:20 -0800 Subject: [PATCH 0299/1109] CTS: WifiManager.addNetwork with HttpProxy Added CTS tests verifying, that adding a WifiConfiguration containing an httpProxy will: -Succeed if caller is DeviceOwner -Fail if caller is not DeviceOwner Test: Added two CTS tests Bug: 14669153 Change-Id: I2c81492dba5052117a03a2aa7b3cc8ffb5d52d5f Merged-In: I2c81492dba5052117a03a2aa7b3cc8ffb5d52d5f --- .../android/net/wifi/cts/WifiManagerTest.java | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 897e5cfe8e..dcedb18605 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -22,7 +22,6 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; -import android.location.LocationManager; import android.net.NetworkInfo; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; @@ -35,6 +34,8 @@ import android.provider.Settings; import android.test.AndroidTestCase; import android.util.Log; +import com.android.compatibility.common.util.WifiConfigCreator; + import java.net.HttpURLConnection; import java.net.URL; import java.util.HashSet; @@ -68,6 +69,8 @@ public class WifiManagerTest extends AndroidTestCase { private static final String TAG = "WifiManagerTest"; private static final String SSID1 = "\"WifiManagerTest\""; private static final String SSID2 = "\"WifiManagerTestModified\""; + private static final String PROXY_TEST_SSID = "SomeProxyAp"; + private static final String ADD_NETWORK_EXCEPTION_SUBSTR = "addNetwork"; private static final int TIMEOUT_MSEC = 6000; private static final int WAIT_MSEC = 60; private static final int DURATION = 10000; @@ -75,6 +78,8 @@ public class WifiManagerTest extends AndroidTestCase { private static final int WIFI_SCAN_TEST_CACHE_DELAY_MILLIS = 3 * 60 * 1000; private static final int WIFI_SCAN_TEST_ITERATIONS = 5; + private static final String TEST_PAC_URL = "http://www.example.com/proxy.pac"; + private IntentFilter mIntentFilter; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override @@ -405,6 +410,31 @@ public class WifiManagerTest extends AndroidTestCase { } } + /** + * Verifies that addNetwork() fails for WifiConfigurations containing a non-null http proxy when + * the caller doesn't have OVERRIDE_WIFI_CONFIG permission, DeviceOwner or ProfileOwner device + * management policies + */ + public void testSetHttpProxy_PermissionFail() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + WifiConfigCreator configCreator = new WifiConfigCreator(getContext()); + boolean exceptionThrown = false; + try { + configCreator.addHttpProxyNetworkVerifyAndRemove( + PROXY_TEST_SSID, TEST_PAC_URL); + } catch (IllegalStateException e) { + // addHttpProxyNetworkVerifyAndRemove throws three IllegalStateException, + // expect it to throw for the addNetwork operation + if (e.getMessage().contains(ADD_NETWORK_EXCEPTION_SUBSTR)) { + exceptionThrown = true; + } + } + assertTrue(exceptionThrown); + } + private Set getEnabledNetworks(List configuredNetworks) { Set ssids = new HashSet(); for (WifiConfiguration wifiConfig : configuredNetworks) { From 2fa6e7ce432764b477683b78f8a949509a975527 Mon Sep 17 00:00:00 2001 From: bohu Date: Wed, 16 Nov 2016 17:22:47 -0800 Subject: [PATCH 0300/1109] CTS: skip wifi related net test if no such feature When a device does not have wifi feature, we should skip wifi related net tests. BUG: 31806034 Change-Id: I9867342c47499efc855a50a67a04177fa94e83e5 --- .../src/android/net/cts/ConnectivityManagerTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index b8478d246b..185ebfa0fc 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -387,6 +387,10 @@ public class ConnectivityManagerTest extends AndroidTestCase { * Tests reporting of connectivity changed. */ public void testConnectivityChanged_manifestRequestOnly_shouldNotReceiveIntent() { + if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) { + Log.i(TAG, "testConnectivityChanged_manifestRequestOnly_shouldNotReceiveIntent cannot execute unless device supports WiFi"); + return; + } ConnectivityReceiver.prepare(); toggleWifi(); @@ -400,6 +404,10 @@ public class ConnectivityManagerTest extends AndroidTestCase { } public void testConnectivityChanged_whenRegistered_shouldReceiveIntent() { + if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) { + Log.i(TAG, "testConnectivityChanged_whenRegistered_shouldReceiveIntent cannot execute unless device supports WiFi"); + return; + } ConnectivityReceiver.prepare(); ConnectivityReceiver receiver = new ConnectivityReceiver(); IntentFilter filter = new IntentFilter(); @@ -416,6 +424,10 @@ public class ConnectivityManagerTest extends AndroidTestCase { public void testConnectivityChanged_manifestRequestOnlyPreN_shouldReceiveIntent() throws InterruptedException { + if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) { + Log.i(TAG, "testConnectivityChanged_manifestRequestOnlyPreN_shouldReceiveIntent cannot execute unless device supports WiFi"); + return; + } Intent startIntent = new Intent(); startIntent.setComponent(new ComponentName("android.net.cts.appForApi23", "android.net.cts.appForApi23.ConnectivityListeningActivity")); From 038b6a4374f6db8bd99ba3be1d38a67a95d9eabc Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Tue, 10 Jan 2017 12:08:43 +0000 Subject: [PATCH 0301/1109] Prepare for removal of legacy-test from default targets In preparation for removing junit classes from the Android API the legacy-test target will be removed from the TARGET_DEFAULT_JAVA_LIBRARIES. This change adds explicit dependencies on junit and/or legacy-android-test to ensure that modules will compile properly once it is removed. Bug: 30188076 Test: make checkbuild Change-Id: I0f34fe97154240e8f8eef6816df1c794da60351e --- tests/cts/net/Android.mk | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index 4a776409c7..98cde9b874 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -34,8 +34,14 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := CtsNetTestCases -LOCAL_STATIC_JAVA_LIBRARIES := core-tests-support compatibility-device-util \ - ctstestrunner ctstestserver mockwebserver +LOCAL_STATIC_JAVA_LIBRARIES := \ + core-tests-support \ + compatibility-device-util \ + ctstestrunner \ + ctstestserver \ + mockwebserver \ + junit \ + legacy-android-test # uncomment when b/13249961 is fixed #LOCAL_SDK_VERSION := current From d872302cdb008868800798908151e0ae26c67574 Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Tue, 10 Jan 2017 12:08:43 +0000 Subject: [PATCH 0302/1109] Prepare for removal of legacy-test from default targets In preparation for removing junit classes from the Android API the legacy-test target will be removed from the TARGET_DEFAULT_JAVA_LIBRARIES. This change adds explicit dependencies on junit and/or legacy-android-test to ensure that modules will compile properly once it is removed. Bug: 30188076 Test: make checkbuild Merged-In: I0f34fe97154240e8f8eef6816df1c794da60351e Change-Id: I7e3b028321c42b7427d79365eb3f51ddf896f930 --- tests/cts/net/Android.mk | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index c553a9bb2e..7d2b0bac99 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -34,8 +34,14 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := CtsNetTestCases -LOCAL_STATIC_JAVA_LIBRARIES := core-tests-support ctsdeviceutil \ - ctstestrunner ctstestserver mockwebserver +LOCAL_STATIC_JAVA_LIBRARIES := \ + core-tests-support \ + ctsdeviceutil \ + ctstestrunner \ + ctstestserver \ + mockwebserver \ + junit \ + legacy-android-test # uncomment when b/13249961 is fixed #LOCAL_SDK_VERSION := current From 32599fd50c32c1c0dbc44625725304cf3e5ab634 Mon Sep 17 00:00:00 2001 From: George Burgess IV Date: Wed, 25 Jan 2017 11:15:52 -0800 Subject: [PATCH 0303/1109] Replace strlen("foo") with sizeof("foo") - 1. We have an upcoming change to Bionic that no longer allows us to treat strlen("foo") as a constant expression, which causes this bit of code to no longer compile. So, we need to either use __builtin_strlen("foo") or sizeof("foo") - 1 instead. (Note that the *optimizer* can still turn it into a constant, but optimization happens after we figure out if something is actually a constant expression or not.) sizeof("foo") is used elsewhere in this file, so I just went with that. Bug: 32073964 Test: Now builds. Change-Id: I2797ee75fd114e237de8e97c50549763c88f73f4 --- tests/cts/net/jni/NativeMultinetworkJni.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/jni/NativeMultinetworkJni.c b/tests/cts/net/jni/NativeMultinetworkJni.c index 6990efa452..91565043ec 100644 --- a/tests/cts/net/jni/NativeMultinetworkJni.c +++ b/tests/cts/net/jni/NativeMultinetworkJni.c @@ -88,7 +88,9 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runSetsocknetwork( return rval == 0 ? 0 : -saved_errno; } -static const int kSockaddrStrLen = INET6_ADDRSTRLEN + strlen("[]:65535"); +// Use sizeof("x") - 1 because we need a compile-time constant, and strlen("x") +// isn't guaranteed to fold to a constant. +static const int kSockaddrStrLen = INET6_ADDRSTRLEN + sizeof("[]:65535") - 1; void sockaddr_ntop(const struct sockaddr *sa, socklen_t salen, char *dst, const size_t size) { char addrstr[INET6_ADDRSTRLEN]; From 446ca6fd2a6ec2872221491b6f02de09bdaa0096 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Fri, 27 Jan 2017 10:15:23 -0800 Subject: [PATCH 0304/1109] WifiManagerTest: |disableOthers| flag change Change the CTS test to reflect the change in behaviour of the |disableOthers| flag in WifiManager.enableNetwork(). This will now just be used as an indication to trigger connection to the specified network instead of disabling all other configured networks. Bug: 34765254 Test: Compiles Change-Id: I97a5a84bb861e289d966552cea7f36d7dd4fd090 --- .../net/src/android/net/wifi/cts/WifiManagerTest.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index dcedb18605..4185189f50 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -218,16 +218,6 @@ public class WifiManagerTest extends AndroidTestCase { return -1; } - private void assertDisableOthers(WifiConfiguration wifiConfiguration, boolean disableOthers) { - for (WifiConfiguration w : mWifiManager.getConfiguredNetworks()) { - if ((!w.SSID.equals(wifiConfiguration.SSID)) && w.status != Status.CURRENT) { - if (disableOthers) { - assertEquals(Status.DISABLED, w.status); - } - } - } - } - /** * test point of wifiManager actions: * 1.reconnect @@ -383,7 +373,6 @@ public class WifiManagerTest extends AndroidTestCase { boolean disableOthers = true; assertTrue(mWifiManager.enableNetwork(netId, disableOthers)); wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); - assertDisableOthers(wifiConfiguration, disableOthers); assertEquals(Status.ENABLED, wifiConfiguration.status); assertTrue(mWifiManager.disableNetwork(netId)); From 9f295aaa43114cc5ea4e18cde4200363806f30e4 Mon Sep 17 00:00:00 2001 From: Paul Stewart Date: Fri, 27 Jan 2017 11:48:29 -0800 Subject: [PATCH 0305/1109] Add CTS test for client certificate chains Add tests to excercise new WifiEnterpriseConfig methods, including setClientKeyEntryWithCertificateChain, and the new getters related to it. Bug: 34688653 Test: This is a test Change-Id: I183166f5864c5ec77eb8590e2e0f521bbc7a39e7 --- .../wifi/cts/WifiEnterpriseConfigTest.java | 268 ++++++++++++++++++ 1 file changed, 268 insertions(+) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java index a074f14c8d..d3235da369 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java @@ -26,8 +26,11 @@ import android.net.wifi.WifiManager; import android.test.AndroidTestCase; import java.io.ByteArrayInputStream; +import java.security.KeyFactory; +import java.security.PrivateKey; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; +import java.security.spec.PKCS8EncodedKeySpec; public class WifiEnterpriseConfigTest extends AndroidTestCase { private WifiManager mWifiManager; @@ -432,6 +435,246 @@ public class WifiEnterpriseConfigTest extends AndroidTestCase { (byte) 0x9e, (byte) 0x34, (byte) 0x73 }; + /** + * Client certificate generated from above and converted with: + * + * openssl x509 -outform d -in usercert.pem | xxd -i | sed 's/0x/(byte) 0x/g' + */ + private static final byte[] FAKE_EC_3 = { + (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0xdf, (byte) 0x30, (byte) 0x82, + (byte) 0x01, (byte) 0xc7, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01, + (byte) 0x02, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x30, (byte) 0x0d, + (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, + (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x0b, (byte) 0x05, + (byte) 0x00, (byte) 0x30, (byte) 0x64, (byte) 0x31, (byte) 0x0b, (byte) 0x30, + (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06, + (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x0b, + (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, + (byte) 0x08, (byte) 0x0c, (byte) 0x02, (byte) 0x43, (byte) 0x41, (byte) 0x31, + (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03, (byte) 0x55, + (byte) 0x04, (byte) 0x07, (byte) 0x0c, (byte) 0x0d, (byte) 0x4d, (byte) 0x6f, + (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6e, + (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77, (byte) 0x31, + (byte) 0x0f, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x03, (byte) 0x55, + (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x06, (byte) 0x47, (byte) 0x6f, + (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, (byte) 0x31, (byte) 0x10, + (byte) 0x30, (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, + (byte) 0x0b, (byte) 0x0c, (byte) 0x07, (byte) 0x41, (byte) 0x6e, (byte) 0x64, + (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x31, (byte) 0x0d, + (byte) 0x30, (byte) 0x0b, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, + (byte) 0x03, (byte) 0x0c, (byte) 0x04, (byte) 0x54, (byte) 0x45, (byte) 0x53, + (byte) 0x54, (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x31, + (byte) 0x37, (byte) 0x30, (byte) 0x31, (byte) 0x32, (byte) 0x37, (byte) 0x31, + (byte) 0x37, (byte) 0x35, (byte) 0x38, (byte) 0x31, (byte) 0x32, (byte) 0x5a, + (byte) 0x17, (byte) 0x0d, (byte) 0x32, (byte) 0x37, (byte) 0x30, (byte) 0x31, + (byte) 0x32, (byte) 0x35, (byte) 0x31, (byte) 0x37, (byte) 0x35, (byte) 0x38, + (byte) 0x31, (byte) 0x32, (byte) 0x5a, (byte) 0x30, (byte) 0x50, (byte) 0x31, + (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, + (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, + (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, + (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x02, (byte) 0x43, + (byte) 0x41, (byte) 0x31, (byte) 0x0f, (byte) 0x30, (byte) 0x0d, (byte) 0x06, + (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x06, + (byte) 0x47, (byte) 0x6f, (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, + (byte) 0x31, (byte) 0x10, (byte) 0x30, (byte) 0x0e, (byte) 0x06, (byte) 0x03, + (byte) 0x55, (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x07, (byte) 0x41, + (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, + (byte) 0x31, (byte) 0x11, (byte) 0x30, (byte) 0x0f, (byte) 0x06, (byte) 0x03, + (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x08, (byte) 0x54, + (byte) 0x45, (byte) 0x53, (byte) 0x54, (byte) 0x2d, (byte) 0x55, (byte) 0x53, + (byte) 0x52, (byte) 0x30, (byte) 0x59, (byte) 0x30, (byte) 0x13, (byte) 0x06, + (byte) 0x07, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, + (byte) 0x02, (byte) 0x01, (byte) 0x06, (byte) 0x08, (byte) 0x2a, (byte) 0x86, + (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x03, (byte) 0x01, (byte) 0x07, + (byte) 0x03, (byte) 0x42, (byte) 0x00, (byte) 0x04, (byte) 0x4a, (byte) 0xb8, + (byte) 0x60, (byte) 0x17, (byte) 0x40, (byte) 0x91, (byte) 0x30, (byte) 0xf7, + (byte) 0xdf, (byte) 0x36, (byte) 0x83, (byte) 0x31, (byte) 0xb5, (byte) 0x3a, + (byte) 0xf4, (byte) 0xd4, (byte) 0xa1, (byte) 0xce, (byte) 0xd5, (byte) 0x54, + (byte) 0x97, (byte) 0x93, (byte) 0x7e, (byte) 0x7b, (byte) 0x08, (byte) 0x63, + (byte) 0x37, (byte) 0x62, (byte) 0xf1, (byte) 0x4e, (byte) 0x6a, (byte) 0x2e, + (byte) 0x35, (byte) 0x4e, (byte) 0x9f, (byte) 0x48, (byte) 0xcd, (byte) 0x09, + (byte) 0x17, (byte) 0xb3, (byte) 0xc1, (byte) 0x58, (byte) 0x02, (byte) 0x49, + (byte) 0x7b, (byte) 0x4c, (byte) 0xf7, (byte) 0x9b, (byte) 0xbb, (byte) 0x1b, + (byte) 0x2b, (byte) 0x9c, (byte) 0xe9, (byte) 0x36, (byte) 0xc4, (byte) 0x00, + (byte) 0x81, (byte) 0x2c, (byte) 0x28, (byte) 0xd9, (byte) 0x6b, (byte) 0xad, + (byte) 0xe3, (byte) 0xe8, (byte) 0xa3, (byte) 0x7b, (byte) 0x30, (byte) 0x79, + (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, + (byte) 0x13, (byte) 0x04, (byte) 0x02, (byte) 0x30, (byte) 0x00, (byte) 0x30, + (byte) 0x2c, (byte) 0x06, (byte) 0x09, (byte) 0x60, (byte) 0x86, (byte) 0x48, + (byte) 0x01, (byte) 0x86, (byte) 0xf8, (byte) 0x42, (byte) 0x01, (byte) 0x0d, + (byte) 0x04, (byte) 0x1f, (byte) 0x16, (byte) 0x1d, (byte) 0x4f, (byte) 0x70, + (byte) 0x65, (byte) 0x6e, (byte) 0x53, (byte) 0x53, (byte) 0x4c, (byte) 0x20, + (byte) 0x47, (byte) 0x65, (byte) 0x6e, (byte) 0x65, (byte) 0x72, (byte) 0x61, + (byte) 0x74, (byte) 0x65, (byte) 0x64, (byte) 0x20, (byte) 0x43, (byte) 0x65, + (byte) 0x72, (byte) 0x74, (byte) 0x69, (byte) 0x66, (byte) 0x69, (byte) 0x63, + (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x30, (byte) 0x1d, (byte) 0x06, + (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16, + (byte) 0x04, (byte) 0x14, (byte) 0xef, (byte) 0xf0, (byte) 0x15, (byte) 0xd7, + (byte) 0xc9, (byte) 0x3e, (byte) 0x9a, (byte) 0x73, (byte) 0xfa, (byte) 0x38, + (byte) 0xc5, (byte) 0x81, (byte) 0x84, (byte) 0x74, (byte) 0xd3, (byte) 0x83, + (byte) 0x74, (byte) 0x26, (byte) 0xf1, (byte) 0x0b, (byte) 0x30, (byte) 0x1f, + (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04, + (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0x38, + (byte) 0x6a, (byte) 0x9b, (byte) 0xf8, (byte) 0x3c, (byte) 0x0d, (byte) 0x54, + (byte) 0x9f, (byte) 0xdf, (byte) 0xf8, (byte) 0x53, (byte) 0x32, (byte) 0xa8, + (byte) 0xf7, (byte) 0x09, (byte) 0x15, (byte) 0x08, (byte) 0x76, (byte) 0xab, + (byte) 0x8d, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, + (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, + (byte) 0x01, (byte) 0x0b, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x82, + (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0xa6, (byte) 0x6c, (byte) 0x18, + (byte) 0xa9, (byte) 0x67, (byte) 0x16, (byte) 0x6a, (byte) 0x9e, (byte) 0x23, + (byte) 0xb3, (byte) 0x2a, (byte) 0xb8, (byte) 0x16, (byte) 0x7b, (byte) 0xb4, + (byte) 0xc8, (byte) 0xbc, (byte) 0x51, (byte) 0xe0, (byte) 0x6f, (byte) 0x05, + (byte) 0x66, (byte) 0xa1, (byte) 0x6f, (byte) 0x96, (byte) 0xde, (byte) 0x5b, + (byte) 0x41, (byte) 0x60, (byte) 0xe5, (byte) 0x29, (byte) 0x99, (byte) 0x12, + (byte) 0xfc, (byte) 0xa9, (byte) 0x91, (byte) 0x23, (byte) 0xb7, (byte) 0x9e, + (byte) 0x00, (byte) 0x5f, (byte) 0x93, (byte) 0xd4, (byte) 0xf7, (byte) 0x27, + (byte) 0x29, (byte) 0x77, (byte) 0xfb, (byte) 0x53, (byte) 0x09, (byte) 0xdc, + (byte) 0xe9, (byte) 0xd0, (byte) 0x5c, (byte) 0x92, (byte) 0x6d, (byte) 0xb7, + (byte) 0xcf, (byte) 0x04, (byte) 0xab, (byte) 0xf1, (byte) 0x39, (byte) 0xb9, + (byte) 0x49, (byte) 0x23, (byte) 0x7c, (byte) 0x0f, (byte) 0x15, (byte) 0x27, + (byte) 0xcd, (byte) 0x65, (byte) 0x3c, (byte) 0x6b, (byte) 0x91, (byte) 0x42, + (byte) 0x5a, (byte) 0xfe, (byte) 0xbe, (byte) 0xb8, (byte) 0xa2, (byte) 0xfd, + (byte) 0x67, (byte) 0x43, (byte) 0x4b, (byte) 0xc9, (byte) 0x28, (byte) 0x65, + (byte) 0x1b, (byte) 0x82, (byte) 0x5b, (byte) 0x25, (byte) 0x20, (byte) 0x9b, + (byte) 0xea, (byte) 0x99, (byte) 0xbb, (byte) 0x66, (byte) 0xc1, (byte) 0x8e, + (byte) 0x46, (byte) 0x0b, (byte) 0x4e, (byte) 0x06, (byte) 0xdd, (byte) 0x50, + (byte) 0x51, (byte) 0x64, (byte) 0xe8, (byte) 0x83, (byte) 0x99, (byte) 0x8e, + (byte) 0x53, (byte) 0xe9, (byte) 0x48, (byte) 0x47, (byte) 0x0e, (byte) 0x08, + (byte) 0x5e, (byte) 0x0d, (byte) 0x4a, (byte) 0x54, (byte) 0x17, (byte) 0xc1, + (byte) 0xf8, (byte) 0xcf, (byte) 0xba, (byte) 0x5c, (byte) 0x38, (byte) 0x70, + (byte) 0x33, (byte) 0x31, (byte) 0x22, (byte) 0x03, (byte) 0x6f, (byte) 0x54, + (byte) 0x3c, (byte) 0x41, (byte) 0xf0, (byte) 0x89, (byte) 0x85, (byte) 0xbc, + (byte) 0x77, (byte) 0x3c, (byte) 0xe8, (byte) 0xec, (byte) 0xb4, (byte) 0x35, + (byte) 0x7a, (byte) 0xcc, (byte) 0x8c, (byte) 0x5f, (byte) 0xa1, (byte) 0xed, + (byte) 0xa6, (byte) 0x28, (byte) 0x14, (byte) 0xc7, (byte) 0x8a, (byte) 0xef, + (byte) 0x56, (byte) 0x26, (byte) 0x35, (byte) 0x46, (byte) 0xab, (byte) 0xb0, + (byte) 0x97, (byte) 0xd2, (byte) 0xbd, (byte) 0xa9, (byte) 0x6a, (byte) 0xe4, + (byte) 0x3e, (byte) 0x87, (byte) 0xfb, (byte) 0xe1, (byte) 0x09, (byte) 0x8d, + (byte) 0x33, (byte) 0x12, (byte) 0xcf, (byte) 0xf0, (byte) 0xc0, (byte) 0xb8, + (byte) 0x9b, (byte) 0x9f, (byte) 0xb1, (byte) 0xcb, (byte) 0xac, (byte) 0x76, + (byte) 0xa8, (byte) 0x05, (byte) 0x6b, (byte) 0xcc, (byte) 0x41, (byte) 0xd2, + (byte) 0x26, (byte) 0x73, (byte) 0xfa, (byte) 0x69, (byte) 0xd3, (byte) 0x1f, + (byte) 0xa9, (byte) 0x0c, (byte) 0x6a, (byte) 0xd6, (byte) 0xc9, (byte) 0x35, + (byte) 0xc5, (byte) 0xad, (byte) 0xa1, (byte) 0x98, (byte) 0xc9, (byte) 0x78, + (byte) 0xa0, (byte) 0xe8, (byte) 0x02, (byte) 0x69, (byte) 0x80, (byte) 0x44, + (byte) 0xd9, (byte) 0xe6, (byte) 0xe5, (byte) 0x26, (byte) 0x4f, (byte) 0xcf, + (byte) 0x38, (byte) 0xcb, (byte) 0x55, (byte) 0x8c, (byte) 0x7d, (byte) 0x3c, + (byte) 0xa8, (byte) 0x82, (byte) 0x69, (byte) 0xa3, (byte) 0xdf, (byte) 0x0a, + (byte) 0x79, (byte) 0x7b, (byte) 0xdd, (byte) 0x24, (byte) 0x6a, (byte) 0x21, + (byte) 0x7b, (byte) 0x20, (byte) 0x94, (byte) 0xcd, (byte) 0x15, (byte) 0x92, + (byte) 0xad, (byte) 0x4a, (byte) 0x72, (byte) 0x0b, (byte) 0x0e, (byte) 0xb2, + (byte) 0xc9 + }; + + private static final byte[] FAKE_KEY_3 = { + (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x02, (byte) 0x01, + (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, + (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, + (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82, + (byte) 0x02, (byte) 0x62, (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5e, + (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81, + (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6, (byte) 0x5b, + (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c, (byte) 0x66, + (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86, (byte) 0x8a, + (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3, (byte) 0x02, + (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08, (byte) 0xf3, + (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04, (byte) 0x6d, + (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f, (byte) 0x67, + (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c, (byte) 0xcb, + (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30, (byte) 0xe2, + (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5, (byte) 0x79, + (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b, (byte) 0xce, + (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb, (byte) 0x08, + (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff, (byte) 0x3b, + (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9, (byte) 0xc4, + (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29, (byte) 0x0d, + (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b, (byte) 0x23, + (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78, (byte) 0x08, + (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5, (byte) 0xf1, + (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19, (byte) 0xb4, + (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03, (byte) 0x16, + (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce, (byte) 0x9e, + (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03, (byte) 0x01, + (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x16, + (byte) 0x59, (byte) 0xc3, (byte) 0x24, (byte) 0x1d, (byte) 0x33, (byte) 0x98, + (byte) 0x9c, (byte) 0xc9, (byte) 0xc8, (byte) 0x2c, (byte) 0x88, (byte) 0xbf, + (byte) 0x0a, (byte) 0x01, (byte) 0xce, (byte) 0xfb, (byte) 0x34, (byte) 0x7a, + (byte) 0x58, (byte) 0x7a, (byte) 0xb0, (byte) 0xbf, (byte) 0xa6, (byte) 0xb2, + (byte) 0x60, (byte) 0xbe, (byte) 0x70, (byte) 0x21, (byte) 0xf5, (byte) 0xfc, + (byte) 0x85, (byte) 0x0d, (byte) 0x33, (byte) 0x58, (byte) 0xa1, (byte) 0xe5, + (byte) 0x09, (byte) 0x36, (byte) 0x84, (byte) 0xb2, (byte) 0x04, (byte) 0x0a, + (byte) 0x02, (byte) 0xd3, (byte) 0x88, (byte) 0x1f, (byte) 0x0c, (byte) 0x2b, + (byte) 0x1d, (byte) 0xe9, (byte) 0x3d, (byte) 0xe7, (byte) 0x79, (byte) 0xf9, + (byte) 0x32, (byte) 0x5c, (byte) 0x8a, (byte) 0x75, (byte) 0x49, (byte) 0x12, + (byte) 0xe4, (byte) 0x05, (byte) 0x26, (byte) 0xd4, (byte) 0x2e, (byte) 0x9e, + (byte) 0x1f, (byte) 0xcc, (byte) 0x54, (byte) 0xad, (byte) 0x33, (byte) 0x8d, + (byte) 0x99, (byte) 0x00, (byte) 0xdc, (byte) 0xf5, (byte) 0xb4, (byte) 0xa2, + (byte) 0x2f, (byte) 0xba, (byte) 0xe5, (byte) 0x62, (byte) 0x30, (byte) 0x6d, + (byte) 0xe6, (byte) 0x3d, (byte) 0xeb, (byte) 0x24, (byte) 0xc2, (byte) 0xdc, + (byte) 0x5f, (byte) 0xb7, (byte) 0x16, (byte) 0x35, (byte) 0xa3, (byte) 0x98, + (byte) 0x98, (byte) 0xa8, (byte) 0xef, (byte) 0xe8, (byte) 0xc4, (byte) 0x96, + (byte) 0x6d, (byte) 0x38, (byte) 0xab, (byte) 0x26, (byte) 0x6d, (byte) 0x30, + (byte) 0xc2, (byte) 0xa0, (byte) 0x44, (byte) 0xe4, (byte) 0xff, (byte) 0x7e, + (byte) 0xbe, (byte) 0x7c, (byte) 0x33, (byte) 0xa5, (byte) 0x10, (byte) 0xad, + (byte) 0xd7, (byte) 0x1e, (byte) 0x13, (byte) 0x20, (byte) 0xb3, (byte) 0x1f, + (byte) 0x41, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xf1, (byte) 0x89, + (byte) 0x07, (byte) 0x0f, (byte) 0xe8, (byte) 0xcf, (byte) 0xab, (byte) 0x13, + (byte) 0x2a, (byte) 0x8f, (byte) 0x88, (byte) 0x80, (byte) 0x11, (byte) 0x9a, + (byte) 0x79, (byte) 0xb6, (byte) 0x59, (byte) 0x3a, (byte) 0x50, (byte) 0x6e, + (byte) 0x57, (byte) 0x37, (byte) 0xab, (byte) 0x2a, (byte) 0xd2, (byte) 0xaa, + (byte) 0xd9, (byte) 0x72, (byte) 0x73, (byte) 0xff, (byte) 0x8b, (byte) 0x47, + (byte) 0x76, (byte) 0xdd, (byte) 0xdc, (byte) 0xf5, (byte) 0x97, (byte) 0x44, + (byte) 0x3a, (byte) 0x78, (byte) 0xbe, (byte) 0x17, (byte) 0xb4, (byte) 0x22, + (byte) 0x6f, (byte) 0xe5, (byte) 0x23, (byte) 0x70, (byte) 0x1d, (byte) 0x10, + (byte) 0x5d, (byte) 0xba, (byte) 0x16, (byte) 0x81, (byte) 0xf1, (byte) 0x45, + (byte) 0xce, (byte) 0x30, (byte) 0xb4, (byte) 0xab, (byte) 0x80, (byte) 0xe4, + (byte) 0x98, (byte) 0x31, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xda, + (byte) 0x82, (byte) 0x9d, (byte) 0x3f, (byte) 0xca, (byte) 0x2f, (byte) 0xe1, + (byte) 0xd4, (byte) 0x86, (byte) 0x77, (byte) 0x48, (byte) 0xa6, (byte) 0xab, + (byte) 0xab, (byte) 0x1c, (byte) 0x42, (byte) 0x5c, (byte) 0xd5, (byte) 0xc7, + (byte) 0x46, (byte) 0x59, (byte) 0x91, (byte) 0x3f, (byte) 0xfc, (byte) 0xcc, + (byte) 0xec, (byte) 0xc2, (byte) 0x40, (byte) 0x12, (byte) 0x2c, (byte) 0x8d, + (byte) 0x1f, (byte) 0xa2, (byte) 0x18, (byte) 0x88, (byte) 0xee, (byte) 0x82, + (byte) 0x4a, (byte) 0x5a, (byte) 0x5e, (byte) 0x88, (byte) 0x20, (byte) 0xe3, + (byte) 0x7b, (byte) 0xe0, (byte) 0xd8, (byte) 0x3a, (byte) 0x52, (byte) 0x9a, + (byte) 0x26, (byte) 0x6a, (byte) 0x04, (byte) 0xec, (byte) 0xe8, (byte) 0xb9, + (byte) 0x48, (byte) 0x40, (byte) 0xe1, (byte) 0xe1, (byte) 0x83, (byte) 0xa6, + (byte) 0x67, (byte) 0xa6, (byte) 0xfd, (byte) 0x02, (byte) 0x41, (byte) 0x00, + (byte) 0x89, (byte) 0x72, (byte) 0x3e, (byte) 0xb0, (byte) 0x90, (byte) 0xfd, + (byte) 0x4c, (byte) 0x0e, (byte) 0xd6, (byte) 0x13, (byte) 0x63, (byte) 0xcb, + (byte) 0xed, (byte) 0x38, (byte) 0x88, (byte) 0xb6, (byte) 0x79, (byte) 0xc4, + (byte) 0x33, (byte) 0x6c, (byte) 0xf6, (byte) 0xf8, (byte) 0xd8, (byte) 0xd0, + (byte) 0xbf, (byte) 0x9d, (byte) 0x35, (byte) 0xac, (byte) 0x69, (byte) 0xd2, + (byte) 0x2b, (byte) 0xc1, (byte) 0xf9, (byte) 0x24, (byte) 0x7b, (byte) 0xce, + (byte) 0xcd, (byte) 0xcb, (byte) 0xa7, (byte) 0xb2, (byte) 0x7a, (byte) 0x0a, + (byte) 0x27, (byte) 0x19, (byte) 0xc9, (byte) 0xaf, (byte) 0x0d, (byte) 0x21, + (byte) 0x89, (byte) 0x88, (byte) 0x7c, (byte) 0xad, (byte) 0x9e, (byte) 0x8d, + (byte) 0x47, (byte) 0x6d, (byte) 0x3f, (byte) 0xce, (byte) 0x7b, (byte) 0xa1, + (byte) 0x74, (byte) 0xf1, (byte) 0xa0, (byte) 0xa1, (byte) 0x02, (byte) 0x41, + (byte) 0x00, (byte) 0xd9, (byte) 0xa8, (byte) 0xf5, (byte) 0xfe, (byte) 0xce, + (byte) 0xe6, (byte) 0x77, (byte) 0x6b, (byte) 0xfe, (byte) 0x2d, (byte) 0xe0, + (byte) 0x1e, (byte) 0xb6, (byte) 0x2e, (byte) 0x12, (byte) 0x4e, (byte) 0x40, + (byte) 0xaf, (byte) 0x6a, (byte) 0x7b, (byte) 0x37, (byte) 0x49, (byte) 0x2a, + (byte) 0x96, (byte) 0x25, (byte) 0x83, (byte) 0x49, (byte) 0xd4, (byte) 0x0c, + (byte) 0xc6, (byte) 0x78, (byte) 0x25, (byte) 0x24, (byte) 0x90, (byte) 0x90, + (byte) 0x06, (byte) 0x15, (byte) 0x9e, (byte) 0xfe, (byte) 0xf9, (byte) 0xdf, + (byte) 0x5b, (byte) 0xf3, (byte) 0x7e, (byte) 0x38, (byte) 0x70, (byte) 0xeb, + (byte) 0x57, (byte) 0xd0, (byte) 0xd9, (byte) 0xa7, (byte) 0x0e, (byte) 0x14, + (byte) 0xf7, (byte) 0x95, (byte) 0x68, (byte) 0xd5, (byte) 0xc8, (byte) 0xab, + (byte) 0x9d, (byte) 0x3a, (byte) 0x2b, (byte) 0x51, (byte) 0xf9, (byte) 0x02, + (byte) 0x41, (byte) 0x00, (byte) 0x96, (byte) 0xdf, (byte) 0xe9, (byte) 0x67, + (byte) 0x6c, (byte) 0xdc, (byte) 0x90, (byte) 0x14, (byte) 0xb4, (byte) 0x1d, + (byte) 0x22, (byte) 0x33, (byte) 0x4a, (byte) 0x31, (byte) 0xc1, (byte) 0x9d, + (byte) 0x2e, (byte) 0xff, (byte) 0x9a, (byte) 0x2a, (byte) 0x95, (byte) 0x4b, + (byte) 0x27, (byte) 0x74, (byte) 0xcb, (byte) 0x21, (byte) 0xc3, (byte) 0xd2, + (byte) 0x0b, (byte) 0xb2, (byte) 0x46, (byte) 0x87, (byte) 0xf8, (byte) 0x28, + (byte) 0x01, (byte) 0x8b, (byte) 0xd8, (byte) 0xb9, (byte) 0x4b, (byte) 0xcd, + (byte) 0x9a, (byte) 0x96, (byte) 0x41, (byte) 0x0e, (byte) 0x36, (byte) 0x6d, + (byte) 0x40, (byte) 0x42, (byte) 0xbc, (byte) 0xd9, (byte) 0xd3, (byte) 0x7b, + (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1, + (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51 + }; private boolean hasWifi() { return getContext().getPackageManager().hasSystemFeature( @@ -492,7 +735,32 @@ public class WifiEnterpriseConfigTest extends AndroidTestCase { X509Certificate[] certs = config.getCaCertificates(); assertTrue(cert1.getSerialNumber().equals(certs[0].getSerialNumber())); assertTrue(cert2.getSerialNumber().equals(certs[1].getSerialNumber())); + + X509Certificate clientCert = (X509Certificate) factory.generateCertificate( + new ByteArrayInputStream(FAKE_EC_3)); + KeyFactory kf = KeyFactory.getInstance("RSA"); + PrivateKey clientKey = kf.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_3)); + + config.setClientKeyEntry(clientKey, clientCert); + X509Certificate testClientCert = config.getClientCertificate(); + X509Certificate[] testClientCertChain = config.getClientCertificateChain(); + assertTrue(clientCert.getSerialNumber().equals(testClientCert.getSerialNumber())); + assertTrue(testClientCertChain.length == 1); + assertTrue(testClientCertChain[0] == testClientCert); + config.setClientKeyEntry(null, null); + assertTrue(config.getClientCertificate() == null); + assertTrue(config.getClientCertificateChain() == null); + + config.setClientKeyEntryWithCertificateChain(clientKey, + new X509Certificate[]{clientCert, cert1}); + testClientCert = config.getClientCertificate(); + testClientCertChain = config.getClientCertificateChain(); + assertTrue(clientCert.getSerialNumber().equals(testClientCert.getSerialNumber())); + assertTrue(testClientCertChain.length == 2); + assertTrue(testClientCertChain[0] == testClientCert); + assertTrue(testClientCertChain[1] == cert1); + config.setSubjectMatch(SUBJECT_MATCH); assertTrue(config.getSubjectMatch().equals(SUBJECT_MATCH)); // Hotspot 2.0 related attributes From 1ac3a1f3fcd0dd4acd18122d054c3123a10c0ae9 Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Fri, 14 Oct 2016 17:30:15 -0700 Subject: [PATCH 0306/1109] Include Wear device idle settings Certain tests interacting with device idle must set correctly both the normal and wear device idle setting space. Bug: 32183373 Test: Run on wear device and Nexus6P run cts --skip-device-info -m CtsHostsideNetworkTests -t com.android.cts.net.HostsideRestrictBackgroundNetworkTests#testDozeModeMetered_enabledButWhitelistedOnNotificationAction run cts --skip-device-info -m CtsHostsideNetworkTests -t com.android.cts.net.HostsideRestrictBackgroundNetworkTests#testDozeModeNonMetered_enabledButWhitelistedOnNotificationAction Change-Id: I6a53d29021a7d4a257b102a4d3bd5d2cc845c16f --- ...ractRestrictBackgroundNetworkTestCase.java | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index b4d7d9db78..cbd8feaa72 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -29,6 +29,7 @@ import android.app.Instrumentation; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; @@ -99,6 +100,8 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected WifiManager mWfm; protected int mUid; private String mMeteredWifi; + private boolean mHasWatch; + private String mDeviceIdleConstantsSetting; @Override protected void setUp() throws Exception { @@ -110,7 +113,13 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation mWfm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); mUid = getUid(TEST_APP2_PKG); final int myUid = getUid(mContext.getPackageName()); - + mHasWatch = mContext.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_WATCH); + if (mHasWatch) { + mDeviceIdleConstantsSetting = "device_idle_constants_watch"; + } else { + mDeviceIdleConstantsSetting = "device_idle_constants"; + } Log.i(TAG, "Apps status on " + getName() + ":\n" + "\ttest app: uid=" + myUid + ", state=" + getProcessStateByUid(myUid) + "\n" + "\tapp2: uid=" + mUid + ", state=" + getProcessStateByUid(mUid)); @@ -726,14 +735,14 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation } protected void setPendingIntentWhitelistDuration(int durationMs) throws Exception { - final String command = String.format( - "settings put global device_idle_constants %s=%d", - "notification_whitelist_duration", durationMs); - executeSilentShellCommand(command); + executeSilentShellCommand(String.format( + "settings put global %s %s=%d", mDeviceIdleConstantsSetting, + "notification_whitelist_duration", durationMs)); } protected void resetDeviceIdleSettings() throws Exception { - executeShellCommand("settings delete global device_idle_constants"); + executeShellCommand(String.format("settings delete global %s", + mDeviceIdleConstantsSetting)); } protected void startForegroundService() throws Exception { From d5eadafa77a74d3792083a52b0659c46542d42e1 Mon Sep 17 00:00:00 2001 From: Geoffrey Pitsch Date: Mon, 30 Jan 2017 13:32:15 -0500 Subject: [PATCH 0307/1109] All cts uses notification channels and new Builder constructor Test: ran cts for all *Test.java files in CL Change-Id: I62f6eae53b539a1cfc79a05a2aa4070bf30fbfc0 --- .../net/hostside/app2/MyBroadcastReceiver.java | 5 +++-- .../net/hostside/app2/MyForegroundService.java | 10 ++++++++-- .../cts/net/hostside/app2/MyService.java | 18 ++++++++++++++++-- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java index f59cba1252..aa54075783 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyBroadcastReceiver.java @@ -196,7 +196,8 @@ public class MyBroadcastReceiver extends BroadcastReceiver { * Sends a system notification containing actions with pending intents to launch the app's * main activitiy or service. */ - static void sendNotification(Context context, int notificationId, String notificationType ) { + static void sendNotification(Context context, String channelId, int notificationId, + String notificationType ) { Log.d(TAG, "sendNotification: id=" + notificationId + ", type=" + notificationType); final Intent serviceIntent = new Intent(context, MyService.class); final PendingIntent pendingIntent = PendingIntent.getService(context, 0, serviceIntent, @@ -204,7 +205,7 @@ public class MyBroadcastReceiver extends BroadcastReceiver { final Bundle bundle = new Bundle(); bundle.putCharSequence("parcelable", "I am not"); - final Notification.Builder builder = new Notification.Builder(context) + final Notification.Builder builder = new Notification.Builder(context, channelId) .setSmallIcon(R.drawable.ic_notification); Action action = null; diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java index b88c45dbb4..fa3fdd148c 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java @@ -18,6 +18,8 @@ package com.android.cts.net.hostside.app2; import static com.android.cts.net.hostside.app2.Common.TAG; import android.R; import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; import android.app.Service; import android.content.Intent; import android.os.IBinder; @@ -27,7 +29,7 @@ import android.util.Log; * Service used to change app state to FOREGROUND_SERVICE. */ public class MyForegroundService extends Service { - + private static final String NOTIFICATION_CHANNEL_ID = "cts/MyForegroundService"; private static final int FLAG_START_FOREGROUND = 1; private static final int FLAG_STOP_FOREGROUND = 2; @@ -39,10 +41,14 @@ public class MyForegroundService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.v(TAG, "MyForegroundService.onStartCommand(): " + intent); + NotificationManager notificationManager = getSystemService(NotificationManager.class); + notificationManager.createNotificationChannel(new NotificationChannel( + NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_ID, + NotificationManager.IMPORTANCE_DEFAULT)); switch (intent.getFlags()) { case FLAG_START_FOREGROUND: Log.d(TAG, "Starting foreground"); - startForeground(42, new Notification.Builder(this) + startForeground(42, new Notification.Builder(this, NOTIFICATION_CHANNEL_ID) .setSmallIcon(R.drawable.ic_dialog_alert) // any icon is fine .build()); break; diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java index 9c19e50238..2496c4ac7d 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java @@ -20,6 +20,8 @@ import static com.android.cts.net.hostside.app2.Common.ACTION_RECEIVER_READY; import static com.android.cts.net.hostside.app2.Common.DYNAMIC_RECEIVER; import static com.android.cts.net.hostside.app2.Common.TAG; +import android.app.NotificationChannel; +import android.app.NotificationManager; import android.app.Service; import android.content.Context; import android.content.Intent; @@ -36,6 +38,7 @@ import com.android.cts.net.hostside.IMyService; * Service used to dynamically register a broadcast receiver. */ public class MyService extends Service { + private static final String NOTIFICATION_CHANNEL_ID = "MyService"; private MyBroadcastReceiver mReceiver; @@ -75,8 +78,8 @@ public class MyService extends Service { @Override public void sendNotification(int notificationId, String notificationType) { - MyBroadcastReceiver - .sendNotification(getApplicationContext(), notificationId, notificationType); + MyBroadcastReceiver .sendNotification(getApplicationContext(), NOTIFICATION_CHANNEL_ID, + notificationId, notificationType); } }; @@ -85,8 +88,19 @@ public class MyService extends Service { return mBinder; } + @Override + public void onCreate() { + final Context context = getApplicationContext(); + ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE)) + .createNotificationChannel(new NotificationChannel(NOTIFICATION_CHANNEL_ID, + NOTIFICATION_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT)); + } + @Override public void onDestroy() { + final Context context = getApplicationContext(); + ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE)) + .deleteNotificationChannel(NOTIFICATION_CHANNEL_ID); if (mReceiver != null) { Log.d(TAG, "onDestroy(): unregistering " + mReceiver); getApplicationContext().unregisterReceiver(mReceiver); From e098c1804d4894a3a83b77f2992fa7e80dea09fe Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Tue, 10 Jan 2017 12:08:43 +0000 Subject: [PATCH 0308/1109] Prepare for removal of legacy-test from default targets In preparation for removing junit classes from the Android API the legacy-test target will be removed from the TARGET_DEFAULT_JAVA_LIBRARIES. This change adds explicit dependencies on junit and/or legacy-android-test to ensure that modules will compile properly once it is removed. Bug: 30188076 Test: make checkbuild Change-Id: I2bbe603b1344d3eef4b48c498311f91b756b85e3 Merged-In: I0f34fe97154240e8f8eef6816df1c794da60351e --- tests/cts/net/Android.mk | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index c553a9bb2e..7d2b0bac99 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -34,8 +34,14 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := CtsNetTestCases -LOCAL_STATIC_JAVA_LIBRARIES := core-tests-support ctsdeviceutil \ - ctstestrunner ctstestserver mockwebserver +LOCAL_STATIC_JAVA_LIBRARIES := \ + core-tests-support \ + ctsdeviceutil \ + ctstestrunner \ + ctstestserver \ + mockwebserver \ + junit \ + legacy-android-test # uncomment when b/13249961 is fixed #LOCAL_SDK_VERSION := current From e66cee48611b7876a8c263cf403b5aac4fdcc078 Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Mon, 9 Jan 2017 16:02:02 -0800 Subject: [PATCH 0309/1109] Update network tests to make sure app has connectivity on start. In the tests, we check the ouput from "am get-uid-state" command to see if the app is coming to foreground and check for network access. But the command gives internal uid state info in AMS and it's possible that the activity/service is not started yet. Update this behavior so that we check for network access only after the activity/service is started. Bug: 27803922 Test: cts-tradefed run singleCommand cts-dev --module CtsHostsideNetworkTests Change-Id: Ic0d94a585439c1d8629a897a8b56bcbf178a4371 --- tests/cts/hostside/aidl/Android.mk | 1 + .../net/hostside/INetworkStateObserver.aidl | 21 ++++ .../net/hostside/AbstractAppIdleTestCase.java | 8 +- .../AbstractBatterySaverModeTestCase.java | 6 +- .../hostside/AbstractDozeModeTestCase.java | 6 +- ...ractRestrictBackgroundNetworkTestCase.java | 100 ++++++++++++------ .../cts/net/hostside/DataSaverModeTest.java | 6 +- .../android/cts/net/hostside/app2/Common.java | 32 ++++++ .../cts/net/hostside/app2/MyActivity.java | 23 +++- .../hostside/app2/MyForegroundService.java | 8 ++ 10 files changed, 160 insertions(+), 51 deletions(-) create mode 100644 tests/cts/hostside/aidl/com/android/cts/net/hostside/INetworkStateObserver.aidl diff --git a/tests/cts/hostside/aidl/Android.mk b/tests/cts/hostside/aidl/Android.mk index 58be21f608..85f71c3726 100644 --- a/tests/cts/hostside/aidl/Android.mk +++ b/tests/cts/hostside/aidl/Android.mk @@ -19,6 +19,7 @@ LOCAL_MODULE_TAGS := tests LOCAL_SDK_VERSION := current LOCAL_SRC_FILES := \ com/android/cts/net/hostside/IMyService.aidl \ + com/android/cts/net/hostside/INetworkStateObserver.aidl \ com/android/cts/net/hostside/IRemoteSocketFactory.aidl LOCAL_MODULE := CtsHostsideNetworkTestsAidl include $(BUILD_STATIC_JAVA_LIBRARY) diff --git a/tests/cts/hostside/aidl/com/android/cts/net/hostside/INetworkStateObserver.aidl b/tests/cts/hostside/aidl/com/android/cts/net/hostside/INetworkStateObserver.aidl new file mode 100644 index 0000000000..09f3120ba9 --- /dev/null +++ b/tests/cts/hostside/aidl/com/android/cts/net/hostside/INetworkStateObserver.aidl @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2016 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.cts.net.hostside; + +oneway interface INetworkStateObserver { + void onNetworkStateChecked(String resultData); +} \ No newline at end of file diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java index 78ba4b9514..0e35b1b8ed 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java @@ -91,9 +91,7 @@ abstract class AbstractAppIdleTestCase extends AbstractRestrictBackgroundNetwork // Make sure foreground app doesn't lose access upon enabling it. setAppIdle(true); - launchActivity(); - assertAppIdle(false); // Sanity check - not idle anymore, since activity was launched... - assertForegroundNetworkAccess(); + launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY); finishActivity(); assertAppIdle(false); // Sanity check - not idle anymore, since activity was launched... assertBackgroundNetworkAccess(true); @@ -102,9 +100,7 @@ abstract class AbstractAppIdleTestCase extends AbstractRestrictBackgroundNetwork // Same for foreground service. setAppIdle(true); - startForegroundService(); - assertAppIdle(true); // Sanity check - still idle - assertForegroundServiceNetworkAccess(); + launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_FOREGROUND_SERVICE); stopForegroundService(); assertAppIdle(true); assertBackgroundNetworkAccess(false); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java index 50bcc6058e..546a550d5c 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java @@ -87,8 +87,7 @@ abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgrou // Make sure foreground app doesn't lose access upon Battery Saver. setBatterySaverMode(false); - launchActivity(); - assertForegroundNetworkAccess(); + launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY); setBatterySaverMode(true); assertForegroundNetworkAccess(); @@ -104,8 +103,7 @@ abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgrou // Make sure foreground service doesn't lose access upon enabling Battery Saver. setBatterySaverMode(false); - startForegroundService(); - assertForegroundNetworkAccess(); + launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_FOREGROUND_SERVICE); setBatterySaverMode(true); assertForegroundNetworkAccess(); stopForegroundService(); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java index 6669af5edd..68f6e7439d 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java @@ -88,8 +88,7 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor // Make sure foreground service doesn't lose network access upon enabling doze. setDozeMode(false); - startForegroundService(); - assertForegroundNetworkAccess(); + launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_FOREGROUND_SERVICE); setDozeMode(true); assertForegroundNetworkAccess(); stopForegroundService(); @@ -159,8 +158,7 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor // leaves Doze Mode. @Override protected void assertsForegroundAlwaysHasNetworkAccess() throws Exception { - startForegroundService(); - assertForegroundServiceNetworkAccess(); + launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_FOREGROUND_SERVICE); stopForegroundService(); assertBackgroundState(); } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 014d7ae6e2..3374378605 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -22,11 +22,13 @@ import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; import static com.android.compatibility.common.util.SystemUtil.runShellCommand; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import android.app.Instrumentation; import android.content.BroadcastReceiver; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; @@ -35,11 +37,15 @@ import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; import android.net.wifi.WifiManager; +import android.os.Binder; +import android.os.Bundle; import android.os.SystemClock; import android.service.notification.NotificationListenerService; import android.test.InstrumentationTestCase; import android.util.Log; +import com.android.cts.net.hostside.INetworkStateObserver; + /** * Superclass for tests related to background network restrictions. */ @@ -49,6 +55,9 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected static final String TEST_PKG = "com.android.cts.net.hostside"; protected static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2"; + private static final String TEST_APP2_ACTIVITY_CLASS = TEST_APP2_PKG + ".MyActivity"; + private static final String TEST_APP2_SERVICE_CLASS = TEST_APP2_PKG + ".MyForegroundService"; + private static final int SLEEP_TIME_SEC = 1; private static final boolean DEBUG = true; @@ -76,6 +85,12 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation private static final int PROCESS_STATE_FOREGROUND_SERVICE = 4; private static final int PROCESS_STATE_TOP = 2; + private static final String KEY_NETWORK_STATE_OBSERVER = TEST_PKG + ".observer"; + + protected static final int TYPE_COMPONENT_ACTIVTIY = 0; + protected static final int TYPE_COMPONENT_FOREGROUND_SERVICE = 1; + + private static final int FOREGROUND_PROC_NETWORK_TIMEOUT_MS = 6000; // Must be higher than NETWORK_TIMEOUT_MS private static final int ORDERED_BROADCAST_TIMEOUT_MS = NETWORK_TIMEOUT_MS * 4; @@ -225,13 +240,11 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation */ protected void assertsForegroundAlwaysHasNetworkAccess() throws Exception{ // Checks foreground first. - launchActivity(); - assertForegroundNetworkAccess(); + launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY); finishActivity(); // Then foreground service - startForegroundService(); - assertForegroundServiceNetworkAccess(); + launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_FOREGROUND_SERVICE); stopForegroundService(); } @@ -329,14 +342,19 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation */ private String checkNetworkAccess(boolean expectAvailable) throws Exception { final String resultData = mServiceClient.checkNetworkStatus(); + return checkForAvailabilityInResultData(resultData, expectAvailable); + } + + private String checkForAvailabilityInResultData(String resultData, boolean expectAvailable) { if (resultData == null) { - return "did not get network status from app2"; + assertNotNull("Network status from app2 is null", resultData); } // Network status format is described on MyBroadcastReceiver.checkNetworkStatus() final String[] parts = resultData.split(NETWORK_STATUS_SEPARATOR); assertEquals("Wrong network status: " + resultData, 5, parts.length); // Sanity check final State state = parts[0].equals("null") ? null : State.valueOf(parts[0]); - final DetailedState detailedState = parts[1].equals("null") ? null : DetailedState.valueOf(parts[1]); + final DetailedState detailedState = parts[1].equals("null") + ? null : DetailedState.valueOf(parts[1]); final boolean connected = Boolean.valueOf(parts[2]); final String connectionCheckDetails = parts[3]; final String networkInfo = parts[4]; @@ -641,7 +659,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation Log.i(TAG, "Setting Battery Saver Mode to " + enabled); if (enabled) { turnBatteryOff(); - executeSilentShellCommand("cmd battery unplug"); executeSilentShellCommand("settings put global low_power 1"); } else { executeSilentShellCommand("settings put global low_power 0"); @@ -742,35 +759,58 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation mDeviceIdleConstantsSetting)); } - protected void startForegroundService() throws Exception { - executeShellCommand( - "am startservice -f 1 com.android.cts.net.hostside.app2/.MyForegroundService"); - assertForegroundServiceState(); + protected void launchComponentAndAssertNetworkAccess(int type) throws Exception { + if (type == TYPE_COMPONENT_ACTIVTIY) { + turnScreenOn(); + } + final CountDownLatch latch = new CountDownLatch(1); + final Intent launchIntent = getIntentForComponent(type); + final Bundle extras = new Bundle(); + final String[] errors = new String[] {null}; + extras.putBinder(KEY_NETWORK_STATE_OBSERVER, getNewNetworkStateObserver(latch, errors)); + launchIntent.putExtras(extras); + if (type == TYPE_COMPONENT_ACTIVTIY) { + mContext.startActivity(launchIntent); + } else if (type == TYPE_COMPONENT_FOREGROUND_SERVICE) { + mContext.startService(launchIntent); + } + if (latch.await(FOREGROUND_PROC_NETWORK_TIMEOUT_MS, TimeUnit.MILLISECONDS)) { + if (!errors[0].isEmpty()) { + fail("Network is not available for app2 (" + mUid + "): " + errors[0]); + } + } else { + fail("Timed out waiting for network availability status from app2 (" + mUid + ")"); + } + } + + private Intent getIntentForComponent(int type) { + final Intent intent = new Intent(); + if (type == TYPE_COMPONENT_ACTIVTIY) { + intent.setComponent(new ComponentName(TEST_APP2_PKG, TEST_APP2_ACTIVITY_CLASS)); + } else if (type == TYPE_COMPONENT_FOREGROUND_SERVICE) { + intent.setComponent(new ComponentName(TEST_APP2_PKG, TEST_APP2_SERVICE_CLASS)) + .setFlags(1); + } else { + fail("Unknown type: " + type); + } + return intent; } protected void stopForegroundService() throws Exception { - executeShellCommand( - "am startservice -f 2 com.android.cts.net.hostside.app2/.MyForegroundService"); + executeShellCommand(String.format("am startservice -f 2 %s/%s", + TEST_APP2_PKG, TEST_APP2_SERVICE_CLASS)); // NOTE: cannot assert state because it depends on whether activity was on top before. } - /** - * Launches an activity on app2 so its process is elevated to foreground status. - */ - protected void launchActivity() throws Exception { - turnScreenOn(); - executeShellCommand("am start com.android.cts.net.hostside.app2/.MyActivity"); - final int maxTries = 30; - ProcessState state = null; - for (int i = 1; i <= maxTries; i++) { - state = getProcessStateByUid(mUid); - if (state.state == PROCESS_STATE_TOP) return; - Log.w(TAG, "launchActivity(): uid " + mUid + " not on TOP state on attempt #" + i - + "; turning screen on and sleeping 1s before checking again"); - turnScreenOn(); - SystemClock.sleep(SECOND_IN_MS); - } - fail("App2 is not on foreground state after " + maxTries + " attempts: " + state); + private Binder getNewNetworkStateObserver(final CountDownLatch latch, + final String[] errors) { + return new INetworkStateObserver.Stub() { + @Override + public void onNetworkStateChecked(String resultData) { + errors[0] = checkForAvailabilityInResultData(resultData, true); + latch.countDown(); + } + }; } /** diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index 7ca302f52a..4c907fff55 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -100,8 +100,7 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase // Make sure foreground app doesn't lose access upon enabling Data Saver. setRestrictBackground(false); - launchActivity(); - assertForegroundNetworkAccess(); + launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_ACTIVTIY); setRestrictBackground(true); assertForegroundNetworkAccess(); @@ -117,8 +116,7 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase // Make sure foreground service doesn't lose access upon enabling Data Saver. setRestrictBackground(false); - startForegroundService(); - assertForegroundNetworkAccess(); + launchComponentAndAssertNetworkAccess(TYPE_COMPONENT_FOREGROUND_SERVICE); setRestrictBackground(true); assertForegroundNetworkAccess(); stopForegroundService(); diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java index dc9a63036a..20bbd5a75c 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/Common.java @@ -16,7 +16,14 @@ package com.android.cts.net.hostside.app2; import android.content.Context; +import android.content.Intent; import android.content.pm.PackageManager.NameNotFoundException; +import android.os.AsyncTask; +import android.os.Bundle; +import android.os.RemoteException; +import android.util.Log; + +import com.android.cts.net.hostside.INetworkStateObserver; public final class Common { @@ -42,6 +49,9 @@ public final class Common { static final String NOTIFICATION_TYPE_ACTION_BUNDLE = "ACTION_BUNDLE"; static final String NOTIFICATION_TYPE_ACTION_REMOTE_INPUT = "ACTION_REMOTE_INPUT"; + static final String TEST_PKG = "com.android.cts.net.hostside"; + static final String KEY_NETWORK_STATE_OBSERVER = TEST_PKG + ".observer"; + static int getUid(Context context) { final String packageName = context.getPackageName(); try { @@ -50,4 +60,26 @@ public final class Common { throw new IllegalStateException("Could not get UID for " + packageName, e); } } + + static void notifyNetworkStateObserver(Context context, Intent intent) { + if (intent == null) { + return; + } + final Bundle extras = intent.getExtras(); + if (extras == null) { + return; + } + final INetworkStateObserver observer = INetworkStateObserver.Stub.asInterface( + extras.getBinder(KEY_NETWORK_STATE_OBSERVER)); + if (observer != null) { + AsyncTask.execute(() -> { + try { + observer.onNetworkStateChecked( + MyBroadcastReceiver.checkNetworkStatus(context)); + } catch (RemoteException e) { + Log.e(TAG, "Error occured while notifying the observer: " + e); + } + }); + } + } } diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java index 444b696962..da7e704e8b 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyActivity.java @@ -17,30 +17,47 @@ package com.android.cts.net.hostside.app2; import static com.android.cts.net.hostside.app2.Common.ACTION_FINISH_ACTIVITY; import static com.android.cts.net.hostside.app2.Common.TAG; +import static com.android.cts.net.hostside.app2.Common.TEST_PKG; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.os.AsyncTask; import android.os.Bundle; +import android.os.RemoteException; import android.util.Log; +import com.android.cts.net.hostside.INetworkStateObserver; + /** * Activity used to bring process to foreground. */ public class MyActivity extends Activity { + private BroadcastReceiver finishCommandReceiver = null; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - registerReceiver(new BroadcastReceiver() { - + Common.notifyNetworkStateObserver(this, getIntent()); + finishCommandReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "Finishing MyActivity"); MyActivity.this.finish(); - }}, new IntentFilter(ACTION_FINISH_ACTIVITY)); + } + }; + registerReceiver(finishCommandReceiver, new IntentFilter(ACTION_FINISH_ACTIVITY)); + } + + @Override + public void finish() { + if (finishCommandReceiver != null) { + unregisterReceiver(finishCommandReceiver); + } + super.finish(); } @Override diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java index fa3fdd148c..ff4ba656b1 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java @@ -16,15 +16,22 @@ package com.android.cts.net.hostside.app2; import static com.android.cts.net.hostside.app2.Common.TAG; +import static com.android.cts.net.hostside.app2.Common.TEST_PKG; + import android.R; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.Service; import android.content.Intent; +import android.os.AsyncTask; +import android.os.Bundle; import android.os.IBinder; +import android.os.RemoteException; import android.util.Log; +import com.android.cts.net.hostside.INetworkStateObserver; + /** * Service used to change app state to FOREGROUND_SERVICE. */ @@ -51,6 +58,7 @@ public class MyForegroundService extends Service { startForeground(42, new Notification.Builder(this, NOTIFICATION_CHANNEL_ID) .setSmallIcon(R.drawable.ic_dialog_alert) // any icon is fine .build()); + Common.notifyNetworkStateObserver(this, intent); break; case FLAG_STOP_FOREGROUND: Log.d(TAG, "Stopping foreground"); From 863ec4b9cb4ee9a8f428bcc76469011bebb0e7ae Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Tue, 21 Feb 2017 13:57:43 -0800 Subject: [PATCH 0310/1109] Relax the check of network availability in CtsHostsideNetworkTests. Bug: 35523062 Test: cts-tradefed run singleCommand cts-dev --module CtsHostsideNetworkTests -t \ com.android.cts.net.HostsideRestrictBackgroundNetworkTests Change-Id: I6c2df38fd7282a0cb9861afbb624018297d400fd --- .../hostside/AbstractRestrictBackgroundNetworkTestCase.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index f5b5dd187d..15daed971b 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -817,7 +817,9 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation } if (latch.await(FOREGROUND_PROC_NETWORK_TIMEOUT_MS, TimeUnit.MILLISECONDS)) { if (!errors[0].isEmpty()) { - fail("Network is not available for app2 (" + mUid + "): " + errors[0]); + // TODO: revert this change once b/35523062 is fixed. +// fail("Network is not available for app2 (" + mUid + "): " + errors[0]); + assertForegroundNetworkAccess(); } } else { fail("Timed out waiting for network availability status from app2 (" + mUid + ")"); From 485adf65b6c9334a72892a9507d87bfd25c1f61f Mon Sep 17 00:00:00 2001 From: Peter Qiu Date: Mon, 27 Feb 2017 13:40:17 -0800 Subject: [PATCH 0311/1109] WifiManagerTest: add tests for verifying Passpoint configuration management APIs Bug: 35756298 Test: run WifiManagerTest Change-Id: I3d106ca9dd4ea74de91c6553eb285534a7856363 --- .../src/android/net/wifi/cts/FakeKeys.java | 237 ++++++++++++++++++ .../android/net/wifi/cts/WifiManagerTest.java | 131 ++++++++++ 2 files changed, 368 insertions(+) create mode 100644 tests/cts/net/src/android/net/wifi/cts/FakeKeys.java diff --git a/tests/cts/net/src/android/net/wifi/cts/FakeKeys.java b/tests/cts/net/src/android/net/wifi/cts/FakeKeys.java new file mode 100644 index 0000000000..f422c2f0fa --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/cts/FakeKeys.java @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2016 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.wifi.cts; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; + +/** + * A class containing test certificates and private keys. + */ +public class FakeKeys { + private static final String CA_CERT0_STRING = "-----BEGIN CERTIFICATE-----\n" + + "MIIDKDCCAhCgAwIBAgIJAILlFdwzLVurMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV\n" + + "BAMTB0VBUCBDQTEwHhcNMTYwMTEyMTE1MDE1WhcNMjYwMTA5MTE1MDE1WjASMRAw\n" + + "DgYDVQQDEwdFQVAgQ0ExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n" + + "znAPUz26Msae4ws43czR41/J2QtrSIZUKmVUsVumDbYHrPNvTXKSMXAcewORDQYX\n" + + "RqvHvpn8CscB1+oGXZvHwxj4zV0WKoK2zeXkau3vcyl3HIKupJfq2TEACefVjj0t\n" + + "JW+X35PGWp9/H5zIUNVNVjS7Ums84IvKhRB8512PB9UyHagXYVX5GWpAcVpyfrlR\n" + + "FI9Qdhh+Pbk0uyktdbf/CdfgHOoebrTtwRljM0oDtX+2Cv6j0wBK7hD8pPvf1+uy\n" + + "GzczigAU/4Kw7eZqydf9B+5RupR+IZipX41xEiIrKRwqi517WWzXcjaG2cNbf451\n" + + "xpH5PnV3i1tq04jMGQUzFwIDAQABo4GAMH4wHQYDVR0OBBYEFIwX4vs8BiBcScod\n" + + "5noZHRM8E4+iMEIGA1UdIwQ7MDmAFIwX4vs8BiBcScod5noZHRM8E4+ioRakFDAS\n" + + "MRAwDgYDVQQDEwdFQVAgQ0ExggkAguUV3DMtW6swDAYDVR0TBAUwAwEB/zALBgNV\n" + + "HQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAFfQqOTA7Rv7K+luQ7pnas4BYwHE\n" + + "9GEP/uohv6KOy0TGQFbrRTjFoLVNB9BZ1ymMDZ0/TIwIUc7wi7a8t5mEqYH153wW\n" + + "aWooiSjyLLhuI4sNrNCOtisdBq2r2MFXt6h0mAQYOPv8R8K7/fgSxGFqzhyNmmVL\n" + + "1qBJldx34SpwsTALQVPb4hGwJzZfr1PcpEQx6xMnTl8xEWZE3Ms99uaUxbQqIwRu\n" + + "LgAOkNCmY2m89VhzaHJ1uV85AdM/tD+Ysmlnnjt9LRCejbBipjIGjOXrg1JP+lxV\n" + + "muM4vH+P/mlmxsPPz0d65b+EGmJZpoLkO/tdNNvCYzjJpTEWpEsO6NMhKYo=\n" + + "-----END CERTIFICATE-----\n"; + public static final X509Certificate CA_CERT0 = loadCertificate(CA_CERT0_STRING); + + private static final String CA_CERT1_STRING = "-----BEGIN CERTIFICATE-----\n" + + "MIIDKDCCAhCgAwIBAgIJAOM5SzKO2pzCMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV\n" + + "BAMTB0VBUCBDQTAwHhcNMTYwMTEyMDAxMDQ3WhcNMjYwMTA5MDAxMDQ3WjASMRAw\n" + + "DgYDVQQDEwdFQVAgQ0EwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n" + + "89ug+IEKVQXnJGKg5g4uVHg6J/8iRUxR5k2eH5o03hrJNMfN2D+cBe/wCiZcnWbI\n" + + "GbGZACWm2nQth2wy9Zgm2LOd3b4ocrHYls3XLq6Qb5Dd7a0JKU7pdGufiNVEkrmF\n" + + "EB+N64wgwH4COTvCiN4erp5kyJwkfqAl2xLkZo0C464c9XoyQOXbmYD9A8v10wZu\n" + + "jyNsEo7Nr2USyw+qhjWSbFbEirP77Tvx+7pJQJwdtk1V9Tn73T2dGF2WHYejei9S\n" + + "mcWpdIUqsu9etYH+zDmtu7I1xlkwiaVsNr2+D+qaCJyOYqrDTKVNK5nmbBPXDWZc\n" + + "NoDbTOoqquX7xONpq9M6jQIDAQABo4GAMH4wHQYDVR0OBBYEFAZ3A2S4qJZZwuNY\n" + + "wkJ6mAdc0gVdMEIGA1UdIwQ7MDmAFAZ3A2S4qJZZwuNYwkJ6mAdc0gVdoRakFDAS\n" + + "MRAwDgYDVQQDEwdFQVAgQ0EwggkA4zlLMo7anMIwDAYDVR0TBAUwAwEB/zALBgNV\n" + + "HQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAHmdMwEhtys4d0E+t7owBmoVR+lU\n" + + "hMCcRtWs8YKX5WIM2kTweT0h/O1xwE1mWmRv/IbDAEb8od4BjAQLhIcolStr2JaO\n" + + "9ZzyxjOnNzqeErh/1DHDbb/moPpqfeJ8YiEz7nH/YU56Q8iCPO7TsgS0sNNE7PfN\n" + + "IUsBW0yHRgpQ4OxWmiZG2YZWiECRzAC0ecPzo59N5iH4vLQIMTMYquiDeMPQnn1e\n" + + "NDGxG8gCtDKIaS6tMg3a28MvWB094pr2ETou8O1C8Ji0Y4hE8QJmSdT7I4+GZjgW\n" + + "g94DZ5RiL7sdp3vC48CXOmeT61YBIvhGUsE1rPhXqkpqQ3Z3C4TFF0jXZZc=\n" + + "-----END CERTIFICATE-----\n"; + public static final X509Certificate CA_CERT1 = loadCertificate(CA_CERT1_STRING); + + private static final String CLIENT_CERT_STR = "-----BEGIN CERTIFICATE-----\n" + + "MIIE/DCCAuQCAQEwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxCzAJBgNV\n" + + "BAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdUZXN0aW5n\n" + + "MB4XDTE2MDkzMDIwNTQyOFoXDTE3MDkzMDIwNTQyOFowRDELMAkGA1UEBhMCVVMx\n" + + "CzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdU\n" + + "ZXN0aW5nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnpmcbuaeHfnJ\n" + + "k+2QNvxmdVFTawyFMNk0USCq5sexscwmxbewG/Rb8YnixwJWS44v2XkSujB67z5C\n" + + "s2qudFEhRXKdEuC6idbAuA97KjipHh0AAniWMsyv61fvbgsUC0b0canx3LiDq81p\n" + + "y28NNGmAvoazLZUZ4AhBRiwYZY6FKk723gmZoGbEIeG7J1dlXPusc1662rIjz4eU\n" + + "zlmmlvqyHfNqnNk8L14Vug6Xh+lOEGN85xhu1YHAEKGrS89kZxs5rum/cZU8KH2V\n" + + "v6eKnY03kxjiVLQtnLpm/7VUEoCMGHyruRj+p3my4+DgqMsmsH52RZCBsjyGlpbU\n" + + "NOwOTIX6xh+Rqloduz4AnrMYYIiIw2s8g+2zJM7VbcVKx0fGS26BKdrxgrXWfmNE\n" + + "nR0/REQ5AxDGw0jfTUvtdTkXAf+K4MDjcNLEZ+MA4rHfAfQWZtUR5BkHCQYxNpJk\n" + + "pA0gyk+BpKdC4WdzI14NSWsu5sRCmBCFqH6BTOSEq/V1cNorBxNwLSSTwFFqUDqx\n" + + "Y5nQLXygkJf9WHZWtSKeSjtOYgilz7UKzC2s3CsjmIyGFe+SwpuHJnuE4Uc8Z5Cb\n" + + "bjNGHPzqL6XnmzZHJp7RF8kBdKdjGC7dCUltzOfICZeKlzOOq+Kw42T/nXjuXvpb\n" + + "nkXNxg741Nwd6RecykXJbseFwm3EYxkCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEA\n" + + "Ga1mGwI9aXkL2fTPXO9YkAPzoGeX8aeuVYSQaSkNq+5vnogYCyAt3YDHjRG+ewTT\n" + + "WbnPA991xRAPac+biJeXWmwvgGj0YuT7e79phAiGkTTnbAjFHGfYnBy/tI/v7btO\n" + + "hRNElA5yTJ1m2fVbBEKXzMR83jrT9iyI+YLRN86zUZIaC86xxSbqnrdWN2jOK6MX\n" + + "dS8Arp9tPQjC/4gW+2Ilxv68jiYh+5auWHQZVjppWVY//iu4mAbkq1pTwQEhZ8F8\n" + + "Zrmh9DHh60hLFcfSuhIAwf/NMzppwdkjy1ruKVrpijhGKGp4OWu8nvOUgHSzxc7F\n" + + "PwpVZ5N2Ku4L8MLO6BG2VasRJK7l17TzDXlfLZHJjkuryOFxVaQKt8ZNFgTOaCXS\n" + + "E+gpTLksKU7riYckoiP4+H1sn9qcis0e8s4o/uf1UVc8GSdDw61ReGM5oZEDm1u8\n" + + "H9x20QU6igLqzyBpqvCKv7JNgU1uB2PAODHH78zJiUfnKd1y+o+J1iWzaGj3EFji\n" + + "T8AXksbTP733FeFXfggXju2dyBH+Z1S5BBTEOd1brWgXlHSAZGm97MKZ94r6/tkX\n" + + "qfv3fCos0DKz0oV7qBxYS8wiYhzrRVxG6ITAoH8uuUVVQaZF+G4nJ2jEqNbfuKyX\n" + + "ATQsVNjNNlDA0J33GobPMjT326wa4YAWMx8PI5PJZ3g=\n" + + "-----END CERTIFICATE-----\n"; + public static final X509Certificate CLIENT_CERT = loadCertificate(CLIENT_CERT_STR); + + private static final byte[] FAKE_RSA_KEY_1 = new byte[] { + (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x02, (byte) 0x01, + (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, + (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, + (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82, + (byte) 0x02, (byte) 0x62, (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5e, + (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81, + (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6, (byte) 0x5b, + (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c, (byte) 0x66, + (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86, (byte) 0x8a, + (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3, (byte) 0x02, + (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08, (byte) 0xf3, + (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04, (byte) 0x6d, + (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f, (byte) 0x67, + (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c, (byte) 0xcb, + (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30, (byte) 0xe2, + (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5, (byte) 0x79, + (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b, (byte) 0xce, + (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb, (byte) 0x08, + (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff, (byte) 0x3b, + (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9, (byte) 0xc4, + (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29, (byte) 0x0d, + (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b, (byte) 0x23, + (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78, (byte) 0x08, + (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5, (byte) 0xf1, + (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19, (byte) 0xb4, + (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03, (byte) 0x16, + (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce, (byte) 0x9e, + (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03, (byte) 0x01, + (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x16, + (byte) 0x59, (byte) 0xc3, (byte) 0x24, (byte) 0x1d, (byte) 0x33, (byte) 0x98, + (byte) 0x9c, (byte) 0xc9, (byte) 0xc8, (byte) 0x2c, (byte) 0x88, (byte) 0xbf, + (byte) 0x0a, (byte) 0x01, (byte) 0xce, (byte) 0xfb, (byte) 0x34, (byte) 0x7a, + (byte) 0x58, (byte) 0x7a, (byte) 0xb0, (byte) 0xbf, (byte) 0xa6, (byte) 0xb2, + (byte) 0x60, (byte) 0xbe, (byte) 0x70, (byte) 0x21, (byte) 0xf5, (byte) 0xfc, + (byte) 0x85, (byte) 0x0d, (byte) 0x33, (byte) 0x58, (byte) 0xa1, (byte) 0xe5, + (byte) 0x09, (byte) 0x36, (byte) 0x84, (byte) 0xb2, (byte) 0x04, (byte) 0x0a, + (byte) 0x02, (byte) 0xd3, (byte) 0x88, (byte) 0x1f, (byte) 0x0c, (byte) 0x2b, + (byte) 0x1d, (byte) 0xe9, (byte) 0x3d, (byte) 0xe7, (byte) 0x79, (byte) 0xf9, + (byte) 0x32, (byte) 0x5c, (byte) 0x8a, (byte) 0x75, (byte) 0x49, (byte) 0x12, + (byte) 0xe4, (byte) 0x05, (byte) 0x26, (byte) 0xd4, (byte) 0x2e, (byte) 0x9e, + (byte) 0x1f, (byte) 0xcc, (byte) 0x54, (byte) 0xad, (byte) 0x33, (byte) 0x8d, + (byte) 0x99, (byte) 0x00, (byte) 0xdc, (byte) 0xf5, (byte) 0xb4, (byte) 0xa2, + (byte) 0x2f, (byte) 0xba, (byte) 0xe5, (byte) 0x62, (byte) 0x30, (byte) 0x6d, + (byte) 0xe6, (byte) 0x3d, (byte) 0xeb, (byte) 0x24, (byte) 0xc2, (byte) 0xdc, + (byte) 0x5f, (byte) 0xb7, (byte) 0x16, (byte) 0x35, (byte) 0xa3, (byte) 0x98, + (byte) 0x98, (byte) 0xa8, (byte) 0xef, (byte) 0xe8, (byte) 0xc4, (byte) 0x96, + (byte) 0x6d, (byte) 0x38, (byte) 0xab, (byte) 0x26, (byte) 0x6d, (byte) 0x30, + (byte) 0xc2, (byte) 0xa0, (byte) 0x44, (byte) 0xe4, (byte) 0xff, (byte) 0x7e, + (byte) 0xbe, (byte) 0x7c, (byte) 0x33, (byte) 0xa5, (byte) 0x10, (byte) 0xad, + (byte) 0xd7, (byte) 0x1e, (byte) 0x13, (byte) 0x20, (byte) 0xb3, (byte) 0x1f, + (byte) 0x41, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xf1, (byte) 0x89, + (byte) 0x07, (byte) 0x0f, (byte) 0xe8, (byte) 0xcf, (byte) 0xab, (byte) 0x13, + (byte) 0x2a, (byte) 0x8f, (byte) 0x88, (byte) 0x80, (byte) 0x11, (byte) 0x9a, + (byte) 0x79, (byte) 0xb6, (byte) 0x59, (byte) 0x3a, (byte) 0x50, (byte) 0x6e, + (byte) 0x57, (byte) 0x37, (byte) 0xab, (byte) 0x2a, (byte) 0xd2, (byte) 0xaa, + (byte) 0xd9, (byte) 0x72, (byte) 0x73, (byte) 0xff, (byte) 0x8b, (byte) 0x47, + (byte) 0x76, (byte) 0xdd, (byte) 0xdc, (byte) 0xf5, (byte) 0x97, (byte) 0x44, + (byte) 0x3a, (byte) 0x78, (byte) 0xbe, (byte) 0x17, (byte) 0xb4, (byte) 0x22, + (byte) 0x6f, (byte) 0xe5, (byte) 0x23, (byte) 0x70, (byte) 0x1d, (byte) 0x10, + (byte) 0x5d, (byte) 0xba, (byte) 0x16, (byte) 0x81, (byte) 0xf1, (byte) 0x45, + (byte) 0xce, (byte) 0x30, (byte) 0xb4, (byte) 0xab, (byte) 0x80, (byte) 0xe4, + (byte) 0x98, (byte) 0x31, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xda, + (byte) 0x82, (byte) 0x9d, (byte) 0x3f, (byte) 0xca, (byte) 0x2f, (byte) 0xe1, + (byte) 0xd4, (byte) 0x86, (byte) 0x77, (byte) 0x48, (byte) 0xa6, (byte) 0xab, + (byte) 0xab, (byte) 0x1c, (byte) 0x42, (byte) 0x5c, (byte) 0xd5, (byte) 0xc7, + (byte) 0x46, (byte) 0x59, (byte) 0x91, (byte) 0x3f, (byte) 0xfc, (byte) 0xcc, + (byte) 0xec, (byte) 0xc2, (byte) 0x40, (byte) 0x12, (byte) 0x2c, (byte) 0x8d, + (byte) 0x1f, (byte) 0xa2, (byte) 0x18, (byte) 0x88, (byte) 0xee, (byte) 0x82, + (byte) 0x4a, (byte) 0x5a, (byte) 0x5e, (byte) 0x88, (byte) 0x20, (byte) 0xe3, + (byte) 0x7b, (byte) 0xe0, (byte) 0xd8, (byte) 0x3a, (byte) 0x52, (byte) 0x9a, + (byte) 0x26, (byte) 0x6a, (byte) 0x04, (byte) 0xec, (byte) 0xe8, (byte) 0xb9, + (byte) 0x48, (byte) 0x40, (byte) 0xe1, (byte) 0xe1, (byte) 0x83, (byte) 0xa6, + (byte) 0x67, (byte) 0xa6, (byte) 0xfd, (byte) 0x02, (byte) 0x41, (byte) 0x00, + (byte) 0x89, (byte) 0x72, (byte) 0x3e, (byte) 0xb0, (byte) 0x90, (byte) 0xfd, + (byte) 0x4c, (byte) 0x0e, (byte) 0xd6, (byte) 0x13, (byte) 0x63, (byte) 0xcb, + (byte) 0xed, (byte) 0x38, (byte) 0x88, (byte) 0xb6, (byte) 0x79, (byte) 0xc4, + (byte) 0x33, (byte) 0x6c, (byte) 0xf6, (byte) 0xf8, (byte) 0xd8, (byte) 0xd0, + (byte) 0xbf, (byte) 0x9d, (byte) 0x35, (byte) 0xac, (byte) 0x69, (byte) 0xd2, + (byte) 0x2b, (byte) 0xc1, (byte) 0xf9, (byte) 0x24, (byte) 0x7b, (byte) 0xce, + (byte) 0xcd, (byte) 0xcb, (byte) 0xa7, (byte) 0xb2, (byte) 0x7a, (byte) 0x0a, + (byte) 0x27, (byte) 0x19, (byte) 0xc9, (byte) 0xaf, (byte) 0x0d, (byte) 0x21, + (byte) 0x89, (byte) 0x88, (byte) 0x7c, (byte) 0xad, (byte) 0x9e, (byte) 0x8d, + (byte) 0x47, (byte) 0x6d, (byte) 0x3f, (byte) 0xce, (byte) 0x7b, (byte) 0xa1, + (byte) 0x74, (byte) 0xf1, (byte) 0xa0, (byte) 0xa1, (byte) 0x02, (byte) 0x41, + (byte) 0x00, (byte) 0xd9, (byte) 0xa8, (byte) 0xf5, (byte) 0xfe, (byte) 0xce, + (byte) 0xe6, (byte) 0x77, (byte) 0x6b, (byte) 0xfe, (byte) 0x2d, (byte) 0xe0, + (byte) 0x1e, (byte) 0xb6, (byte) 0x2e, (byte) 0x12, (byte) 0x4e, (byte) 0x40, + (byte) 0xaf, (byte) 0x6a, (byte) 0x7b, (byte) 0x37, (byte) 0x49, (byte) 0x2a, + (byte) 0x96, (byte) 0x25, (byte) 0x83, (byte) 0x49, (byte) 0xd4, (byte) 0x0c, + (byte) 0xc6, (byte) 0x78, (byte) 0x25, (byte) 0x24, (byte) 0x90, (byte) 0x90, + (byte) 0x06, (byte) 0x15, (byte) 0x9e, (byte) 0xfe, (byte) 0xf9, (byte) 0xdf, + (byte) 0x5b, (byte) 0xf3, (byte) 0x7e, (byte) 0x38, (byte) 0x70, (byte) 0xeb, + (byte) 0x57, (byte) 0xd0, (byte) 0xd9, (byte) 0xa7, (byte) 0x0e, (byte) 0x14, + (byte) 0xf7, (byte) 0x95, (byte) 0x68, (byte) 0xd5, (byte) 0xc8, (byte) 0xab, + (byte) 0x9d, (byte) 0x3a, (byte) 0x2b, (byte) 0x51, (byte) 0xf9, (byte) 0x02, + (byte) 0x41, (byte) 0x00, (byte) 0x96, (byte) 0xdf, (byte) 0xe9, (byte) 0x67, + (byte) 0x6c, (byte) 0xdc, (byte) 0x90, (byte) 0x14, (byte) 0xb4, (byte) 0x1d, + (byte) 0x22, (byte) 0x33, (byte) 0x4a, (byte) 0x31, (byte) 0xc1, (byte) 0x9d, + (byte) 0x2e, (byte) 0xff, (byte) 0x9a, (byte) 0x2a, (byte) 0x95, (byte) 0x4b, + (byte) 0x27, (byte) 0x74, (byte) 0xcb, (byte) 0x21, (byte) 0xc3, (byte) 0xd2, + (byte) 0x0b, (byte) 0xb2, (byte) 0x46, (byte) 0x87, (byte) 0xf8, (byte) 0x28, + (byte) 0x01, (byte) 0x8b, (byte) 0xd8, (byte) 0xb9, (byte) 0x4b, (byte) 0xcd, + (byte) 0x9a, (byte) 0x96, (byte) 0x41, (byte) 0x0e, (byte) 0x36, (byte) 0x6d, + (byte) 0x40, (byte) 0x42, (byte) 0xbc, (byte) 0xd9, (byte) 0xd3, (byte) 0x7b, + (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1, + (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51 + }; + public static final PrivateKey RSA_KEY1 = loadPrivateRSAKey(FAKE_RSA_KEY_1); + + private static X509Certificate loadCertificate(String blob) { + try { + final CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); + InputStream stream = new ByteArrayInputStream(blob.getBytes(StandardCharsets.UTF_8)); + + return (X509Certificate) certFactory.generateCertificate(stream); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + private static PrivateKey loadPrivateRSAKey(byte[] fakeKey) { + try { + KeyFactory kf = KeyFactory.getInstance("RSA"); + return kf.generatePrivate(new PKCS8EncodedKeySpec(fakeKey)); + } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { + return null; + } + } +} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 4185189f50..d3dc8faadd 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -29,6 +29,9 @@ import android.net.wifi.WifiConfiguration.Status; import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.TxPacketCountListener; import android.net.wifi.WifiManager.WifiLock; +import android.net.wifi.hotspot2.PasspointConfiguration; +import android.net.wifi.hotspot2.pps.Credential; +import android.net.wifi.hotspot2.pps.HomeSp; import android.os.SystemClock; import android.provider.Settings; import android.test.AndroidTestCase; @@ -38,6 +41,8 @@ import com.android.compatibility.common.util.WifiConfigCreator; import java.net.HttpURLConnection; import java.net.URL; +import java.security.MessageDigest; +import java.security.cert.X509Certificate; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -543,4 +548,130 @@ public class WifiManagerTest extends AndroidTestCase { } assertTrue(i < 15); } + + /** + * Verify Passpoint configuration management APIs (add, remove, get) for a Passpoint + * configuration with an user credential. + * + * @throws Exception + */ + public void testAddPasspointConfigWithUserCredential() throws Exception { + testAddPasspointConfig(generatePasspointConfig(generateUserCredential())); + } + + /** + * Verify Passpoint configuration management APIs (add, remove, get) for a Passpoint + * configuration with a certificate credential. + * + * @throws Exception + */ + public void testAddPasspointConfigWithCertCredential() throws Exception { + testAddPasspointConfig(generatePasspointConfig(generateCertCredential())); + } + + /** + * Verify Passpoint configuration management APIs (add, remove, get) for a Passpoint + * configuration with a SIm credential. + * + * @throws Exception + */ + public void testAddPasspointConfigWithSimCredential() throws Exception { + testAddPasspointConfig(generatePasspointConfig(generateSimCredential())); + } + + /** + * Helper function for generating a {@link PasspointConfiguration} for testing. + * + * @return {@link PasspointConfiguration} + */ + private PasspointConfiguration generatePasspointConfig(Credential credential) { + PasspointConfiguration config = new PasspointConfiguration(); + config.setCredential(credential); + + // Setup HomeSp. + HomeSp homeSp = new HomeSp(); + homeSp.setFqdn("Test.com"); + homeSp.setFriendlyName("Test Provider"); + config.setHomeSp(homeSp); + + return config; + } + + /** + * Helper function for generating an user credential for testing. + * + * @return {@link Credential} + */ + private Credential generateUserCredential() { + Credential credential = new Credential(); + credential.setRealm("test.net"); + Credential.UserCredential userCred = new Credential.UserCredential(); + userCred.setEapType(21 /* EAP_TTLS */); + userCred.setUsername("username"); + userCred.setPassword("password"); + userCred.setNonEapInnerMethod("PAP"); + credential.setUserCredential(userCred); + credential.setCaCertificate(FakeKeys.CA_CERT0); + return credential; + } + + /** + * Helper function for generating a certificate credential for testing. + * + * @return {@link Credential} + */ + private Credential generateCertCredential() throws Exception { + Credential credential = new Credential(); + credential.setRealm("test.net"); + Credential.CertificateCredential certCredential = new Credential.CertificateCredential(); + certCredential.setCertType("x509v3"); + certCredential.setCertSha256Fingerprint( + MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded())); + credential.setCertCredential(certCredential); + credential.setCaCertificate(FakeKeys.CA_CERT0); + credential.setClientCertificateChain(new X509Certificate[] {FakeKeys.CLIENT_CERT}); + credential.setClientPrivateKey(FakeKeys.RSA_KEY1); + return credential; + } + + /** + * Helper function for generating a SIM credential for testing. + * + * @return {@link Credential} + */ + private Credential generateSimCredential() throws Exception { + Credential credential = new Credential(); + credential.setRealm("test.net"); + Credential.SimCredential simCredential = new Credential.SimCredential(); + simCredential.setImsi("1234*"); + simCredential.setEapType(18 /* EAP_SIM */); + credential.setSimCredential(simCredential); + return credential; + } + + /** + * Helper function verifying Passpoint configuration management APIs (add, remove, get) for + * a given configuration. + * + * @param config The configuration to test with + */ + private void testAddPasspointConfig(PasspointConfiguration config) throws Exception { + assertTrue(mWifiManager.addOrUpdatePasspointConfiguration(config)); + + // Certificates and keys will be set to null after it is installed to the KeyStore by + // WifiManager. Reset them in the expected config so that it can be used to compare + // against the retrieved config. + config.getCredential().setCaCertificate(null); + config.getCredential().setClientCertificateChain(null); + config.getCredential().setClientPrivateKey(null); + + // Retrieve the configuration and verify it. + List configList = mWifiManager.getPasspointConfigurations(); + assertEquals(1, configList.size()); + assertEquals(config, configList.get(0)); + + // Remove the configuration and verify no installed configuration. + assertTrue(mWifiManager.removePasspointConfiguration(config.getHomeSp().getFqdn())); + assertTrue(mWifiManager.getPasspointConfigurations().isEmpty()); + } } From 24a0a8e64347b1d254e61c89a9be5e10169a4f76 Mon Sep 17 00:00:00 2001 From: Peter Qiu Date: Mon, 27 Feb 2017 15:23:06 -0800 Subject: [PATCH 0312/1109] wifi: add CTS tests for Passpoint parsing APIs Added a test for PPS MO (PerProviderSubscription Management Object) tree parsing API and a test for Release 1 installation file parsing API. Bug: 35756298 Test: run the newly added PpsMoParserTest and ConfigParserTest Change-Id: I6da40bef9609830afb80d8562e5bfb051920b541 --- .../net/assets/HSR1ProfileWithCACert.base64 | 85 ++++ .../net/assets/PerProviderSubscription.xml | 399 ++++++++++++++++++ .../net/wifi/cts/ConfigParserTest.java | 114 +++++ .../android/net/wifi/cts/PpsMoParserTest.java | 194 +++++++++ 4 files changed, 792 insertions(+) create mode 100644 tests/cts/net/assets/HSR1ProfileWithCACert.base64 create mode 100644 tests/cts/net/assets/PerProviderSubscription.xml create mode 100644 tests/cts/net/src/android/net/wifi/cts/ConfigParserTest.java create mode 100644 tests/cts/net/src/android/net/wifi/cts/PpsMoParserTest.java diff --git a/tests/cts/net/assets/HSR1ProfileWithCACert.base64 b/tests/cts/net/assets/HSR1ProfileWithCACert.base64 new file mode 100644 index 0000000000..995963d2b4 --- /dev/null +++ b/tests/cts/net/assets/HSR1ProfileWithCACert.base64 @@ -0,0 +1,85 @@ +Q29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5PXtib3VuZGFyeX0KQ29udGVu +dC1UcmFuc2Zlci1FbmNvZGluZzogYmFzZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBh +cHBsaWNhdGlvbi94LXBhc3Nwb2ludC1wcm9maWxlCkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6 +IGJhc2U2NAoKUEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29n +SUR4V1pYSkVWRVErTVM0eVBDOVdaWEpFVkVRKwpDaUFnUEU1dlpHVStDaUFnSUNBOFRtOWtaVTVo +YldVK1VHVnlVSEp2ZG1sa1pYSlRkV0p6WTNKcGNIUnBiMjQ4TDA1dlpHVk9ZVzFsClBnb2dJQ0Fn +UEZKVVVISnZjR1Z5ZEdsbGN6NEtJQ0FnSUNBZ1BGUjVjR1UrQ2lBZ0lDQWdJQ0FnUEVSRVJrNWhi +V1UrZFhKdU9uZG0KWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZ +M0pwY0hScGIyNDZNUzR3UEM5RVJFWk9ZVzFsUGdvZwpJQ0FnSUNBOEwxUjVjR1UrQ2lBZ0lDQThM +MUpVVUhKdmNHVnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVSth +VEF3TVR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFRt +RnRaVDVJYjIxbFUxQTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lD +QWdJQ0FnUEU1dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdApaVHd2VG05a1pVNWhiV1UrQ2lBZ0lD +QWdJQ0FnSUNBOFZtRnNkV1UrUTJWdWRIVnllU0JJYjNWelpUd3ZWbUZzZFdVK0NpQWdJQ0FnCklD +QWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcx +bFBrWlJSRTQ4TDA1dlpHVk8KWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBtMXBOaTVqYnk1 +MWF6d3ZWbUZzZFdVK0NpQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZwpJQ0FnSUNBZ0lEeE9iMlJsUGdv +Z0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsSnZZVzFwYm1kRGIyNXpiM0owYVhWdFQwazhMMDV2 +ClpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUGpFeE1qSXpNeXcwTkRVMU5qWThMMVpo +YkhWbFBnb2dJQ0FnSUNBZ0lEd3YKVG05a1pUNEtJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0E4 +VG05a1pUNEtJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStRM0psWkdWdQpkR2xoYkR3dlRtOWtaVTVo +YldVK0NpQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1VtVmhi +RzA4CkwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBuTm9ZV3RsYmk1emRHbHlj +bVZrTG1OdmJUd3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9i +MlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsVnpaWEp1WVcxbApVR0Z6YzNkdmNtUThM +MDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2Iy +UmxUbUZ0ClpUNVZjMlZ5Ym1GdFpUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lX +eDFaVDVxWVcxbGN6d3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lD +QWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxCaApjM04zYjNKa1BD +OU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbGx0T1hWYVJFRjNUbmM5UFR3 +dlZtRnNkV1UrCkNpQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0 +S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWwKUGtWQlVFMWxkR2h2WkR3dlRtOWtaVTVoYldV +K0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0FnSUR4TwpiMlJsVG1G +dFpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBOFZtRnNkV1Ur +TWpFOEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lDQWdJQ0Fn +SUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeE8KYjJSbFRtRnRaVDVKYm01bGNrMWxkR2h2 +WkR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQazFUTFVOSQpRVkF0 +VmpJOEwxWmhiSFZsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThM +MDV2WkdVK0NpQWdJQ0FnCklDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJ +Q0FnSUNBZ1BFNXZaR1ZPWVcxbFBrUnBaMmwwWVd4RFpYSjAKYVdacFkyRjBaVHd2VG05a1pVNWhi +V1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbApQ +a05sY25ScFptbGpZWFJsVkhsd1pUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lX +eDFaVDU0TlRBNWRqTThMMVpoCmJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lD +QWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNURaWEowVTBoQk1q +VTJSbWx1WjJWeWNISnBiblE4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdV +KwpNV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpG +bU1XWXhaakZtTVdZeFpqRm1NV1l4ClpqRm1NV1l4Wmp3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0FnSUNB +OEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWcKSUR4T2IyUmxQZ29nSUNB +Z0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxOSlRUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4 +VG05awpaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBrbE5VMGs4TDA1dlpHVk9ZVzFs +UGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzCmRXVSthVzF6YVR3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0Fn +SUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWcKSUNBZ0lDQWdQRTV2 +WkdWT1lXMWxQa1ZCVUZSNWNHVThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBOFZtRnNk +V1UrTWpROApMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEd3ZU +bTlrWlQ0S0lDQWdJQ0FnUEM5T2IyUmxQZ29nCklDQWdQQzlPYjJSbFBnb2dJRHd2VG05a1pUNEtQ +QzlOWjIxMFZISmxaVDRLCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94 +LXg1MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRMUzFD +UlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlowbEtR +VWxNYkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQwSm5U +bFlLUWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYyaGpU +azFxV1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZrRm5V +VEJGZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtOblMw +TkJVVVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIxV1ZY +TldkVzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJOQ01T +dHZSMWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpVClJV +RkRaV1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwyUzJo +U1FqZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dyVUdK +ck1IVjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIzUWtz +M2FFUTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNLMGxh +CmFYQllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFVRzVX +TTJreGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNXVVZH +U1hkWU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJOMDFF +YlVGR1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RWSkJk +MFJuCldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldVUldV +akJVUWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNXaDJZ +MDVCVVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQwaEZD +amxIUlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5VVNY +ZEpWV00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5KT1Ew +OTBhWE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhsT2JX +MVdUQW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhnMmVF +MXVWR3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxXYUhw +aFNFb3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5WnpG +S1VDdHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQTDNS +a1RrNTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJKUmts +RFFWUkZMUzB0TFMwSwotLXtib3VuZGFyeX0tLQo= diff --git a/tests/cts/net/assets/PerProviderSubscription.xml b/tests/cts/net/assets/PerProviderSubscription.xml new file mode 100644 index 0000000000..7f2d95de95 --- /dev/null +++ b/tests/cts/net/assets/PerProviderSubscription.xml @@ -0,0 +1,399 @@ + + 1.2 + + PerProviderSubscription + + + urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0 + + + + UpdateIdentifier + 12 + + + i001 + + HomeSP + + FriendlyName + Century House + + + FQDN + mi6.co.uk + + + RoamingConsortiumOI + 112233,445566 + + + IconURL + icon.test.com + + + NetworkID + + n001 + + SSID + TestSSID + + + HESSID + 12345678 + + + + n002 + + SSID + NullHESSID + + + + + HomeOIList + + h001 + + HomeOI + 11223344 + + + HomeOIRequired + true + + + + h002 + + HomeOI + 55667788 + + + HomeOIRequired + false + + + + + OtherHomePartners + + o001 + + FQDN + other.fqdn.com + + + + + + Credential + + CreationDate + 2016-01-01T10:00:00Z + + + ExpirationDate + 2016-02-01T10:00:00Z + + + Realm + shaken.stirred.com + + + CheckAAAServerCertStatus + true + + + UsernamePassword + + Username + james + + + Password + Ym9uZDAwNw== + + + MachineManaged + true + + + SoftTokenApp + TestApp + + + AbleToShare + true + + + EAPMethod + + EAPType + 21 + + + InnerMethod + MS-CHAP-V2 + + + + + DigitalCertificate + + CertificateType + x509v3 + + + CertSHA256Fingerprint + 1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f + + + + SIM + + IMSI + imsi + + + EAPType + 24 + + + + + Policy + + PreferredRoamingPartnerList + + p001 + + FQDN_Match + test1.fqdn.com,exactMatch + + + Priority + 127 + + + Country + us,fr + + + + p002 + + FQDN_Match + test2.fqdn.com,includeSubdomains + + + Priority + 200 + + + Country + * + + + + + MinBackhaulThreshold + + m001 + + NetworkType + home + + + DLBandwidth + 23412 + + + ULBandwidth + 9823 + + + + m002 + + NetworkType + roaming + + + DLBandwidth + 9271 + + + ULBandwidth + 2315 + + + + + PolicyUpdate + + UpdateInterval + 120 + + + UpdateMethod + OMA-DM-ClientInitiated + + + Restriction + HomeSP + + + URI + policy.update.com + + + UsernamePassword + + Username + updateUser + + + Password + updatePass + + + + TrustRoot + + CertURL + update.cert.com + + + CertSHA256Fingerprint + 1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f + + + + + SPExclusionList + + s001 + + SSID + excludeSSID + + + + + RequiredProtoPortTuple + + r001 + + IPProtocol + 12 + + + PortNumber + 34,92,234 + + + + + MaximumBSSLoadValue + 23 + + + + CredentialPriority + 99 + + + AAAServerTrustRoot + + a001 + + CertURL + server1.trust.root.com + + + CertSHA256Fingerprint + 1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f + + + + + SubscriptionUpdate + + UpdateInterval + 120 + + + UpdateMethod + SSP-ClientInitiated + + + Restriction + RoamingPartner + + + URI + subscription.update.com + + + UsernamePassword + + Username + subscriptionUser + + + Password + subscriptionPass + + + + TrustRoot + + CertURL + subscription.update.cert.com + + + CertSHA256Fingerprint + 1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f + + + + + SubscriptionParameter + + CreationDate + 2016-02-01T10:00:00Z + + + ExpirationDate + 2016-03-01T10:00:00Z + + + TypeOfSubscription + Gold + + + UsageLimits + + DataLimit + 921890 + + + StartDate + 2016-12-01T10:00:00Z + + + TimeLimit + 120 + + + UsageTimePeriod + 99910 + + + + + + diff --git a/tests/cts/net/src/android/net/wifi/cts/ConfigParserTest.java b/tests/cts/net/src/android/net/wifi/cts/ConfigParserTest.java new file mode 100644 index 0000000000..52ed2a6d73 --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/cts/ConfigParserTest.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2017 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.wifi.cts; + +import android.net.wifi.hotspot2.ConfigParser; +import android.net.wifi.hotspot2.PasspointConfiguration; +import android.net.wifi.hotspot2.pps.Credential; +import android.net.wifi.hotspot2.pps.HomeSp; +import android.test.AndroidTestCase; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Arrays; + +/** + * CTS tests for Hotspot 2.0 Release 1 installation file parsing API. + */ +public class ConfigParserTest extends AndroidTestCase { + /** + * Hotspot 2.0 Release 1 installation file that contains a Passpoint profile and a + * CA (Certificate Authority) X.509 certificate {@link FakeKeys#CA_CERT0}. + */ + private static final String PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT = + "assets/HSR1ProfileWithCACert.base64"; + + /** + * Read the content of the given resource file into a String. + * + * @param filename String name of the file + * @return String + * @throws IOException + */ + private String loadResourceFile(String filename) throws IOException { + InputStream in = getClass().getClassLoader().getResourceAsStream(filename); + BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + StringBuilder builder = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + builder.append(line).append("\n"); + } + + return builder.toString(); + } + + /** + * Generate a {@link PasspointConfiguration} that matches the configuration specified in the + * XML file {@link #PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT}. + * + * @return {@link PasspointConfiguration} + */ + private PasspointConfiguration generateConfigurationFromProfile() { + PasspointConfiguration config = new PasspointConfiguration(); + + // HomeSP configuration. + HomeSp homeSp = new HomeSp(); + homeSp.setFriendlyName("Century House"); + homeSp.setFqdn("mi6.co.uk"); + homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L}); + config.setHomeSp(homeSp); + + // Credential configuration. + Credential credential = new Credential(); + credential.setRealm("shaken.stirred.com"); + Credential.UserCredential userCredential = new Credential.UserCredential(); + userCredential.setUsername("james"); + userCredential.setPassword("Ym9uZDAwNw=="); + userCredential.setEapType(21); + userCredential.setNonEapInnerMethod("MS-CHAP-V2"); + credential.setUserCredential(userCredential); + Credential.CertificateCredential certCredential = new Credential.CertificateCredential(); + certCredential.setCertType("x509v3"); + byte[] certSha256Fingerprint = new byte[32]; + Arrays.fill(certSha256Fingerprint, (byte)0x1f); + certCredential.setCertSha256Fingerprint(certSha256Fingerprint); + credential.setCertCredential(certCredential); + Credential.SimCredential simCredential = new Credential.SimCredential(); + simCredential.setImsi("imsi"); + simCredential.setEapType(24); + credential.setSimCredential(simCredential); + credential.setCaCertificate(FakeKeys.CA_CERT0); + config.setCredential(credential); + return config; + } + + /** + * Verify a valid installation file is parsed successfully with the matching contents. + * + * @throws Exception + */ + public void testParseConfigFile() throws Exception { + String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT); + PasspointConfiguration expectedConfig = generateConfigurationFromProfile(); + PasspointConfiguration actualConfig = + ConfigParser.parsePasspointConfig( + "application/x-wifi-config", configStr.getBytes()); + assertTrue(actualConfig.equals(expectedConfig)); + } +} \ No newline at end of file diff --git a/tests/cts/net/src/android/net/wifi/cts/PpsMoParserTest.java b/tests/cts/net/src/android/net/wifi/cts/PpsMoParserTest.java new file mode 100644 index 0000000000..5eccc0d0bb --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/cts/PpsMoParserTest.java @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2017 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.wifi.cts; + +import android.net.wifi.hotspot2.PasspointConfiguration; +import android.net.wifi.hotspot2.omadm.PpsMoParser; +import android.net.wifi.hotspot2.pps.Credential; +import android.net.wifi.hotspot2.pps.HomeSp; +import android.net.wifi.hotspot2.pps.Policy; +import android.net.wifi.hotspot2.pps.UpdateParameter; +import android.test.AndroidTestCase; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * CTS tests for PPS MO (PerProviderSubscription Management Object) XML string parsing API. + */ +public class PpsMoParserTest extends AndroidTestCase { + private static final String PPS_MO_XML_FILE = "assets/PerProviderSubscription.xml"; + + /** + * Read the content of the given resource file into a String. + * + * @param filename String name of the file + * @return String + * @throws IOException + */ + private String loadResourceFile(String filename) throws IOException { + InputStream in = getClass().getClassLoader().getResourceAsStream(filename); + BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + StringBuilder builder = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + builder.append(line).append("\n"); + } + return builder.toString(); + } + + /** + * Generate a {@link PasspointConfiguration} that matches the configuration specified in the + * XML file {@link #PPS_MO_XML_FILE}. + * + * @return {@link PasspointConfiguration} + */ + private PasspointConfiguration generateConfigurationFromPPSMOTree() throws Exception { + DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + byte[] certFingerprint = new byte[32]; + Arrays.fill(certFingerprint, (byte) 0x1f); + + PasspointConfiguration config = new PasspointConfiguration(); + config.setUpdateIdentifier(12); + config.setCredentialPriority(99); + + // AAA Server trust root. + Map trustRootCertList = new HashMap<>(); + trustRootCertList.put("server1.trust.root.com", certFingerprint); + config.setTrustRootCertList(trustRootCertList); + + // Subscription update. + UpdateParameter subscriptionUpdate = new UpdateParameter(); + subscriptionUpdate.setUpdateIntervalInMinutes(120); + subscriptionUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SSP); + subscriptionUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER); + subscriptionUpdate.setServerUri("subscription.update.com"); + subscriptionUpdate.setUsername("subscriptionUser"); + subscriptionUpdate.setBase64EncodedPassword("subscriptionPass"); + subscriptionUpdate.setTrustRootCertUrl("subscription.update.cert.com"); + subscriptionUpdate.setTrustRootCertSha256Fingerprint(certFingerprint); + config.setSubscriptionUpdate(subscriptionUpdate); + + // Subscription parameters. + config.setSubscriptionCreationTimeInMs(format.parse("2016-02-01T10:00:00Z").getTime()); + config.setSubscriptionExpirationTimeInMs(format.parse("2016-03-01T10:00:00Z").getTime()); + config.setSubscriptionType("Gold"); + config.setUsageLimitDataLimit(921890); + config.setUsageLimitStartTimeInMs(format.parse("2016-12-01T10:00:00Z").getTime()); + config.setUsageLimitTimeLimitInMinutes(120); + config.setUsageLimitUsageTimePeriodInMinutes(99910); + + // HomeSP configuration. + HomeSp homeSp = new HomeSp(); + homeSp.setFriendlyName("Century House"); + homeSp.setFqdn("mi6.co.uk"); + homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L}); + homeSp.setIconUrl("icon.test.com"); + Map homeNetworkIds = new HashMap<>(); + homeNetworkIds.put("TestSSID", 0x12345678L); + homeNetworkIds.put("NullHESSID", null); + homeSp.setHomeNetworkIds(homeNetworkIds); + homeSp.setMatchAllOis(new long[] {0x11223344}); + homeSp.setMatchAnyOis(new long[] {0x55667788}); + homeSp.setOtherHomePartners(new String[] {"other.fqdn.com"}); + config.setHomeSp(homeSp); + + // Credential configuration. + Credential credential = new Credential(); + credential.setCreationTimeInMs(format.parse("2016-01-01T10:00:00Z").getTime()); + credential.setExpirationTimeInMs(format.parse("2016-02-01T10:00:00Z").getTime()); + credential.setRealm("shaken.stirred.com"); + credential.setCheckAaaServerCertStatus(true); + Credential.UserCredential userCredential = new Credential.UserCredential(); + userCredential.setUsername("james"); + userCredential.setPassword("Ym9uZDAwNw=="); + userCredential.setMachineManaged(true); + userCredential.setSoftTokenApp("TestApp"); + userCredential.setAbleToShare(true); + userCredential.setEapType(21); + userCredential.setNonEapInnerMethod("MS-CHAP-V2"); + credential.setUserCredential(userCredential); + Credential.CertificateCredential certCredential = new Credential.CertificateCredential(); + certCredential.setCertType("x509v3"); + certCredential.setCertSha256Fingerprint(certFingerprint); + credential.setCertCredential(certCredential); + Credential.SimCredential simCredential = new Credential.SimCredential(); + simCredential.setImsi("imsi"); + simCredential.setEapType(24); + credential.setSimCredential(simCredential); + config.setCredential(credential); + + // Policy configuration. + Policy policy = new Policy(); + List preferredRoamingPartnerList = new ArrayList<>(); + Policy.RoamingPartner partner1 = new Policy.RoamingPartner(); + partner1.setFqdn("test1.fqdn.com"); + partner1.setFqdnExactMatch(true); + partner1.setPriority(127); + partner1.setCountries("us,fr"); + Policy.RoamingPartner partner2 = new Policy.RoamingPartner(); + partner2.setFqdn("test2.fqdn.com"); + partner2.setFqdnExactMatch(false); + partner2.setPriority(200); + partner2.setCountries("*"); + preferredRoamingPartnerList.add(partner1); + preferredRoamingPartnerList.add(partner2); + policy.setPreferredRoamingPartnerList(preferredRoamingPartnerList); + policy.setMinHomeDownlinkBandwidth(23412); + policy.setMinHomeUplinkBandwidth(9823); + policy.setMinRoamingDownlinkBandwidth(9271); + policy.setMinRoamingUplinkBandwidth(2315); + policy.setExcludedSsidList(new String[] {"excludeSSID"}); + Map requiredProtoPortMap = new HashMap<>(); + requiredProtoPortMap.put(12, "34,92,234"); + policy.setRequiredProtoPortMap(requiredProtoPortMap); + policy.setMaximumBssLoadValue(23); + UpdateParameter policyUpdate = new UpdateParameter(); + policyUpdate.setUpdateIntervalInMinutes(120); + policyUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM); + policyUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP); + policyUpdate.setServerUri("policy.update.com"); + policyUpdate.setUsername("updateUser"); + policyUpdate.setBase64EncodedPassword("updatePass"); + policyUpdate.setTrustRootCertUrl("update.cert.com"); + policyUpdate.setTrustRootCertSha256Fingerprint(certFingerprint); + policy.setPolicyUpdate(policyUpdate); + config.setPolicy(policy); + return config; + } + + /** + * Parse and verify all supported fields under PPS MO tree. + * + * @throws Exception + */ + public void testParsePPSMOTree() throws Exception { + String ppsMoTree = loadResourceFile(PPS_MO_XML_FILE); + PasspointConfiguration expectedConfig = generateConfigurationFromPPSMOTree(); + PasspointConfiguration actualConfig = PpsMoParser.parseMoText(ppsMoTree); + assertTrue(actualConfig.equals(expectedConfig)); + } +} From 5dc4e9b091bbd1c5a7dc830cbf3a26136a8e65f6 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Mon, 27 Feb 2017 13:19:22 -0800 Subject: [PATCH 0313/1109] [AWARE] Initial CTS: availability API + broadcast Initial CTS tests for Wi-Fi Aware: - Add CTS test class for Wi-Fi Aware - Setup/initialize - Test the availablity API + broadcast Bug: 30556108 Test: builds, CTS runs (test fails as expected) Change-Id: Ibbc58c3ed7a9ad7312864d038fd34c7202222e82 --- .../net/wifi/aware/cts/SingleDeviceTest.java | 152 ++++++++++++++++++ .../android/net/wifi/aware/cts/TestUtils.java | 36 +++++ 2 files changed, 188 insertions(+) create mode 100644 tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java create mode 100644 tests/cts/net/src/android/net/wifi/aware/cts/TestUtils.java diff --git a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java new file mode 100644 index 0000000000..536e885c3a --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2017 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.wifi.aware.cts; + +import static android.net.wifi.aware.cts.TestUtils.shouldTestWifiAware; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.wifi.WifiManager; +import android.net.wifi.aware.Characteristics; +import android.net.wifi.aware.WifiAwareManager; +import android.test.AndroidTestCase; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +/** + * Wi-Fi Aware CTS test suite: single device testing. Performs tests on a single + * device to validate Wi-Fi Aware. + */ +public class SingleDeviceTest extends AndroidTestCase { + static private final String TAG = "WifiAwareCtsTests"; + + // wait for Wi-Fi Aware to become available + static private final int WAIT_FOR_AWARE_CHANGE_SECS = 10; + + private WifiAwareManager mWifiAwareManager; + private WifiManager mWifiManager; + private WifiManager.WifiLock mWifiLock; + + private class WifiAwareBroadcastReceiver extends BroadcastReceiver { + private CountDownLatch mBlocker = new CountDownLatch(1); + + @Override + public void onReceive(Context context, Intent intent) { + if (WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED.equals(intent.getAction())) { + mBlocker.countDown(); + } + } + + boolean waitForStateChange() throws InterruptedException { + return mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS); + } + }; + + @Override + protected void setUp() throws Exception { + super.setUp(); + + if (!shouldTestWifiAware(getContext())) { + return; + } + + mWifiAwareManager = (WifiAwareManager) getContext().getSystemService( + Context.WIFI_AWARE_SERVICE); + assertNotNull("Wi-Fi Aware Manager", mWifiAwareManager); + + mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); + assertNotNull("Wi-Fi Manager", mWifiManager); + mWifiLock = mWifiManager.createWifiLock(TAG); + mWifiLock.acquire(); + if (!mWifiManager.isWifiEnabled()) { + mWifiManager.setWifiEnabled(true); + } + + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED); + WifiAwareBroadcastReceiver receiver = new WifiAwareBroadcastReceiver(); + mContext.registerReceiver(receiver, intentFilter); + if (!mWifiAwareManager.isAvailable()) { + assertTrue("Timeout waiting for Wi-Fi Aware to change status", + receiver.waitForStateChange()); + assertTrue("Wi-Fi Aware is not available (should be)", mWifiAwareManager.isAvailable()); + } + } + + @Override + protected void tearDown() throws Exception { + if (!shouldTestWifiAware(getContext())) { + super.tearDown(); + return; + } + + super.tearDown(); + } + + /** + * Validate: + * - Characteristics are available + * - Characteristics values are legitimate. Not in the CDD. However, the tested values are + * based on the Wi-Fi Aware protocol. + */ + public void testCharacteristics() { + if (!shouldTestWifiAware(getContext())) { + return; + } + + Characteristics characteristics = mWifiAwareManager.getCharacteristics(); + assertNotNull("Wi-Fi Aware characteristics are null", characteristics); + assertEquals("Service Name Length", characteristics.getMaxServiceNameLength(), 255); + assertEquals("Service Specific Information Length", + characteristics.getMaxServiceSpecificInfoLength(), 255); + assertEquals("Match Filter Length", characteristics.getMaxMatchFilterLength(), 255); + } + + /** + * Validate that on Wi-Fi Aware availability change we get a broadcast + the API returns + * correct status. + */ + public void testAvailabilityStatusChange() throws Exception { + if (!shouldTestWifiAware(getContext())) { + return; + } + + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED); + + // 1. Disable Wi-Fi + WifiAwareBroadcastReceiver receiver1 = new WifiAwareBroadcastReceiver(); + mContext.registerReceiver(receiver1, intentFilter); + mWifiManager.setWifiEnabled(false); + + assertTrue("Timeout waiting for Wi-Fi Aware to change status", + receiver1.waitForStateChange()); + assertFalse("Wi-Fi Aware is available (should not be)", mWifiAwareManager.isAvailable()); + + // 2. Enable Wi-Fi + WifiAwareBroadcastReceiver receiver2 = new WifiAwareBroadcastReceiver(); + mContext.registerReceiver(receiver2, intentFilter); + mWifiManager.setWifiEnabled(true); + + assertTrue("Timeout waiting for Wi-Fi Aware to change status", + receiver2.waitForStateChange()); + assertTrue("Wi-Fi Aware is not available (should be)", mWifiAwareManager.isAvailable()); + } +} diff --git a/tests/cts/net/src/android/net/wifi/aware/cts/TestUtils.java b/tests/cts/net/src/android/net/wifi/aware/cts/TestUtils.java new file mode 100644 index 0000000000..ff9a5d2118 --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/aware/cts/TestUtils.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2017 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.wifi.aware.cts; + +import android.content.Context; +import android.content.pm.PackageManager; + +/** + * Test utilities for Wi-Fi Aware CTS test suite. + */ +public class TestUtils { + static final String TAG = "WifiAwareCtsTests"; + + /** + * Returns a flag indicating whether or not Wi-Fi Aware should be tested. Wi-Fi Aware + * should be tested if the feature is supported on the current device. + */ + public static boolean shouldTestWifiAware(Context context) { + final PackageManager pm = context.getPackageManager(); + return pm.hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE); + } +} From 08a2758524274446fc45631aef1026af423589d8 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Tue, 28 Feb 2017 18:00:47 -0800 Subject: [PATCH 0314/1109] [AWARE] CTS for attaching to session + MAC address Add CTS to verify initial session attach: - Basic attach - Attach with identity callback: use to verify MAC address change on subsequent attach. Bug: 30556108 Test: CTS tests pass/fail per expectations Change-Id: I8c2d29be81bef600a2c9eac99868326473d72b6e --- .../net/wifi/aware/cts/SingleDeviceTest.java | 170 +++++++++++++++++- .../android/net/wifi/aware/cts/TestUtils.java | 37 +++- 2 files changed, 198 insertions(+), 9 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java index 536e885c3a..bea4500855 100644 --- a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java +++ b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java @@ -16,17 +16,22 @@ package android.net.wifi.aware.cts; -import static android.net.wifi.aware.cts.TestUtils.shouldTestWifiAware; - import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.wifi.WifiManager; +import android.net.wifi.aware.AttachCallback; import android.net.wifi.aware.Characteristics; +import android.net.wifi.aware.IdentityChangedListener; import android.net.wifi.aware.WifiAwareManager; +import android.net.wifi.aware.WifiAwareSession; import android.test.AndroidTestCase; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -35,15 +40,20 @@ import java.util.concurrent.TimeUnit; * device to validate Wi-Fi Aware. */ public class SingleDeviceTest extends AndroidTestCase { - static private final String TAG = "WifiAwareCtsTests"; + private static final String TAG = "WifiAwareCtsTests"; // wait for Wi-Fi Aware to become available static private final int WAIT_FOR_AWARE_CHANGE_SECS = 10; + private final Object mLock = new Object(); + private WifiAwareManager mWifiAwareManager; private WifiManager mWifiManager; private WifiManager.WifiLock mWifiLock; + // used to store any WifiAwareSession allocated during tests - will clean-up after tests + private List mSessions = new ArrayList<>(); + private class WifiAwareBroadcastReceiver extends BroadcastReceiver { private CountDownLatch mBlocker = new CountDownLatch(1); @@ -59,11 +69,92 @@ public class SingleDeviceTest extends AndroidTestCase { } }; + private class AttachCallbackTest extends AttachCallback { + static final int ATTACHED = 0; + static final int ATTACH_FAILED = 1; + static final int ERROR = 2; // no callback: timeout, interruption + + private CountDownLatch mBlocker = new CountDownLatch(1); + private int mCallbackCalled = ERROR; // garbage init + private WifiAwareSession mSession = null; + + @Override + public void onAttached(WifiAwareSession session) { + mCallbackCalled = ATTACHED; + mSession = session; + synchronized (mLock) { + mSessions.add(session); + } + mBlocker.countDown(); + } + + @Override + public void onAttachFailed() { + mCallbackCalled = ATTACH_FAILED; + mBlocker.countDown(); + } + + /** + * Waits for any of the callbacks to be called - or an error (timeout, interruption). + * Returns one of the ATTACHED, ATTACH_FAILED, or ERROR values. + */ + int waitForAnyCallback() { + try { + boolean noTimeout = mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS); + if (noTimeout) { + return mCallbackCalled; + } else { + return ERROR; + } + } catch (InterruptedException e) { + return ERROR; + } + } + + /** + * Access the session created by a callback. Only useful to be called after calling + * waitForAnyCallback() and getting the ATTACHED code back. + */ + WifiAwareSession getSession() { + return mSession; + } + } + + private class IdentityChangedListenerTest extends IdentityChangedListener { + private CountDownLatch mBlocker = new CountDownLatch(1); + private byte[] mMac = null; + + @Override + public void onIdentityChanged(byte[] mac) { + mMac = mac; + mBlocker.countDown(); + } + + /** + * Waits for the listener callback to be called - or an error (timeout, interruption). + * Returns true on callback called, false on error (timeout, interruption). + */ + boolean waitForListener() { + try { + return mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS); + } catch (InterruptedException e) { + return false; + } + } + + /** + * Returns the MAC address of the discovery interface supplied to the triggered callback. + */ + byte[] getMac() { + return mMac; + } + } + @Override protected void setUp() throws Exception { super.setUp(); - if (!shouldTestWifiAware(getContext())) { + if (!TestUtils.shouldTestWifiAware(getContext())) { return; } @@ -92,11 +183,19 @@ public class SingleDeviceTest extends AndroidTestCase { @Override protected void tearDown() throws Exception { - if (!shouldTestWifiAware(getContext())) { + if (!TestUtils.shouldTestWifiAware(getContext())) { super.tearDown(); return; } + synchronized (mLock) { + for (WifiAwareSession session : mSessions) { + // no damage from destroying twice (i.e. ok if test cleaned up after itself already) + session.destroy(); + } + mSessions.clear(); + } + super.tearDown(); } @@ -107,7 +206,7 @@ public class SingleDeviceTest extends AndroidTestCase { * based on the Wi-Fi Aware protocol. */ public void testCharacteristics() { - if (!shouldTestWifiAware(getContext())) { + if (!TestUtils.shouldTestWifiAware(getContext())) { return; } @@ -124,7 +223,7 @@ public class SingleDeviceTest extends AndroidTestCase { * correct status. */ public void testAvailabilityStatusChange() throws Exception { - if (!shouldTestWifiAware(getContext())) { + if (!TestUtils.shouldTestWifiAware(getContext())) { return; } @@ -149,4 +248,61 @@ public class SingleDeviceTest extends AndroidTestCase { receiver2.waitForStateChange()); assertTrue("Wi-Fi Aware is not available (should be)", mWifiAwareManager.isAvailable()); } + + /** + * Validate that can attach to Wi-Fi Aware. + */ + public void testAttachNoIdentity() { + if (!TestUtils.shouldTestWifiAware(getContext())) { + return; + } + + AttachCallbackTest attachCb = new AttachCallbackTest(); + mWifiAwareManager.attach(attachCb, null); + int cbCalled = attachCb.waitForAnyCallback(); + assertEquals("Wi-Fi Aware attach", AttachCallbackTest.ATTACHED, cbCalled); + + WifiAwareSession session = attachCb.getSession(); + assertNotNull("Wi-Fi Aware session", session); + + session.destroy(); + } + + /** + * Validate that can attach to Wi-Fi Aware and get identity information. Use the identity + * information to validate that MAC address changes on every attach. + * + * Note: relies on no other entity using Wi-Fi Aware during the CTS test. Since if it is used + * then the attach/destroy will not correspond to enable/disable and will not result in a new + * MAC address being generated. + */ + public void testAttachDiscoveryAddressChanges() { + if (!TestUtils.shouldTestWifiAware(getContext())) { + return; + } + + final int numIterations = 10; + Set macs = new HashSet<>(); + + for (int i = 0; i < numIterations; ++i) { + AttachCallbackTest attachCb = new AttachCallbackTest(); + IdentityChangedListenerTest identityL = new IdentityChangedListenerTest(); + mWifiAwareManager.attach(attachCb, identityL, null); + assertEquals("Wi-Fi Aware attach: iteration " + i, AttachCallbackTest.ATTACHED, + attachCb.waitForAnyCallback()); + assertTrue("Wi-Fi Aware attach: iteration " + i, identityL.waitForListener()); + + WifiAwareSession session = attachCb.getSession(); + assertNotNull("Wi-Fi Aware session: iteration " + i, session); + + byte[] mac = identityL.getMac(); + assertNotNull("Wi-Fi Aware discovery MAC: iteration " + i, mac); + + session.destroy(); + + macs.add(new TestUtils.MacWrapper(mac)); + } + + assertEquals("", numIterations, macs.size()); + } } diff --git a/tests/cts/net/src/android/net/wifi/aware/cts/TestUtils.java b/tests/cts/net/src/android/net/wifi/aware/cts/TestUtils.java index ff9a5d2118..a12c8bb0d2 100644 --- a/tests/cts/net/src/android/net/wifi/aware/cts/TestUtils.java +++ b/tests/cts/net/src/android/net/wifi/aware/cts/TestUtils.java @@ -19,18 +19,51 @@ package android.net.wifi.aware.cts; import android.content.Context; import android.content.pm.PackageManager; +import java.util.Arrays; + /** * Test utilities for Wi-Fi Aware CTS test suite. */ -public class TestUtils { +class TestUtils { static final String TAG = "WifiAwareCtsTests"; /** * Returns a flag indicating whether or not Wi-Fi Aware should be tested. Wi-Fi Aware * should be tested if the feature is supported on the current device. */ - public static boolean shouldTestWifiAware(Context context) { + static boolean shouldTestWifiAware(Context context) { final PackageManager pm = context.getPackageManager(); return pm.hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE); } + + /** + * Wraps a byte[] (MAC address representation). Intended to provide hash and equality operators + * so that the MAC address can be used in containers. + */ + static class MacWrapper { + private byte[] mMac; + + MacWrapper(byte[] mac) { + mMac = mac; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (!(o instanceof MacWrapper)) { + return false; + } + + MacWrapper lhs = (MacWrapper) o; + return Arrays.equals(mMac, lhs.mMac); + } + + @Override + public int hashCode() { + return Arrays.hashCode(mMac); + } + } } From 87b18c3df13e50e30e9faf6df95009d3b7b667cf Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Tue, 6 Dec 2016 09:57:59 -0800 Subject: [PATCH 0315/1109] [CM] CTS tests for requestNetwork APIs Add CTS tests for: - requestNetwork API: test onAvailable - requestNetwork with timeout API: test onUnavailable (failure) Bug: 31399536 Test: CTS tests passing Change-Id: I3565ef375ec90f90b2c76aabee14bf993251eeef --- .../net/cts/ConnectivityManagerTest.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 185ebfa0fc..24871ca156 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -18,6 +18,7 @@ package android.net.cts; import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; +import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import android.app.PendingIntent; import android.content.BroadcastReceiver; @@ -383,6 +384,57 @@ public class ConnectivityManagerTest extends AndroidTestCase { } } + /** + * Exercises the requestNetwork with NetworkCallback API. This checks to + * see if we get a callback for an INTERNET request. + */ + public void testRequestNetworkCallback() { + final TestNetworkCallback callback = new TestNetworkCallback(); + mCm.requestNetwork(new NetworkRequest.Builder() + .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + .build(), callback); + + try { + // Wait to get callback for availability of internet + Network internetNetwork = callback.waitForAvailable(); + assertNotNull("Did not receive NetworkCallback#onAvailable for INTERNET", + internetNetwork); + } catch (InterruptedException e) { + fail("NetworkCallback wait was interrupted."); + } finally { + mCm.unregisterNetworkCallback(callback); + } + } + + /** + * Exercises the requestNetwork with NetworkCallback API with timeout - expected to + * fail. Use WIFI and switch Wi-Fi off. + */ + public void testRequestNetworkCallback_onUnavailable() { + final boolean previousWifiEnabledState = mWifiManager.isWifiEnabled(); + if (previousWifiEnabledState) { + disconnectFromWifi(null); + } + + final TestNetworkCallback callback = new TestNetworkCallback(); + mCm.requestNetwork(new NetworkRequest.Builder() + .addTransportType(TRANSPORT_WIFI) + .build(), 100, callback); + + try { + // Wait to get callback for unavailability of requested network + assertTrue("Did not receive NetworkCallback#onUnavailable", + callback.waitForUnavailable()); + } catch (InterruptedException e) { + fail("NetworkCallback wait was interrupted."); + } finally { + mCm.unregisterNetworkCallback(callback); + if (previousWifiEnabledState) { + connectToWifi(); + } + } + } + /** * Tests reporting of connectivity changed. */ @@ -639,6 +691,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { private static class TestNetworkCallback extends ConnectivityManager.NetworkCallback { private final CountDownLatch mAvailableLatch = new CountDownLatch(1); private final CountDownLatch mLostLatch = new CountDownLatch(1); + private final CountDownLatch mUnavailableLatch = new CountDownLatch(1); public Network currentNetwork; public Network lastLostNetwork; @@ -651,6 +704,11 @@ public class ConnectivityManagerTest extends AndroidTestCase { return mLostLatch.await(30, TimeUnit.SECONDS) ? lastLostNetwork : null; } + public boolean waitForUnavailable() throws InterruptedException { + return mUnavailableLatch.await(2, TimeUnit.SECONDS); + } + + @Override public void onAvailable(Network network) { currentNetwork = network; @@ -665,6 +723,11 @@ public class ConnectivityManagerTest extends AndroidTestCase { } mLostLatch.countDown(); } + + @Override + public void onUnavailable() { + mUnavailableLatch.countDown(); + } } private Network getWifiNetwork() { From a9f33d578d764d6bb0a4e86d8fa31e1c799181b4 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Thu, 2 Mar 2017 12:35:34 -0800 Subject: [PATCH 0316/1109] [AWARE] CTS tests for publish/subscribe discovery Validate the SUCCESS case of publish and subscribe discovery sessions. Bug: 30556108 Test: CTS tests pass Change-Id: Ib88606cdf662560258890e2f274c85c3a8818206 --- .../net/wifi/aware/cts/SingleDeviceTest.java | 252 +++++++++++++++++- 1 file changed, 244 insertions(+), 8 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java index bea4500855..37c0ac5892 100644 --- a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java +++ b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java @@ -23,13 +23,21 @@ import android.content.IntentFilter; import android.net.wifi.WifiManager; import android.net.wifi.aware.AttachCallback; import android.net.wifi.aware.Characteristics; +import android.net.wifi.aware.DiscoverySessionCallback; import android.net.wifi.aware.IdentityChangedListener; +import android.net.wifi.aware.PeerHandle; +import android.net.wifi.aware.PublishConfig; +import android.net.wifi.aware.PublishDiscoverySession; +import android.net.wifi.aware.SubscribeConfig; +import android.net.wifi.aware.SubscribeDiscoverySession; import android.net.wifi.aware.WifiAwareManager; import android.net.wifi.aware.WifiAwareSession; import android.test.AndroidTestCase; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.concurrent.CountDownLatch; @@ -150,6 +158,140 @@ public class SingleDeviceTest extends AndroidTestCase { } } + private class DiscoverySessionCallbackTest extends DiscoverySessionCallback { + static final int ON_PUBLISH_STARTED = 0; + static final int ON_SUBSCRIBE_STARTED = 1; + static final int ON_SESSION_CONFIG_UPDATED = 2; + static final int ON_SESSION_CONFIG_FAILED = 3; + static final int ON_SESSION_TERMINATED = 4; + static final int ON_SERVICE_DISCOVERED = 5; + static final int ON_MESSAGE_SEND_SUCCEEDED = 6; + static final int ON_MESSAGE_SEND_FAILED = 7; + static final int ON_MESSAGE_RECEIVED = 8; + + private final Object mLocalLock = new Object(); + + private CountDownLatch mBlocker; + private int mCurrentWaitForCallback; + private ArrayDeque mCallbackQueue = new ArrayDeque<>(); + + private PublishDiscoverySession mPublishDiscoverySession; + private SubscribeDiscoverySession mSubscribeDiscoverySession; + + private void processCallback(int callback) { + synchronized (mLocalLock) { + if (mBlocker != null && mCurrentWaitForCallback == callback) { + mBlocker.countDown(); + } else { + mCallbackQueue.addLast(callback); + } + } + } + + @Override + public void onPublishStarted(PublishDiscoverySession session) { + mPublishDiscoverySession = session; + processCallback(ON_PUBLISH_STARTED); + } + + @Override + public void onSubscribeStarted(SubscribeDiscoverySession session) { + mSubscribeDiscoverySession = session; + processCallback(ON_SUBSCRIBE_STARTED); + } + + @Override + public void onSessionConfigUpdated() { + processCallback(ON_SESSION_CONFIG_UPDATED); + } + + @Override + public void onSessionConfigFailed() { + processCallback(ON_SESSION_CONFIG_FAILED); + } + + @Override + public void onSessionTerminated() { + processCallback(ON_SESSION_TERMINATED); + } + + @Override + public void onServiceDiscovered(PeerHandle peerHandle, byte[] serviceSpecificInfo, + List matchFilter) { + processCallback(ON_SERVICE_DISCOVERED); + } + + @Override + public void onMessageSendSucceeded(int messageId) { + processCallback(ON_MESSAGE_SEND_SUCCEEDED); + } + + @Override + public void onMessageSendFailed(int messageId) { + processCallback(ON_MESSAGE_SEND_FAILED); + } + + @Override + public void onMessageReceived(PeerHandle peerHandle, byte[] message) { + processCallback(ON_MESSAGE_RECEIVED); + } + + /** + * Wait for the specified callback - any of the ON_* constants. Returns a true + * on success (specified callback triggered) or false on failure (timed-out or + * interrupted while waiting for the requested callback). + * + * Note: other callbacks happening while while waiting for the specified callback will + * be queued. + */ + boolean waitForCallback(int callback) { + synchronized (mLocalLock) { + boolean found = mCallbackQueue.remove(callback); + if (found) { + return true; + } + + mCurrentWaitForCallback = callback; + mBlocker = new CountDownLatch(1); + } + + try { + return mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS); + } catch (InterruptedException e) { + return false; + } + } + + /** + * Indicates whether the specified callback (any of the ON_* constants) has already + * happened and in the queue. Useful when the order of events is important. + */ + boolean hasCallbackAlreadyHappened(int callback) { + synchronized (mLocalLock) { + return mCallbackQueue.contains(callback); + } + } + + /** + * Returns the last created publish discovery session. + */ + PublishDiscoverySession getPublishDiscoverySession() { + PublishDiscoverySession session = mPublishDiscoverySession; + mPublishDiscoverySession = null; + return session; + } + + /** + * Returns the last created subscribe discovery session. + */ + SubscribeDiscoverySession getSubscribeDiscoverySession() { + SubscribeDiscoverySession session = mSubscribeDiscoverySession; + mSubscribeDiscoverySession = null; + return session; + } + + } + @Override protected void setUp() throws Exception { super.setUp(); @@ -257,14 +399,7 @@ public class SingleDeviceTest extends AndroidTestCase { return; } - AttachCallbackTest attachCb = new AttachCallbackTest(); - mWifiAwareManager.attach(attachCb, null); - int cbCalled = attachCb.waitForAnyCallback(); - assertEquals("Wi-Fi Aware attach", AttachCallbackTest.ATTACHED, cbCalled); - - WifiAwareSession session = attachCb.getSession(); - assertNotNull("Wi-Fi Aware session", session); - + WifiAwareSession session = attachAndGetSession(); session.destroy(); } @@ -305,4 +440,105 @@ public class SingleDeviceTest extends AndroidTestCase { assertEquals("", numIterations, macs.size()); } + + /** + * Validate a successful publish discovery session lifetime: publish, update publish, destroy. + */ + public void testPublishDiscoverySuccess() { + if (!TestUtils.shouldTestWifiAware(getContext())) { + return; + } + + final String serviceName = "ValidName"; + + WifiAwareSession session = attachAndGetSession(); + + PublishConfig publishConfig = new PublishConfig.Builder().setServiceName( + serviceName).build(); + DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); + + // 1. publish + session.publish(publishConfig, discoveryCb, null); + assertTrue("Publish started", + discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED)); + PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession(); + assertNotNull("Publish session", discoverySession); + + // 2. update-publish + publishConfig = new PublishConfig.Builder().setServiceName( + serviceName).setServiceSpecificInfo("extras".getBytes()).build(); + discoverySession.updatePublish(publishConfig); + assertTrue("Publish update", discoveryCb.waitForCallback( + DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED)); + + // 3. destroy + assertFalse("Publish not terminated", discoveryCb.hasCallbackAlreadyHappened( + DiscoverySessionCallbackTest.ON_SESSION_TERMINATED)); + discoverySession.destroy(); + + // 4. try update post-destroy: should time-out waiting for cb + discoverySession.updatePublish(publishConfig); + assertFalse("Publish update post destroy", discoveryCb.waitForCallback( + DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED)); + + session.destroy(); + } + + /** + * Validate a successful subscribe discovery session lifetime: subscribe, update subscribe, + * destroy. + */ + public void testSubscribeDiscoverySuccess() { + if (!TestUtils.shouldTestWifiAware(getContext())) { + return; + } + + final String serviceName = "ValidName"; + + WifiAwareSession session = attachAndGetSession(); + + SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName( + serviceName).build(); + DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); + + // 1. subscribe + session.subscribe(subscribeConfig, discoveryCb, null); + assertTrue("Subscribe started", + discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_SUBSCRIBE_STARTED)); + SubscribeDiscoverySession discoverySession = discoveryCb.getSubscribeDiscoverySession(); + assertNotNull("Subscribe session", discoverySession); + + // 2. update-subscribe + subscribeConfig = new SubscribeConfig.Builder().setServiceName( + serviceName).setServiceSpecificInfo("extras".getBytes()).build(); + discoverySession.updateSubscribe(subscribeConfig); + assertTrue("Subscribe update", discoveryCb.waitForCallback( + DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED)); + + // 3. destroy + assertFalse("Subscribe not terminated", discoveryCb.hasCallbackAlreadyHappened( + DiscoverySessionCallbackTest.ON_SESSION_TERMINATED)); + discoverySession.destroy(); + + // 4. try update post-destroy: should time-out waiting for cb + discoverySession.updateSubscribe(subscribeConfig); + assertFalse("Subscribe update post destroy", discoveryCb.waitForCallback( + DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED)); + + session.destroy(); + } + + // local utilities + + WifiAwareSession attachAndGetSession() { + AttachCallbackTest attachCb = new AttachCallbackTest(); + mWifiAwareManager.attach(attachCb, null); + int cbCalled = attachCb.waitForAnyCallback(); + assertEquals("Wi-Fi Aware attach", AttachCallbackTest.ATTACHED, cbCalled); + + WifiAwareSession session = attachCb.getSession(); + assertNotNull("Wi-Fi Aware session", session); + + return session; + } } From ab5186e4f64233d72c1ea75716f7581d4b0f5ed9 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Thu, 2 Mar 2017 13:54:14 -0800 Subject: [PATCH 0317/1109] [AWARE] CTS for failure mode of send message API Test that sending a message with invalid peer handle (null) fails as expected. Note: limited testing - Single device testing doesn't have a peer - Cannot create an invalid peer handle since opaque object Bug: 30556108 Test: CTS tests pass Change-Id: I72f4b67ea3c3dfc00aa48f6601d064b406dabde7 --- .../net/wifi/aware/cts/SingleDeviceTest.java | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java index 37c0ac5892..ab87815399 100644 --- a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java +++ b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java @@ -75,7 +75,7 @@ public class SingleDeviceTest extends AndroidTestCase { boolean waitForStateChange() throws InterruptedException { return mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS); } - }; + } private class AttachCallbackTest extends AttachCallback { static final int ATTACHED = 0; @@ -289,7 +289,6 @@ public class SingleDeviceTest extends AndroidTestCase { mSubscribeDiscoverySession = null; return session; } - } @Override @@ -528,9 +527,43 @@ public class SingleDeviceTest extends AndroidTestCase { session.destroy(); } + /** + * Test the send message flow. Since testing single device cannot send to a real peer - + * validate that sending to a bogus peer fails. + */ + public void testSendMessageFail() { + if (!TestUtils.shouldTestWifiAware(getContext())) { + return; + } + + WifiAwareSession session = attachAndGetSession(); + + PublishConfig publishConfig = new PublishConfig.Builder().setServiceName( + "ValidName").build(); + DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); + + // 1. publish + session.publish(publishConfig, discoveryCb, null); + assertTrue("Publish started", + discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED)); + PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession(); + assertNotNull("Publish session", discoverySession); + + // 2. send a message with a null peer-handle - expect exception + try { + discoverySession.sendMessage(null, -1290, "some message".getBytes()); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException e) { + // empty + } + + discoverySession.destroy(); + session.destroy(); + } + // local utilities - WifiAwareSession attachAndGetSession() { + private WifiAwareSession attachAndGetSession() { AttachCallbackTest attachCb = new AttachCallbackTest(); mWifiAwareManager.attach(attachCb, null); int cbCalled = attachCb.waitForAnyCallback(); From 12be803ccee1fa111615a9a9fade01f3e47807d8 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Thu, 2 Mar 2017 15:52:14 -0800 Subject: [PATCH 0318/1109] [AWARE] CTS for Aware data-path creation Test Aware data-path creation API flow - failure. Note: testing limited to failure since single device testing doesn't have a peer Bug: 30556108 Test: CTS tests pass Change-Id: Ie15ad57d7331b21fbb6706091691bd5f87e1264e --- .../net/wifi/aware/cts/SingleDeviceTest.java | 108 +++++++++++++++++- 1 file changed, 103 insertions(+), 5 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java index ab87815399..fcd04541b4 100644 --- a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java +++ b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java @@ -20,6 +20,9 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.net.ConnectivityManager; +import android.net.NetworkCapabilities; +import android.net.NetworkRequest; import android.net.wifi.WifiManager; import android.net.wifi.aware.AttachCallback; import android.net.wifi.aware.Characteristics; @@ -32,6 +35,8 @@ import android.net.wifi.aware.SubscribeConfig; import android.net.wifi.aware.SubscribeDiscoverySession; import android.net.wifi.aware.WifiAwareManager; import android.net.wifi.aware.WifiAwareSession; +import android.os.Handler; +import android.os.HandlerThread; import android.test.AndroidTestCase; import java.util.ArrayDeque; @@ -54,10 +59,17 @@ public class SingleDeviceTest extends AndroidTestCase { static private final int WAIT_FOR_AWARE_CHANGE_SECS = 10; private final Object mLock = new Object(); + private final HandlerThread mHandlerThread = new HandlerThread("SingleDeviceTest"); + private final Handler mHandler; + { + mHandlerThread.start(); + mHandler = new Handler(mHandlerThread.getLooper()); + } private WifiAwareManager mWifiAwareManager; private WifiManager mWifiManager; private WifiManager.WifiLock mWifiLock; + private ConnectivityManager mConnectivityManager; // used to store any WifiAwareSession allocated during tests - will clean-up after tests private List mSessions = new ArrayList<>(); @@ -291,6 +303,27 @@ public class SingleDeviceTest extends AndroidTestCase { } } + private class NetworkCallbackTest extends ConnectivityManager.NetworkCallback { + private CountDownLatch mBlocker = new CountDownLatch(1); + + @Override + public void onUnavailable() { + mBlocker.countDown(); + } + + /** + * Wait for the onUnavailable() callback to be triggered. Returns true if triggered, + * otherwise (timed-out, interrupted) returns false. + */ + boolean waitForOnUnavailable() { + try { + return mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS); + } catch (InterruptedException e) { + return false; + } + } + } + @Override protected void setUp() throws Exception { super.setUp(); @@ -311,6 +344,10 @@ public class SingleDeviceTest extends AndroidTestCase { mWifiManager.setWifiEnabled(true); } + mConnectivityManager = (ConnectivityManager) getContext().getSystemService( + Context.CONNECTIVITY_SERVICE); + assertNotNull("Connectivity Manager", mConnectivityManager); + IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED); WifiAwareBroadcastReceiver receiver = new WifiAwareBroadcastReceiver(); @@ -421,7 +458,7 @@ public class SingleDeviceTest extends AndroidTestCase { for (int i = 0; i < numIterations; ++i) { AttachCallbackTest attachCb = new AttachCallbackTest(); IdentityChangedListenerTest identityL = new IdentityChangedListenerTest(); - mWifiAwareManager.attach(attachCb, identityL, null); + mWifiAwareManager.attach(attachCb, identityL, mHandler); assertEquals("Wi-Fi Aware attach: iteration " + i, AttachCallbackTest.ATTACHED, attachCb.waitForAnyCallback()); assertTrue("Wi-Fi Aware attach: iteration " + i, identityL.waitForListener()); @@ -457,7 +494,7 @@ public class SingleDeviceTest extends AndroidTestCase { DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); // 1. publish - session.publish(publishConfig, discoveryCb, null); + session.publish(publishConfig, discoveryCb, mHandler); assertTrue("Publish started", discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED)); PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession(); @@ -501,7 +538,7 @@ public class SingleDeviceTest extends AndroidTestCase { DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); // 1. subscribe - session.subscribe(subscribeConfig, discoveryCb, null); + session.subscribe(subscribeConfig, discoveryCb, mHandler); assertTrue("Subscribe started", discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_SUBSCRIBE_STARTED)); SubscribeDiscoverySession discoverySession = discoveryCb.getSubscribeDiscoverySession(); @@ -543,7 +580,7 @@ public class SingleDeviceTest extends AndroidTestCase { DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); // 1. publish - session.publish(publishConfig, discoveryCb, null); + session.publish(publishConfig, discoveryCb, mHandler); assertTrue("Publish started", discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED)); PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession(); @@ -561,11 +598,72 @@ public class SingleDeviceTest extends AndroidTestCase { session.destroy(); } + /** + * Request an Aware data-path on a Publish discovery session (which can be done with a null + * peer - to accept all requests). Validate that times-out. + */ + public void testDataPathInContextOfDiscoveryFail() { + if (!TestUtils.shouldTestWifiAware(getContext())) { + return; + } + + WifiAwareSession session = attachAndGetSession(); + + PublishConfig publishConfig = new PublishConfig.Builder().setServiceName( + "ValidName").build(); + DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); + NetworkCallbackTest networkCb = new NetworkCallbackTest(); + + // 1. publish + session.publish(publishConfig, discoveryCb, mHandler); + assertTrue("Publish started", + discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED)); + PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession(); + assertNotNull("Publish session", discoverySession); + + // 2. request an AWARE network + NetworkRequest nr = new NetworkRequest.Builder().addTransportType( + NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier( + discoverySession.createNetworkSpecifier(null, null)).build(); + mConnectivityManager.requestNetwork(nr, networkCb, 2000); + assertTrue("OnUnavailable received", networkCb.waitForOnUnavailable()); + + discoverySession.destroy(); + session.destroy(); + } + + /** + * Request an Aware data-path as a Responder with no peer MAC address (i.e. accept any peer + * request). Validate that times-out. + */ + public void testDataPathOutOfBandFail() { + if (!TestUtils.shouldTestWifiAware(getContext())) { + return; + } + + WifiAwareSession session = attachAndGetSession(); + + PublishConfig publishConfig = new PublishConfig.Builder().setServiceName( + "ValidName").build(); + DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); + NetworkCallbackTest networkCb = new NetworkCallbackTest(); + + // 1. request an AWARE network + NetworkRequest nr = new NetworkRequest.Builder().addTransportType( + NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier( + session.createNetworkSpecifier( + WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER, null, null)).build(); + mConnectivityManager.requestNetwork(nr, networkCb, 2000); + assertTrue("OnUnavailable received", networkCb.waitForOnUnavailable()); + + session.destroy(); + } + // local utilities private WifiAwareSession attachAndGetSession() { AttachCallbackTest attachCb = new AttachCallbackTest(); - mWifiAwareManager.attach(attachCb, null); + mWifiAwareManager.attach(attachCb, mHandler); int cbCalled = attachCb.waitForAnyCallback(); assertEquals("Wi-Fi Aware attach", AttachCallbackTest.ATTACHED, cbCalled); From 9602110a367d6c6e448d02ae68f95159f961aecb Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Wed, 8 Mar 2017 09:08:00 -0800 Subject: [PATCH 0319/1109] [AWARE] Update network creation tests open/encrypted API Updated/add CTS tests to validate createNetworkSpecifierXxx API for open and passphrase modules. As these are (still) single-ended CTS tests - they validate failure. Bug: 26564544 Test: CTS passing Change-Id: I07b76bee5a9b73780d341ac8511a2738ded751ca --- .../net/wifi/aware/cts/SingleDeviceTest.java | 81 ++++++++++++++++--- 1 file changed, 72 insertions(+), 9 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java index fcd04541b4..1f7b31b078 100644 --- a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java +++ b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java @@ -599,10 +599,10 @@ public class SingleDeviceTest extends AndroidTestCase { } /** - * Request an Aware data-path on a Publish discovery session (which can be done with a null - * peer - to accept all requests). Validate that times-out. + * Request an Aware data-path (open) on a Publish discovery session (which can be done with a + * null peer - to accept all requests). Validate that times-out. */ - public void testDataPathInContextOfDiscoveryFail() { + public void testDataPathOpenInContextOfDiscoveryFail() { if (!TestUtils.shouldTestWifiAware(getContext())) { return; } @@ -624,7 +624,7 @@ public class SingleDeviceTest extends AndroidTestCase { // 2. request an AWARE network NetworkRequest nr = new NetworkRequest.Builder().addTransportType( NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier( - discoverySession.createNetworkSpecifier(null, null)).build(); + discoverySession.createNetworkSpecifierOpen(null)).build(); mConnectivityManager.requestNetwork(nr, networkCb, 2000); assertTrue("OnUnavailable received", networkCb.waitForOnUnavailable()); @@ -633,10 +633,45 @@ public class SingleDeviceTest extends AndroidTestCase { } /** - * Request an Aware data-path as a Responder with no peer MAC address (i.e. accept any peer - * request). Validate that times-out. + * Request an Aware data-path (encrypted) on a Publish discovery session (which can be done + * with a null peer - to accept all requests). Validate that times-out. */ - public void testDataPathOutOfBandFail() { + public void testDataPathPassphraseInContextOfDiscoveryFail() { + if (!TestUtils.shouldTestWifiAware(getContext())) { + return; + } + + WifiAwareSession session = attachAndGetSession(); + + PublishConfig publishConfig = new PublishConfig.Builder().setServiceName( + "ValidName").build(); + DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); + NetworkCallbackTest networkCb = new NetworkCallbackTest(); + + // 1. publish + session.publish(publishConfig, discoveryCb, mHandler); + assertTrue("Publish started", + discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED)); + PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession(); + assertNotNull("Publish session", discoverySession); + + // 2. request an AWARE network + NetworkRequest nr = new NetworkRequest.Builder().addTransportType( + NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier( + discoverySession.createNetworkSpecifierPassphrase(null, + "Some very long but not very good passphrase")).build(); + mConnectivityManager.requestNetwork(nr, networkCb, 2000); + assertTrue("OnUnavailable received", networkCb.waitForOnUnavailable()); + + discoverySession.destroy(); + session.destroy(); + } + + /** + * Request an Aware data-path (open) as a Responder with no peer MAC address (i.e. accept any + * peer request). Validate that times-out. + */ + public void testDataPathOpenOutOfBandFail() { if (!TestUtils.shouldTestWifiAware(getContext())) { return; } @@ -651,8 +686,36 @@ public class SingleDeviceTest extends AndroidTestCase { // 1. request an AWARE network NetworkRequest nr = new NetworkRequest.Builder().addTransportType( NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier( - session.createNetworkSpecifier( - WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER, null, null)).build(); + session.createNetworkSpecifierOpen( + WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER, null)).build(); + mConnectivityManager.requestNetwork(nr, networkCb, 2000); + assertTrue("OnUnavailable received", networkCb.waitForOnUnavailable()); + + session.destroy(); + } + + /** + * Request an Aware data-path (encrypted) as a Responder with no peer MAC address (i.e. + * accept any peer request). Validate that times-out. + */ + public void testDataPathPassphraseOutOfBandFail() { + if (!TestUtils.shouldTestWifiAware(getContext())) { + return; + } + + WifiAwareSession session = attachAndGetSession(); + + PublishConfig publishConfig = new PublishConfig.Builder().setServiceName( + "ValidName").build(); + DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); + NetworkCallbackTest networkCb = new NetworkCallbackTest(); + + // 1. request an AWARE network + NetworkRequest nr = new NetworkRequest.Builder().addTransportType( + NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier( + session.createNetworkSpecifierPassphrase( + WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER, null, + "abcdefghihk")).build(); mConnectivityManager.requestNetwork(nr, networkCb, 2000); assertTrue("OnUnavailable received", networkCb.waitForOnUnavailable()); From 6bf853a9e158576ac0c11328877fa659313d0657 Mon Sep 17 00:00:00 2001 From: Peter Qiu Date: Thu, 9 Mar 2017 13:18:32 -0800 Subject: [PATCH 0320/1109] wifi: update callsite for Passpoint configuration management APIs The APIs are updated to not return a boolean status based on the API Councils comment. So update the callsite accordingly. Bug: 35858311 Test: make -j32 Change-Id: Ie9106ecddb2b15178ad37ec6f014d5cc7ce77c43 --- tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index d3dc8faadd..f05ff82f04 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -656,7 +656,7 @@ public class WifiManagerTest extends AndroidTestCase { * @param config The configuration to test with */ private void testAddPasspointConfig(PasspointConfiguration config) throws Exception { - assertTrue(mWifiManager.addOrUpdatePasspointConfiguration(config)); + mWifiManager.addOrUpdatePasspointConfiguration(config); // Certificates and keys will be set to null after it is installed to the KeyStore by // WifiManager. Reset them in the expected config so that it can be used to compare @@ -671,7 +671,7 @@ public class WifiManagerTest extends AndroidTestCase { assertEquals(config, configList.get(0)); // Remove the configuration and verify no installed configuration. - assertTrue(mWifiManager.removePasspointConfiguration(config.getHomeSp().getFqdn())); + mWifiManager.removePasspointConfiguration(config.getHomeSp().getFqdn()); assertTrue(mWifiManager.getPasspointConfigurations().isEmpty()); } } From d5fc89275d70e0ef600da80dbc1c1eba953de9aa Mon Sep 17 00:00:00 2001 From: Peter Qiu Date: Fri, 10 Mar 2017 12:35:59 -0800 Subject: [PATCH 0321/1109] wifi: hotspot2: verify getter methods Bug: 35756298 Test: run PpsMoParserTest Change-Id: Ib70bf59f76815e89ba0fc5d67a26502788e19c86 --- .../android/net/wifi/cts/PpsMoParserTest.java | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/tests/cts/net/src/android/net/wifi/cts/PpsMoParserTest.java b/tests/cts/net/src/android/net/wifi/cts/PpsMoParserTest.java index 5eccc0d0bb..b5e2f772d1 100644 --- a/tests/cts/net/src/android/net/wifi/cts/PpsMoParserTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/PpsMoParserTest.java @@ -73,110 +73,193 @@ public class PpsMoParserTest extends AndroidTestCase { PasspointConfiguration config = new PasspointConfiguration(); config.setUpdateIdentifier(12); + assertEquals(12, config.getUpdateIdentifier()); config.setCredentialPriority(99); + assertEquals(99, config.getCredentialPriority()); // AAA Server trust root. Map trustRootCertList = new HashMap<>(); trustRootCertList.put("server1.trust.root.com", certFingerprint); config.setTrustRootCertList(trustRootCertList); + assertEquals(trustRootCertList, config.getTrustRootCertList()); // Subscription update. UpdateParameter subscriptionUpdate = new UpdateParameter(); subscriptionUpdate.setUpdateIntervalInMinutes(120); + assertEquals(120, subscriptionUpdate.getUpdateIntervalInMinutes()); subscriptionUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SSP); + assertEquals(UpdateParameter.UPDATE_METHOD_SSP, subscriptionUpdate.getUpdateMethod()); subscriptionUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER); + assertEquals(UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER, + subscriptionUpdate.getRestriction()); subscriptionUpdate.setServerUri("subscription.update.com"); + assertEquals("subscription.update.com", subscriptionUpdate.getServerUri()); subscriptionUpdate.setUsername("subscriptionUser"); + assertEquals("subscriptionUser", subscriptionUpdate.getUsername()); subscriptionUpdate.setBase64EncodedPassword("subscriptionPass"); + assertEquals("subscriptionPass", subscriptionUpdate.getBase64EncodedPassword()); subscriptionUpdate.setTrustRootCertUrl("subscription.update.cert.com"); + assertEquals("subscription.update.cert.com", subscriptionUpdate.getTrustRootCertUrl()); subscriptionUpdate.setTrustRootCertSha256Fingerprint(certFingerprint); + assertTrue(Arrays.equals(certFingerprint, + subscriptionUpdate.getTrustRootCertSha256Fingerprint())); config.setSubscriptionUpdate(subscriptionUpdate); + assertEquals(subscriptionUpdate, config.getSubscriptionUpdate()); // Subscription parameters. config.setSubscriptionCreationTimeInMs(format.parse("2016-02-01T10:00:00Z").getTime()); + assertEquals(format.parse("2016-02-01T10:00:00Z").getTime(), + config.getSubscriptionCreationTimeInMs()); config.setSubscriptionExpirationTimeInMs(format.parse("2016-03-01T10:00:00Z").getTime()); + assertEquals(format.parse("2016-03-01T10:00:00Z").getTime(), + config.getSubscriptionExpirationTimeInMs()); config.setSubscriptionType("Gold"); + assertEquals("Gold", config.getSubscriptionType()); config.setUsageLimitDataLimit(921890); + assertEquals(921890, config.getUsageLimitDataLimit()); config.setUsageLimitStartTimeInMs(format.parse("2016-12-01T10:00:00Z").getTime()); + assertEquals(format.parse("2016-12-01T10:00:00Z").getTime(), + config.getUsageLimitStartTimeInMs()); config.setUsageLimitTimeLimitInMinutes(120); + assertEquals(120, config.getUsageLimitTimeLimitInMinutes()); config.setUsageLimitUsageTimePeriodInMinutes(99910); + assertEquals(99910, config.getUsageLimitUsageTimePeriodInMinutes()); // HomeSP configuration. HomeSp homeSp = new HomeSp(); homeSp.setFriendlyName("Century House"); + assertEquals("Century House", homeSp.getFriendlyName()); homeSp.setFqdn("mi6.co.uk"); + assertEquals("mi6.co.uk", homeSp.getFqdn()); homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L}); + assertTrue(Arrays.equals(new long[] {0x112233L, 0x445566L}, + homeSp.getRoamingConsortiumOis())); homeSp.setIconUrl("icon.test.com"); + assertEquals("icon.test.com", homeSp.getIconUrl()); Map homeNetworkIds = new HashMap<>(); homeNetworkIds.put("TestSSID", 0x12345678L); homeNetworkIds.put("NullHESSID", null); homeSp.setHomeNetworkIds(homeNetworkIds); + assertEquals(homeNetworkIds, homeSp.getHomeNetworkIds()); homeSp.setMatchAllOis(new long[] {0x11223344}); + assertTrue(Arrays.equals(new long[] {0x11223344}, homeSp.getMatchAllOis())); homeSp.setMatchAnyOis(new long[] {0x55667788}); + assertTrue(Arrays.equals(new long[] {0x55667788}, homeSp.getMatchAnyOis())); homeSp.setOtherHomePartners(new String[] {"other.fqdn.com"}); + assertTrue(Arrays.equals(new String[] {"other.fqdn.com"}, + homeSp.getOtherHomePartners())); config.setHomeSp(homeSp); + assertEquals(homeSp, config.getHomeSp()); // Credential configuration. Credential credential = new Credential(); credential.setCreationTimeInMs(format.parse("2016-01-01T10:00:00Z").getTime()); + assertEquals(format.parse("2016-01-01T10:00:00Z").getTime(), + credential.getCreationTimeInMs()); credential.setExpirationTimeInMs(format.parse("2016-02-01T10:00:00Z").getTime()); + assertEquals(format.parse("2016-02-01T10:00:00Z").getTime(), + credential.getExpirationTimeInMs()); credential.setRealm("shaken.stirred.com"); + assertEquals("shaken.stirred.com", credential.getRealm()); credential.setCheckAaaServerCertStatus(true); + assertTrue(credential.getCheckAaaServerCertStatus()); Credential.UserCredential userCredential = new Credential.UserCredential(); userCredential.setUsername("james"); + assertEquals("james", userCredential.getUsername()); userCredential.setPassword("Ym9uZDAwNw=="); + assertEquals("Ym9uZDAwNw==", userCredential.getPassword()); userCredential.setMachineManaged(true); + assertTrue(userCredential.getMachineManaged()); userCredential.setSoftTokenApp("TestApp"); + assertEquals("TestApp", userCredential.getSoftTokenApp()); userCredential.setAbleToShare(true); + assertTrue(userCredential.getAbleToShare()); userCredential.setEapType(21); + assertEquals(21, userCredential.getEapType()); userCredential.setNonEapInnerMethod("MS-CHAP-V2"); + assertEquals("MS-CHAP-V2", userCredential.getNonEapInnerMethod()); credential.setUserCredential(userCredential); + assertEquals(userCredential, credential.getUserCredential()); Credential.CertificateCredential certCredential = new Credential.CertificateCredential(); certCredential.setCertType("x509v3"); + assertEquals("x509v3", certCredential.getCertType()); certCredential.setCertSha256Fingerprint(certFingerprint); + assertTrue(Arrays.equals(certFingerprint, certCredential.getCertSha256Fingerprint())); credential.setCertCredential(certCredential); + assertEquals(certCredential, credential.getCertCredential()); Credential.SimCredential simCredential = new Credential.SimCredential(); simCredential.setImsi("imsi"); + assertEquals("imsi", simCredential.getImsi()); simCredential.setEapType(24); + assertEquals(24, simCredential.getEapType()); credential.setSimCredential(simCredential); + assertEquals(simCredential, credential.getSimCredential()); config.setCredential(credential); + assertEquals(credential, config.getCredential()); // Policy configuration. Policy policy = new Policy(); List preferredRoamingPartnerList = new ArrayList<>(); Policy.RoamingPartner partner1 = new Policy.RoamingPartner(); partner1.setFqdn("test1.fqdn.com"); + assertEquals("test1.fqdn.com", partner1.getFqdn()); partner1.setFqdnExactMatch(true); + assertTrue(partner1.getFqdnExactMatch()); partner1.setPriority(127); + assertEquals(127, partner1.getPriority()); partner1.setCountries("us,fr"); + assertEquals("us,fr", partner1.getCountries()); Policy.RoamingPartner partner2 = new Policy.RoamingPartner(); partner2.setFqdn("test2.fqdn.com"); + assertEquals("test2.fqdn.com", partner2.getFqdn()); partner2.setFqdnExactMatch(false); + assertFalse(partner2.getFqdnExactMatch()); partner2.setPriority(200); + assertEquals(200, partner2.getPriority()); partner2.setCountries("*"); + assertEquals("*", partner2.getCountries()); preferredRoamingPartnerList.add(partner1); preferredRoamingPartnerList.add(partner2); policy.setPreferredRoamingPartnerList(preferredRoamingPartnerList); + assertEquals(preferredRoamingPartnerList, policy.getPreferredRoamingPartnerList()); policy.setMinHomeDownlinkBandwidth(23412); + assertEquals(23412, policy.getMinHomeDownlinkBandwidth()); policy.setMinHomeUplinkBandwidth(9823); + assertEquals(9823, policy.getMinHomeUplinkBandwidth()); policy.setMinRoamingDownlinkBandwidth(9271); + assertEquals(9271, policy.getMinRoamingDownlinkBandwidth()); policy.setMinRoamingUplinkBandwidth(2315); + assertEquals(2315, policy.getMinRoamingUplinkBandwidth()); policy.setExcludedSsidList(new String[] {"excludeSSID"}); + assertTrue(Arrays.equals(new String[] {"excludeSSID"}, policy.getExcludedSsidList())); Map requiredProtoPortMap = new HashMap<>(); requiredProtoPortMap.put(12, "34,92,234"); policy.setRequiredProtoPortMap(requiredProtoPortMap); + assertEquals(requiredProtoPortMap, policy.getRequiredProtoPortMap()); policy.setMaximumBssLoadValue(23); + assertEquals(23, policy.getMaximumBssLoadValue()); UpdateParameter policyUpdate = new UpdateParameter(); policyUpdate.setUpdateIntervalInMinutes(120); + assertEquals(120, policyUpdate.getUpdateIntervalInMinutes()); policyUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM); + assertEquals(UpdateParameter.UPDATE_METHOD_OMADM, policyUpdate.getUpdateMethod()); policyUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP); + assertEquals(UpdateParameter.UPDATE_RESTRICTION_HOMESP, policyUpdate.getRestriction()); policyUpdate.setServerUri("policy.update.com"); + assertEquals("policy.update.com", policyUpdate.getServerUri()); policyUpdate.setUsername("updateUser"); + assertEquals("updateUser", policyUpdate.getUsername()); policyUpdate.setBase64EncodedPassword("updatePass"); + assertEquals("updatePass", policyUpdate.getBase64EncodedPassword()); policyUpdate.setTrustRootCertUrl("update.cert.com"); + assertEquals("update.cert.com", policyUpdate.getTrustRootCertUrl()); policyUpdate.setTrustRootCertSha256Fingerprint(certFingerprint); + assertTrue(Arrays.equals(certFingerprint, + policyUpdate.getTrustRootCertSha256Fingerprint())); policy.setPolicyUpdate(policyUpdate); + assertEquals(policyUpdate, policy.getPolicyUpdate()); config.setPolicy(policy); + assertEquals(policy, config.getPolicy()); return config; } From 154dea6b603c6545f960ed2bd74a81824611176b Mon Sep 17 00:00:00 2001 From: Peter Qiu Date: Thu, 9 Mar 2017 13:18:32 -0800 Subject: [PATCH 0322/1109] wifi: update callsite for Passpoint configuration management APIs The APIs are updated to not return a boolean status based on the API Councils comment. So update the callsite accordingly. Bug: 35858311 Test: make -j32 Change-Id: Ie9106ecddb2b15178ad37ec6f014d5cc7ce77c43 Merged-In: Ie9106ecddb2b15178ad37ec6f014d5cc7ce77c43 --- tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index d3dc8faadd..f05ff82f04 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -656,7 +656,7 @@ public class WifiManagerTest extends AndroidTestCase { * @param config The configuration to test with */ private void testAddPasspointConfig(PasspointConfiguration config) throws Exception { - assertTrue(mWifiManager.addOrUpdatePasspointConfiguration(config)); + mWifiManager.addOrUpdatePasspointConfiguration(config); // Certificates and keys will be set to null after it is installed to the KeyStore by // WifiManager. Reset them in the expected config so that it can be used to compare @@ -671,7 +671,7 @@ public class WifiManagerTest extends AndroidTestCase { assertEquals(config, configList.get(0)); // Remove the configuration and verify no installed configuration. - assertTrue(mWifiManager.removePasspointConfiguration(config.getHomeSp().getFqdn())); + mWifiManager.removePasspointConfiguration(config.getHomeSp().getFqdn()); assertTrue(mWifiManager.getPasspointConfigurations().isEmpty()); } } From a7ec8300d98e92c1363303f7f103bf0787d13a27 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Tue, 7 Mar 2017 00:22:33 +0900 Subject: [PATCH 0323/1109] Dup fds to stop finalizers from invalidating them. The hostside VPN tests were failing because finalizers were closing the ParcelFileDescriptors that we use to get socekt fds. The close operations were causing the fds to be marked as invalid (i.e., -1), causing the tests' system calls on them to fail with EBADF. Fix this by dup(2)ing the fds and closing the original objects. Also, add some asserts to debug this sort of failure. Fix: 35927643 Test: HostsideVpnTests passed 20/20 times on bullhead Change-Id: If88530b5bd32622bd4726cd6f0907f731209bb43 --- .../net/hostside/RemoteSocketFactoryClient.java | 15 ++++++++++++--- .../src/com/android/cts/net/hostside/VpnTest.java | 10 +++++++++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RemoteSocketFactoryClient.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RemoteSocketFactoryClient.java index 799fe50ebe..80f99b6605 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RemoteSocketFactoryClient.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RemoteSocketFactoryClient.java @@ -22,11 +22,15 @@ import android.content.Intent; import android.content.ServiceConnection; import android.os.ConditionVariable; import android.os.IBinder; +import android.os.ParcelFileDescriptor; import android.os.RemoteException; +import android.system.ErrnoException; +import android.system.Os; import com.android.cts.net.hostside.IRemoteSocketFactory; import java.io.FileDescriptor; +import java.io.IOException; public class RemoteSocketFactoryClient { private static final int TIMEOUT_MS = 5000; @@ -76,9 +80,14 @@ public class RemoteSocketFactoryClient { } } - public FileDescriptor openSocketFd( - String host, int port, int timeoutMs) throws RemoteException { - return mService.openSocketFd(host, port, timeoutMs).getFileDescriptor(); + public FileDescriptor openSocketFd(String host, int port, int timeoutMs) + throws RemoteException, ErrnoException, IOException { + // Dup the filedescriptor so ParcelFileDescriptor's finalizer doesn't garbage collect it + // and cause our fd to become invalid. http://b/35927643 . + ParcelFileDescriptor pfd = mService.openSocketFd(host, port, timeoutMs); + FileDescriptor fd = Os.dup(pfd.getFileDescriptor()); + pfd.close(); + return fd; } public String getPackageName() throws RemoteException { diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java index a8ad2b868e..2bd3c39d2c 100755 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java @@ -481,7 +481,11 @@ public class VpnTest extends InstrumentationTestCase { private FileDescriptor openSocketFd(String host, int port, int timeoutMs) throws Exception { Socket s = new Socket(host, port); s.setSoTimeout(timeoutMs); - return ParcelFileDescriptor.fromSocket(s).getFileDescriptor(); + // Dup the filedescriptor so ParcelFileDescriptor's finalizer doesn't garbage collect it + // and cause our fd to become invalid. http://b/35927643 . + FileDescriptor fd = Os.dup(ParcelFileDescriptor.fromSocket(s).getFileDescriptor()); + s.close(); + return fd; } private FileDescriptor openSocketFdInOtherApp( @@ -511,7 +515,9 @@ public class VpnTest extends InstrumentationTestCase { private void assertSocketStillOpen(FileDescriptor fd, String host) throws Exception { try { + assertTrue(fd.valid()); sendRequest(fd, host); + assertTrue(fd.valid()); } finally { Os.close(fd); } @@ -519,10 +525,12 @@ public class VpnTest extends InstrumentationTestCase { private void assertSocketClosed(FileDescriptor fd, String host) throws Exception { try { + assertTrue(fd.valid()); sendRequest(fd, host); fail("Socket opened before VPN connects should be closed when VPN connects"); } catch (ErrnoException expected) { assertEquals(ECONNABORTED, expected.errno); + assertTrue(fd.valid()); } finally { Os.close(fd); } From e5ad8b0bb1607426c99c95e8a85c958ebebc8628 Mon Sep 17 00:00:00 2001 From: peter_li Date: Tue, 21 Mar 2017 20:03:18 +0800 Subject: [PATCH 0324/1109] [CTS]It should be more reasonable to use setBatterySaverMode API to leave power-save mode instead of plugging in charger for "CtsHostsideNetworkTests" test case. Symptom: It should be more reasonable to use setBatterySaverMode API to leave power-save mode instead of plugging in charger for "CtsHostsideNetworkTests" test case. Root Cause: It uses setBatterySaverMode API to enter power-save mode and uses plugging in charger to leave power save mode.It should be more reasonable to use setBatterySaverMode API to leave power-save mode instead of plugging in charger. Solution: To use setBatterySaverMode API to leave power-save mode instead of plugging in charger. Project: N70 Note: NA Test done by RD: Futher testing need Q team's support: Change-Id: I491c5d0675f340e1c9911b84e41f034663b1454d --- .../com/android/cts/net/hostside/AbstractAppIdleTestCase.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java index 79435f1712..831b387b4d 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java @@ -147,6 +147,8 @@ abstract class AbstractAppIdleTestCase extends AbstractRestrictBackgroundNetwork assertBackgroundNetworkAccess(true); setBatterySaverMode(true); assertBackgroundNetworkAccess(false); + // Use setBatterySaverMode API to leave power-save mode instead of plugging in charger + setBatterySaverMode(false); turnBatteryOn(); assertBackgroundNetworkAccess(true); From d3e27e4bf0b309559207e22354bb696422096b86 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Thu, 23 Mar 2017 15:19:52 +0900 Subject: [PATCH 0325/1109] Require that the VPN tests pass on TVs. The tests were skipped for historical reasons that are no longer valid, and creates a hole in testing because there are now several VPN apps that work on TVs. Test: HostsideVpnTests passes on fugu with UID routing kernel bug fixed Bug: 36465489 Change-Id: Ib0d6a5cec085e1fc09cf0609b08ca897629afe0c --- .../hostside/app/src/com/android/cts/net/hostside/VpnTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java index 2bd3c39d2c..bc982cec78 100755 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java @@ -110,8 +110,7 @@ public class VpnTest extends InstrumentationTestCase { private boolean supportedHardware() { final PackageManager pm = getInstrumentation().getContext().getPackageManager(); - return !pm.hasSystemFeature("android.hardware.type.television") && - !pm.hasSystemFeature("android.hardware.type.watch"); + return !pm.hasSystemFeature("android.hardware.type.watch"); } @Override From c9819a49a5d39431254899be678eafa469dfb784 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Mon, 20 Mar 2017 10:53:23 -0700 Subject: [PATCH 0326/1109] [AWARE] Add CTS tests for publish/subscribe TTL Add time-to-live (TTL) testing on publish/subscribe. Can be verified with single device testing. Bug: 30556108 Test: CTS tests pass Change-Id: Ic0fc6b7bd2bc12a5e615b3334a5373da73ccfbf6 --- .../net/wifi/aware/cts/SingleDeviceTest.java | 99 ++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java index 1f7b31b078..e134b46848 100644 --- a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java +++ b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java @@ -257,6 +257,23 @@ public class SingleDeviceTest extends AndroidTestCase { * be queued. */ boolean waitForCallback(int callback) { + return waitForCallback(callback, WAIT_FOR_AWARE_CHANGE_SECS); + } + + /** + * Wait for the specified callback - any of the ON_* constants. Returns a true + * on success (specified callback triggered) or false on failure (timed-out or + * interrupted while waiting for the requested callback). + * + * Same as waitForCallback(int callback) execpt that allows specifying a custom timeout. + * The default timeout is a short value expected to be sufficient for all behaviors which + * should happen relatively quickly. Specifying a custom timeout should only be done for + * those cases which are known to take a specific longer period of time. + * + * Note: other callbacks happening while while waiting for the specified callback will + * be queued. + */ + boolean waitForCallback(int callback, int timeoutSec) { synchronized (mLocalLock) { boolean found = mCallbackQueue.remove(callback); if (found) { @@ -268,7 +285,7 @@ public class SingleDeviceTest extends AndroidTestCase { } try { - return mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS); + return mBlocker.await(timeoutSec, TimeUnit.SECONDS); } catch (InterruptedException e) { return false; } @@ -520,6 +537,46 @@ public class SingleDeviceTest extends AndroidTestCase { session.destroy(); } + /** + * Validate that publish with a Time To Live (TTL) setting expires within the specified + * time (and validates that the terminate callback is triggered). + */ + public void testPublishLimitedTtlSuccess() { + if (!TestUtils.shouldTestWifiAware(getContext())) { + return; + } + + final String serviceName = "ValidName"; + final int ttlSec = 5; + + WifiAwareSession session = attachAndGetSession(); + + PublishConfig publishConfig = new PublishConfig.Builder().setServiceName( + serviceName).setTtlSec(ttlSec).setTerminateNotificationEnabled(true).build(); + DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); + + // 1. publish + session.publish(publishConfig, discoveryCb, mHandler); + assertTrue("Publish started", + discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED)); + PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession(); + assertNotNull("Publish session", discoverySession); + + // 2. wait for terminate within 'ttlSec'. + assertTrue("Publish terminated", + discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_SESSION_TERMINATED, + ttlSec + 5)); + + // 3. try update post-termination: should time-out waiting for cb + publishConfig = new PublishConfig.Builder().setServiceName( + serviceName).setServiceSpecificInfo("extras".getBytes()).build(); + discoverySession.updatePublish(publishConfig); + assertFalse("Publish update post terminate", discoveryCb.waitForCallback( + DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED)); + + session.destroy(); + } + /** * Validate a successful subscribe discovery session lifetime: subscribe, update subscribe, * destroy. @@ -564,6 +621,46 @@ public class SingleDeviceTest extends AndroidTestCase { session.destroy(); } + /** + * Validate that subscribe with a Time To Live (TTL) setting expires within the specified + * time (and validates that the terminate callback is triggered). + */ + public void testSubscribeLimitedTtlSuccess() { + if (!TestUtils.shouldTestWifiAware(getContext())) { + return; + } + + final String serviceName = "ValidName"; + final int ttlSec = 5; + + WifiAwareSession session = attachAndGetSession(); + + SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName( + serviceName).setTtlSec(ttlSec).setTerminateNotificationEnabled(true).build(); + DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); + + // 1. subscribe + session.subscribe(subscribeConfig, discoveryCb, mHandler); + assertTrue("Subscribe started", + discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_SUBSCRIBE_STARTED)); + SubscribeDiscoverySession discoverySession = discoveryCb.getSubscribeDiscoverySession(); + assertNotNull("Subscribe session", discoverySession); + + // 2. wait for terminate within 'ttlSec'. + assertTrue("Subscribe terminated", + discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_SESSION_TERMINATED, + ttlSec + 5)); + + // 3. try update post-termination: should time-out waiting for cb + subscribeConfig = new SubscribeConfig.Builder().setServiceName( + serviceName).setServiceSpecificInfo("extras".getBytes()).build(); + discoverySession.updateSubscribe(subscribeConfig); + assertFalse("Subscribe update post terminate", discoveryCb.waitForCallback( + DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED)); + + session.destroy(); + } + /** * Test the send message flow. Since testing single device cannot send to a real peer - * validate that sending to a bogus peer fails. From 894c917c9bac50616b68e402953679db1507a52d Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Mon, 27 Mar 2017 14:23:10 -0700 Subject: [PATCH 0327/1109] Skip data saver related tests if the device doesn't support it. Bug: 36007771 Test: manual Change-Id: I817d2cc23e5c8d460367ede749ff35e799f48ee0 --- ...ractRestrictBackgroundNetworkTestCase.java | 20 ++++++++++-- .../cts/net/hostside/DataSaverModeTest.java | 31 +++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 15daed971b..42eb321cbc 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -100,6 +100,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected ConnectivityManager mCm; protected WifiManager mWfm; protected int mUid; + private int mMyUid; private String mMeteredWifi; private MyServiceClient mServiceClient; private boolean mHasWatch; @@ -115,7 +116,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); mWfm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); mUid = getUid(TEST_APP2_PKG); - final int myUid = getUid(mContext.getPackageName()); + mMyUid = getUid(mContext.getPackageName()); mServiceClient = new MyServiceClient(mContext); mServiceClient.bind(); mHasWatch = mContext.getPackageManager().hasSystemFeature( @@ -128,7 +129,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation mSupported = setUpActiveNetworkMeteringState(); Log.i(TAG, "Apps status on " + getName() + ":\n" - + "\ttest app: uid=" + myUid + ", state=" + getProcessStateByUid(myUid) + "\n" + + "\ttest app: uid=" + mMyUid + ", state=" + getProcessStateByUid(mMyUid) + "\n" + "\tapp2: uid=" + mUid + ", state=" + getProcessStateByUid(mUid)); } @@ -204,6 +205,21 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation assertEquals("wrong status", toString(expectedStatus), actualStatus); } + protected void assertMyRestrictBackgroundStatus(int expectedStatus) throws Exception { + final int actualStatus = mCm.getRestrictBackgroundStatus(); + assertEquals("Wrong status", toString(expectedStatus), toString(actualStatus)); + } + + protected boolean isMyRestrictBackgroundStatus(int expectedStatus) throws Exception { + final int actualStatus = mCm.getRestrictBackgroundStatus(); + if (expectedStatus != actualStatus) { + Log.d(TAG, "Expected: " + toString(expectedStatus) + + " but actual: " + toString(actualStatus)); + return false; + } + return true; + } + protected void assertBackgroundNetworkAccess(boolean expectAllowed) throws Exception { assertBackgroundState(); // Sanity check. assertNetworkAccess(expectAllowed); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index c3537c89f4..599a31ce1c 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -20,16 +20,21 @@ import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLE import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; +import android.util.Log; + public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase { private static final String[] REQUIRED_WHITELISTED_PACKAGES = { "com.android.providers.downloads" }; + private boolean mIsDataSaverSupported; + @Override public void setUp() throws Exception { super.setUp(); + mIsDataSaverSupported = isDataSaverSupported(); if (!isSupported()) return; // Set initial state. @@ -59,6 +64,32 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase return setMeteredNetwork(); } + @Override + protected boolean isSupported() throws Exception { + if (!mIsDataSaverSupported) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Data Saver Mode"); + } + return mIsDataSaverSupported && super.isSupported(); + } + + /** + * As per CDD requirements, if the device doesn't support data saver mode then + * ConnectivityManager.getRestrictBackgroundStatus() will always return + * RESTRICT_BACKGROUND_STATUS_DISABLED. So, enable the data saver mode and check if + * ConnectivityManager.getRestrictBackgroundStatus() for an app in background returns + * RESTRICT_BACKGROUND_STATUS_DISABLED or not. + */ + private boolean isDataSaverSupported() throws Exception { + assertMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + try { + setRestrictBackground(true); + return !isMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + } finally { + setRestrictBackground(false); + } + } + public void testGetRestrictBackgroundStatus_disabled() throws Exception { if (!isSupported()) return; From 41914d36f308c87bc567245f67e1594131a9ebe6 Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Mon, 27 Mar 2017 14:23:10 -0700 Subject: [PATCH 0328/1109] DO NOT MERGE: Skip data saver related tests if the device doesn't support it. Bug: 36007771 Test: manual Change-Id: I817d2cc23e5c8d460367ede749ff35e799f48ee0 --- ...ractRestrictBackgroundNetworkTestCase.java | 20 ++++++++++-- .../cts/net/hostside/DataSaverModeTest.java | 31 +++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index a50034819a..d2720d631a 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -99,6 +99,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected ConnectivityManager mCm; protected WifiManager mWfm; protected int mUid; + private int mMyUid; private String mMeteredWifi; private boolean mHasWatch; private String mDeviceIdleConstantsSetting; @@ -113,7 +114,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); mWfm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); mUid = getUid(TEST_APP2_PKG); - final int myUid = getUid(mContext.getPackageName()); + mMyUid = getUid(mContext.getPackageName()); mHasWatch = mContext.getPackageManager().hasSystemFeature( PackageManager.FEATURE_WATCH); if (mHasWatch) { @@ -124,7 +125,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation mSupported = setUpActiveNetworkMeteringState(); Log.i(TAG, "Apps status on " + getName() + ":\n" - + "\ttest app: uid=" + myUid + ", state=" + getProcessStateByUid(myUid) + "\n" + + "\ttest app: uid=" + mMyUid + ", state=" + getProcessStateByUid(mMyUid) + "\n" + "\tapp2: uid=" + mUid + ", state=" + getProcessStateByUid(mUid)); } @@ -199,6 +200,21 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation assertEquals("wrong status", toString(expectedStatus), actualStatus); } + protected void assertMyRestrictBackgroundStatus(int expectedStatus) throws Exception { + final int actualStatus = mCm.getRestrictBackgroundStatus(); + assertEquals("Wrong status", toString(expectedStatus), toString(actualStatus)); + } + + protected boolean isMyRestrictBackgroundStatus(int expectedStatus) throws Exception { + final int actualStatus = mCm.getRestrictBackgroundStatus(); + if (expectedStatus != actualStatus) { + Log.d(TAG, "Expected: " + toString(expectedStatus) + + " but actual: " + toString(actualStatus)); + return false; + } + return true; + } + protected void assertBackgroundNetworkAccess(boolean expectAllowed) throws Exception { assertBackgroundState(); // Sanity check. assertNetworkAccess(expectAllowed); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index 9e4b0c13de..72d0be9d0c 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -20,16 +20,21 @@ import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLE import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; +import android.util.Log; + public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase { private static final String[] REQUIRED_WHITELISTED_PACKAGES = { "com.android.providers.downloads" }; + private boolean mIsDataSaverSupported; + @Override public void setUp() throws Exception { super.setUp(); + mIsDataSaverSupported = isDataSaverSupported(); if (!isSupported()) return; // Set initial state. @@ -59,6 +64,32 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase return setMeteredNetwork(); } + @Override + protected boolean isSupported() throws Exception { + if (!mIsDataSaverSupported) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Data Saver Mode"); + } + return mIsDataSaverSupported && super.isSupported(); + } + + /** + * As per CDD requirements, if the device doesn't support data saver mode then + * ConnectivityManager.getRestrictBackgroundStatus() will always return + * RESTRICT_BACKGROUND_STATUS_DISABLED. So, enable the data saver mode and check if + * ConnectivityManager.getRestrictBackgroundStatus() for an app in background returns + * RESTRICT_BACKGROUND_STATUS_DISABLED or not. + */ + private boolean isDataSaverSupported() throws Exception { + assertMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + try { + setRestrictBackground(true); + return !isMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + } finally { + setRestrictBackground(false); + } + } + public void testGetRestrictBackgroundStatus_disabled() throws Exception { if (!isSupported()) return; From d69455289f21d7645ba0a7bc1cb959ae5f82f74f Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Mon, 27 Mar 2017 14:23:10 -0700 Subject: [PATCH 0329/1109] DO NOT MERGE: Skip data saver related tests if the device doesn't support it. Bug: 36007771 Test: manual Change-Id: I817d2cc23e5c8d460367ede749ff35e799f48ee0 --- ...ractRestrictBackgroundNetworkTestCase.java | 20 ++++++++++-- .../cts/net/hostside/DataSaverModeTest.java | 31 +++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 46d243ee77..793938a1ac 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -84,6 +84,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected ConnectivityManager mCm; protected WifiManager mWfm; protected int mUid; + private int mMyUid; private String mMeteredWifi; private boolean mSupported; @@ -96,11 +97,11 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); mWfm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); mUid = getUid(TEST_APP2_PKG); - final int myUid = getUid(mContext.getPackageName()); + mMyUid = getUid(mContext.getPackageName()); mSupported = setUpActiveNetworkMeteringState(); Log.i(TAG, "Apps status on " + getName() + ":\n" - + "\ttest app: uid=" + myUid + ", state=" + getProcessStateByUid(myUid) + "\n" + + "\ttest app: uid=" + mMyUid + ", state=" + getProcessStateByUid(mMyUid) + "\n" + "\tapp2: uid=" + mUid + ", state=" + getProcessStateByUid(mUid)); } @@ -175,6 +176,21 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation assertEquals("wrong status", toString(expectedStatus), actualStatus); } + protected void assertMyRestrictBackgroundStatus(int expectedStatus) throws Exception { + final int actualStatus = mCm.getRestrictBackgroundStatus(); + assertEquals("Wrong status", toString(expectedStatus), toString(actualStatus)); + } + + protected boolean isMyRestrictBackgroundStatus(int expectedStatus) throws Exception { + final int actualStatus = mCm.getRestrictBackgroundStatus(); + if (expectedStatus != actualStatus) { + Log.d(TAG, "Expected: " + toString(expectedStatus) + + " but actual: " + toString(actualStatus)); + return false; + } + return true; + } + protected void assertBackgroundNetworkAccess(boolean expectAllowed) throws Exception { assertBackgroundState(); // Sanity check. assertNetworkAccess(expectAllowed); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index ac35bd44b6..d5e236f0b8 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -20,16 +20,21 @@ import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLE import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; +import android.util.Log; + public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase { private static final String[] REQUIRED_WHITELISTED_PACKAGES = { "com.android.providers.downloads" }; + private boolean mIsDataSaverSupported; + @Override public void setUp() throws Exception { super.setUp(); + mIsDataSaverSupported = isDataSaverSupported(); if (!isSupported()) return; // Set initial state. @@ -59,6 +64,32 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase return setMeteredNetwork(); } + @Override + protected boolean isSupported() throws Exception { + if (!mIsDataSaverSupported) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Data Saver Mode"); + } + return mIsDataSaverSupported && super.isSupported(); + } + + /** + * As per CDD requirements, if the device doesn't support data saver mode then + * ConnectivityManager.getRestrictBackgroundStatus() will always return + * RESTRICT_BACKGROUND_STATUS_DISABLED. So, enable the data saver mode and check if + * ConnectivityManager.getRestrictBackgroundStatus() for an app in background returns + * RESTRICT_BACKGROUND_STATUS_DISABLED or not. + */ + private boolean isDataSaverSupported() throws Exception { + assertMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + try { + setRestrictBackground(true); + return !isMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + } finally { + setRestrictBackground(false); + } + } + public void testGetRestrictBackgroundStatus_disabled() throws Exception { if (!isSupported()) return; From d44cfd7014dd51077496c29bfeec41dee3d6763c Mon Sep 17 00:00:00 2001 From: Nathan Harold Date: Mon, 6 Mar 2017 10:34:27 -0800 Subject: [PATCH 0330/1109] Initial CTS Tests for IpSec Classes -Test SPI creation, duplication and deletion -Test IpSecTransform creation, apply to socket, and delete Bug: 34811227 Test: Verified on Bullhead with UDP on IPv6 (default) Change-Id: I1ffc84e549c7666996472ed323eb44810c3b9843 --- .../src/android/net/cts/IpSecManagerTest.java | 178 ++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 tests/cts/net/src/android/net/cts/IpSecManagerTest.java diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java new file mode 100644 index 0000000000..93b5c44918 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2017 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.content.Context; +import android.net.ConnectivityManager; +import android.net.IpSecAlgorithm; +import android.net.IpSecManager; +import android.net.IpSecTransform; +import android.test.AndroidTestCase; +import android.util.Log; +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; + +public class IpSecManagerTest extends AndroidTestCase { + + private static final String TAG = IpSecManagerTest.class.getSimpleName(); + + private IpSecManager mISM; + + private ConnectivityManager mCM; + + private static final InetAddress GOOGLE_DNS_4; + private static final InetAddress GOOGLE_DNS_6; + + static { + try { + // Google Public DNS Addresses; + GOOGLE_DNS_4 = InetAddress.getByName("8.8.8.8"); + GOOGLE_DNS_6 = InetAddress.getByName("2001:4860:4860::8888"); + } catch (UnknownHostException e) { + throw new RuntimeException("Could not resolve DNS Addresses", e); + } + } + + private static final InetAddress[] GOOGLE_DNS_LIST = + new InetAddress[] {GOOGLE_DNS_4, GOOGLE_DNS_6}; + + private static final int DROID_SPI = 0xD1201D; + + private static final byte[] CRYPT_KEY = + new byte[] { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F + }; + private static final byte[] AUTH_KEY = + new byte[] { + 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7F + }; + + protected void setUp() throws Exception { + super.setUp(); + mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); + mISM = (IpSecManager) getContext().getSystemService(Context.IPSEC_SERVICE); + } + + /* + * Allocate a random SPI + * Allocate a specific SPI using previous randomly created SPI value + * Realloc the same SPI that was specifically created (expect SpiUnavailable) + * Close SPIs + */ + public void testAllocSpi() throws Exception { + for (InetAddress addr : GOOGLE_DNS_LIST) { + IpSecManager.SecurityParameterIndex randomSpi = null, droidSpi = null; + randomSpi = + mISM.reserveSecurityParameterIndex( + IpSecTransform.DIRECTION_OUT, + addr, + IpSecManager.INVALID_SECURITY_PARAMETER_INDEX); + assertTrue(randomSpi.getSpi() != IpSecManager.INVALID_SECURITY_PARAMETER_INDEX); + + droidSpi = + mISM.reserveSecurityParameterIndex( + IpSecTransform.DIRECTION_IN, addr, DROID_SPI); + assertTrue(droidSpi.getSpi() == DROID_SPI); + + try { + mISM.reserveSecurityParameterIndex(IpSecTransform.DIRECTION_IN, addr, DROID_SPI); + fail("Duplicate SPI was allowed to be created"); + } catch (IpSecManager.SpiUnavailableException expected) { + // This is a success case because we expect a dupe SPI to throw + } + + randomSpi.close(); + droidSpi.close(); + } + } + + /* + * Alloc outbound SPI + * Alloc inbound SPI + * Create transport mode transform + * open socket + * apply transform to socket + * send data on socket + * release transform + * send data (expect exception) + */ + public void testCreateTransform() throws Exception { + InetAddress local = InetAddress.getLoopbackAddress(); + IpSecManager.SecurityParameterIndex outSpi = + mISM.reserveSecurityParameterIndex( + IpSecTransform.DIRECTION_OUT, + local, + IpSecManager.INVALID_SECURITY_PARAMETER_INDEX); + + IpSecManager.SecurityParameterIndex inSpi = + mISM.reserveSecurityParameterIndex( + IpSecTransform.DIRECTION_IN, local, outSpi.getSpi()); + + IpSecTransform transform = + new IpSecTransform.Builder(mContext) + .setSpi(IpSecTransform.DIRECTION_OUT, outSpi) + .setEncryption( + IpSecTransform.DIRECTION_OUT, + new IpSecAlgorithm(IpSecAlgorithm.ALGO_CRYPT_AES_CBC, CRYPT_KEY)) + .setAuthentication( + IpSecTransform.DIRECTION_OUT, + new IpSecAlgorithm( + IpSecAlgorithm.ALGO_AUTH_HMAC_SHA256, + AUTH_KEY, + AUTH_KEY.length * 8)) + .setSpi(IpSecTransform.DIRECTION_IN, inSpi) + .setEncryption( + IpSecTransform.DIRECTION_IN, + new IpSecAlgorithm(IpSecAlgorithm.ALGO_CRYPT_AES_CBC, CRYPT_KEY)) + .setAuthentication( + IpSecTransform.DIRECTION_IN, + new IpSecAlgorithm( + IpSecAlgorithm.ALGO_AUTH_HMAC_SHA256, + AUTH_KEY, + CRYPT_KEY.length * 8)) + .buildTransportModeTransform(local); + + DatagramSocket localSocket; + localSocket = new DatagramSocket(8888); + + localSocket.setSoTimeout(500); + mISM.applyTransportModeTransform(localSocket, transform); + byte[] data = new String("Best test data ever!").getBytes("UTF-8"); + + DatagramPacket out = new DatagramPacket(data, data.length, local, 8888); + localSocket.send(out); + DatagramPacket in = new DatagramPacket(new byte[data.length], data.length); + + localSocket.receive(in); + Log.d(TAG, Arrays.toString(data)); + Log.d(TAG, Arrays.toString(in.getData())); + assertTrue(Arrays.equals(data, in.getData())); + transform.close(); + try { + localSocket.send(out); + } catch (IOException e) { + } + + mISM.removeTransportModeTransform(localSocket, transform); + } +} From ea6bd5400afa4119786396707e76e9d6e6ca4b94 Mon Sep 17 00:00:00 2001 From: Nathan Harold Date: Mon, 6 Mar 2017 10:34:27 -0800 Subject: [PATCH 0331/1109] Initial CTS Tests for IpSec Classes -Test SPI creation, duplication and deletion -Test IpSecTransform creation, apply to socket, and delete Bug: 30984788, 34811227 Test: Verified on Bullhead with UDP on IPv6 (default) Change-Id: I1ffc84e549c7666996472ed323eb44810c3b9843 (cherry picked from commit 4eddc41200c1912b40218d0ee7b0f0cc05c1a960) --- .../src/android/net/cts/IpSecManagerTest.java | 178 ++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 tests/cts/net/src/android/net/cts/IpSecManagerTest.java diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java new file mode 100644 index 0000000000..93b5c44918 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2017 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.content.Context; +import android.net.ConnectivityManager; +import android.net.IpSecAlgorithm; +import android.net.IpSecManager; +import android.net.IpSecTransform; +import android.test.AndroidTestCase; +import android.util.Log; +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; + +public class IpSecManagerTest extends AndroidTestCase { + + private static final String TAG = IpSecManagerTest.class.getSimpleName(); + + private IpSecManager mISM; + + private ConnectivityManager mCM; + + private static final InetAddress GOOGLE_DNS_4; + private static final InetAddress GOOGLE_DNS_6; + + static { + try { + // Google Public DNS Addresses; + GOOGLE_DNS_4 = InetAddress.getByName("8.8.8.8"); + GOOGLE_DNS_6 = InetAddress.getByName("2001:4860:4860::8888"); + } catch (UnknownHostException e) { + throw new RuntimeException("Could not resolve DNS Addresses", e); + } + } + + private static final InetAddress[] GOOGLE_DNS_LIST = + new InetAddress[] {GOOGLE_DNS_4, GOOGLE_DNS_6}; + + private static final int DROID_SPI = 0xD1201D; + + private static final byte[] CRYPT_KEY = + new byte[] { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F + }; + private static final byte[] AUTH_KEY = + new byte[] { + 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7F + }; + + protected void setUp() throws Exception { + super.setUp(); + mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); + mISM = (IpSecManager) getContext().getSystemService(Context.IPSEC_SERVICE); + } + + /* + * Allocate a random SPI + * Allocate a specific SPI using previous randomly created SPI value + * Realloc the same SPI that was specifically created (expect SpiUnavailable) + * Close SPIs + */ + public void testAllocSpi() throws Exception { + for (InetAddress addr : GOOGLE_DNS_LIST) { + IpSecManager.SecurityParameterIndex randomSpi = null, droidSpi = null; + randomSpi = + mISM.reserveSecurityParameterIndex( + IpSecTransform.DIRECTION_OUT, + addr, + IpSecManager.INVALID_SECURITY_PARAMETER_INDEX); + assertTrue(randomSpi.getSpi() != IpSecManager.INVALID_SECURITY_PARAMETER_INDEX); + + droidSpi = + mISM.reserveSecurityParameterIndex( + IpSecTransform.DIRECTION_IN, addr, DROID_SPI); + assertTrue(droidSpi.getSpi() == DROID_SPI); + + try { + mISM.reserveSecurityParameterIndex(IpSecTransform.DIRECTION_IN, addr, DROID_SPI); + fail("Duplicate SPI was allowed to be created"); + } catch (IpSecManager.SpiUnavailableException expected) { + // This is a success case because we expect a dupe SPI to throw + } + + randomSpi.close(); + droidSpi.close(); + } + } + + /* + * Alloc outbound SPI + * Alloc inbound SPI + * Create transport mode transform + * open socket + * apply transform to socket + * send data on socket + * release transform + * send data (expect exception) + */ + public void testCreateTransform() throws Exception { + InetAddress local = InetAddress.getLoopbackAddress(); + IpSecManager.SecurityParameterIndex outSpi = + mISM.reserveSecurityParameterIndex( + IpSecTransform.DIRECTION_OUT, + local, + IpSecManager.INVALID_SECURITY_PARAMETER_INDEX); + + IpSecManager.SecurityParameterIndex inSpi = + mISM.reserveSecurityParameterIndex( + IpSecTransform.DIRECTION_IN, local, outSpi.getSpi()); + + IpSecTransform transform = + new IpSecTransform.Builder(mContext) + .setSpi(IpSecTransform.DIRECTION_OUT, outSpi) + .setEncryption( + IpSecTransform.DIRECTION_OUT, + new IpSecAlgorithm(IpSecAlgorithm.ALGO_CRYPT_AES_CBC, CRYPT_KEY)) + .setAuthentication( + IpSecTransform.DIRECTION_OUT, + new IpSecAlgorithm( + IpSecAlgorithm.ALGO_AUTH_HMAC_SHA256, + AUTH_KEY, + AUTH_KEY.length * 8)) + .setSpi(IpSecTransform.DIRECTION_IN, inSpi) + .setEncryption( + IpSecTransform.DIRECTION_IN, + new IpSecAlgorithm(IpSecAlgorithm.ALGO_CRYPT_AES_CBC, CRYPT_KEY)) + .setAuthentication( + IpSecTransform.DIRECTION_IN, + new IpSecAlgorithm( + IpSecAlgorithm.ALGO_AUTH_HMAC_SHA256, + AUTH_KEY, + CRYPT_KEY.length * 8)) + .buildTransportModeTransform(local); + + DatagramSocket localSocket; + localSocket = new DatagramSocket(8888); + + localSocket.setSoTimeout(500); + mISM.applyTransportModeTransform(localSocket, transform); + byte[] data = new String("Best test data ever!").getBytes("UTF-8"); + + DatagramPacket out = new DatagramPacket(data, data.length, local, 8888); + localSocket.send(out); + DatagramPacket in = new DatagramPacket(new byte[data.length], data.length); + + localSocket.receive(in); + Log.d(TAG, Arrays.toString(data)); + Log.d(TAG, Arrays.toString(in.getData())); + assertTrue(Arrays.equals(data, in.getData())); + transform.close(); + try { + localSocket.send(out); + } catch (IOException e) { + } + + mISM.removeTransportModeTransform(localSocket, transform); + } +} From b45c3dc6f1118c732d516c7a4756700b7daf5b39 Mon Sep 17 00:00:00 2001 From: Peter Qiu Date: Mon, 3 Apr 2017 14:20:12 -0700 Subject: [PATCH 0332/1109] wifi: catch UnsupportedOperationException for devices with Passpoint disabled For devices with build config |config_wifi_hotspot2_enabled| set to false (Passpoint disabled), an UnsupportedOperationException will be thrown when Passpoint related WifiManager APIs are invoked. For these devices, the testing of Passpoint APIs are not relevant. So just catch and ignore this type of exceptions to avoid any test failures. While there, set the UpdateIdentifier for Passpoint configurations, to avoid the CA certificate verification when adding the config, since we're using a fake CA certificate for testing. Bug: 36863137 Test: cts-tradefed run cts-dev -m CtsNetTestCases -t android.net.wifi.cts.WifiManagerTest Change-Id: I8ebdc58349c33f13b510c3d9e2a5fc8ce4ef09c4 --- .../android/net/wifi/cts/WifiManagerTest.java | 36 +++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index f05ff82f04..14ae1b450a 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -587,6 +587,10 @@ public class WifiManagerTest extends AndroidTestCase { private PasspointConfiguration generatePasspointConfig(Credential credential) { PasspointConfiguration config = new PasspointConfiguration(); config.setCredential(credential); + // Setting update identifier to indicate R2 configuration, to avoid CA + // certificate being verified, since we're using a fake CA certificate + // for testing. + config.setUpdateIdentifier(1); // Setup HomeSp. HomeSp homeSp = new HomeSp(); @@ -656,22 +660,26 @@ public class WifiManagerTest extends AndroidTestCase { * @param config The configuration to test with */ private void testAddPasspointConfig(PasspointConfiguration config) throws Exception { - mWifiManager.addOrUpdatePasspointConfiguration(config); + try { + mWifiManager.addOrUpdatePasspointConfiguration(config); - // Certificates and keys will be set to null after it is installed to the KeyStore by - // WifiManager. Reset them in the expected config so that it can be used to compare - // against the retrieved config. - config.getCredential().setCaCertificate(null); - config.getCredential().setClientCertificateChain(null); - config.getCredential().setClientPrivateKey(null); + // Certificates and keys will be set to null after it is installed to the KeyStore by + // WifiManager. Reset them in the expected config so that it can be used to compare + // against the retrieved config. + config.getCredential().setCaCertificate(null); + config.getCredential().setClientCertificateChain(null); + config.getCredential().setClientPrivateKey(null); - // Retrieve the configuration and verify it. - List configList = mWifiManager.getPasspointConfigurations(); - assertEquals(1, configList.size()); - assertEquals(config, configList.get(0)); + // Retrieve the configuration and verify it. + List configList = mWifiManager.getPasspointConfigurations(); + assertEquals(1, configList.size()); + assertEquals(config, configList.get(0)); - // Remove the configuration and verify no installed configuration. - mWifiManager.removePasspointConfiguration(config.getHomeSp().getFqdn()); - assertTrue(mWifiManager.getPasspointConfigurations().isEmpty()); + // Remove the configuration and verify no installed configuration. + mWifiManager.removePasspointConfiguration(config.getHomeSp().getFqdn()); + assertTrue(mWifiManager.getPasspointConfigurations().isEmpty()); + } catch (UnsupportedOperationException e) { + // Passpoint build config |config_wifi_hotspot2_enabled| is disabled, so noop. + } } } From 3c0a0400722c6e47aaab841f5160b024fb2fa1b7 Mon Sep 17 00:00:00 2001 From: Nathan Harold Date: Thu, 6 Apr 2017 18:20:41 -0700 Subject: [PATCH 0333/1109] Update IpSecAlgorithm CTS for API compliance changes Bug: 36073210, b/34811227 Test: verified on Bullhead Change-Id: I8f37016cc9aadafd3e58f6af535bd7bc1d0f4a96 --- .../net/src/android/net/cts/IpSecManagerTest.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java index 93b5c44918..39d683d136 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java @@ -85,8 +85,7 @@ public class IpSecManagerTest extends AndroidTestCase { randomSpi = mISM.reserveSecurityParameterIndex( IpSecTransform.DIRECTION_OUT, - addr, - IpSecManager.INVALID_SECURITY_PARAMETER_INDEX); + addr); assertTrue(randomSpi.getSpi() != IpSecManager.INVALID_SECURITY_PARAMETER_INDEX); droidSpi = @@ -121,8 +120,7 @@ public class IpSecManagerTest extends AndroidTestCase { IpSecManager.SecurityParameterIndex outSpi = mISM.reserveSecurityParameterIndex( IpSecTransform.DIRECTION_OUT, - local, - IpSecManager.INVALID_SECURITY_PARAMETER_INDEX); + local); IpSecManager.SecurityParameterIndex inSpi = mISM.reserveSecurityParameterIndex( @@ -133,21 +131,21 @@ public class IpSecManagerTest extends AndroidTestCase { .setSpi(IpSecTransform.DIRECTION_OUT, outSpi) .setEncryption( IpSecTransform.DIRECTION_OUT, - new IpSecAlgorithm(IpSecAlgorithm.ALGO_CRYPT_AES_CBC, CRYPT_KEY)) + new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY)) .setAuthentication( IpSecTransform.DIRECTION_OUT, new IpSecAlgorithm( - IpSecAlgorithm.ALGO_AUTH_HMAC_SHA256, + IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 8)) .setSpi(IpSecTransform.DIRECTION_IN, inSpi) .setEncryption( IpSecTransform.DIRECTION_IN, - new IpSecAlgorithm(IpSecAlgorithm.ALGO_CRYPT_AES_CBC, CRYPT_KEY)) + new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY)) .setAuthentication( IpSecTransform.DIRECTION_IN, new IpSecAlgorithm( - IpSecAlgorithm.ALGO_AUTH_HMAC_SHA256, + IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, CRYPT_KEY.length * 8)) .buildTransportModeTransform(local); From 7b9e244aaa462aff37fd57c6a1025d750f139196 Mon Sep 17 00:00:00 2001 From: jdesprez Date: Tue, 11 Apr 2017 15:43:44 -0700 Subject: [PATCH 0334/1109] Update configurations to avoid using ApkInstaller - use the new tradefed version of it. - add a tests to check configs. Test: build, run collect-tests-only dry-run Bug: 37213493 Change-Id: Ia212b707befe3ffc70ef43cbc292e97be3f364f1 --- tests/cts/net/AndroidTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/AndroidTest.xml b/tests/cts/net/AndroidTest.xml index 389b926f83..fbad7391c8 100644 --- a/tests/cts/net/AndroidTest.xml +++ b/tests/cts/net/AndroidTest.xml @@ -13,7 +13,7 @@ limitations under the License. --> - +

    + * No apps should ever attempt to acquire this permission, since it would give those + * apps extremely broad access to connectivity functionality. + */ + public void testNetworkStackPermission() { + final PackageManager pm = getContext().getPackageManager(); + + final List holding = pm.getPackagesHoldingPermissions(new String[] { + android.Manifest.permission.NETWORK_STACK + }, PackageManager.MATCH_UNINSTALLED_PACKAGES); + for (PackageInfo pi : holding) { + fail("The NETWORK_STACK permission must not be held by " + pi.packageName + + " and must be revoked for security reasons"); + } + } + + /** + * Verify that the {@link android.Manifest.permission#NETWORK_SETTINGS} permission is + * never held by any package. + *

    + * Only Settings, SysUi and shell apps should ever attempt to acquire this + * permission, since it would give those apps extremely broad access to connectivity + * functionality. The permission is intended to be granted to only those apps with direct user + * access and no others. + */ + public void testNetworkSettingsPermission() { + final PackageManager pm = getContext().getPackageManager(); + + final ArraySet allowedPackages = new ArraySet(); + final ArraySet allowedUIDs = new ArraySet(); + // explicitly add allowed UIDs + allowedUIDs.add(Process.SYSTEM_UID); + allowedUIDs.add(Process.SHELL_UID); + allowedUIDs.add(Process.PHONE_UID); + + // only quick settings is allowed to bind to the BIND_QUICK_SETTINGS_TILE permission, using + // this fact to determined allowed package name for sysui + String validPkg = ""; + final List sysuiPackage = pm.getPackagesHoldingPermissions(new String[] { + android.Manifest.permission.BIND_QUICK_SETTINGS_TILE + }, PackageManager.MATCH_UNINSTALLED_PACKAGES); + + if (sysuiPackage.size() > 1) { + fail("The BIND_QUICK_SETTINGS_TILE permission must only be held by one package"); + } + + if (sysuiPackage.size() == 1) { + validPkg = sysuiPackage.get(0).packageName; + allowedPackages.add(validPkg); + } + + // the captive portal flow also currently holds the NETWORK_SETTINGS permission + final Intent intent = new Intent(ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN); + final ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DISABLED_COMPONENTS); + if (ri != null) { + allowedPackages.add(ri.activityInfo.packageName); + } + + final List holding = pm.getPackagesHoldingPermissions(new String[] { + android.Manifest.permission.NETWORK_SETTINGS + }, PackageManager.MATCH_UNINSTALLED_PACKAGES); + for (PackageInfo pi : holding) { + String packageName = pi.packageName; + if (allowedPackages.contains(packageName)) { + // this is an explicitly allowed package + } else { + // now check if the packages are from allowed UIDs + boolean allowed = false; + try { + if (allowedUIDs.contains(pm.getPackageUid(packageName, 0))) { + allowed = true; + Log.d(TAG, packageName + " is on an allowed UID"); + } + } catch (PackageManager.NameNotFoundException e) { } + if (!allowed) { + fail("The NETWORK_SETTINGS permission must not be held by " + + packageName + " and must be revoked for security reasons"); + } + } + } + } + + /** + * Verify that the {@link android.Manifest.permission#NETWORK_SETUP_WIZARD} permission is + * only held by the device setup wizard application. + *

    + * Only the SetupWizard app should ever attempt to acquire this + * permission, since it would give those apps extremely broad access to connectivity + * functionality. The permission is intended to be granted to only the device setup wizard. + */ + public void testNetworkSetupWizardPermission() { + final PackageManager pm = getContext().getPackageManager(); + + final Intent intent = new Intent(Intent.ACTION_MAIN); + intent.addCategory(Intent.CATEGORY_SETUP_WIZARD); + final ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DISABLED_COMPONENTS); + String validPkg = ""; + if (ri != null) { + validPkg = ri.activityInfo.packageName; + } + + final List holding = pm.getPackagesHoldingPermissions(new String[] { + android.Manifest.permission.NETWORK_SETUP_WIZARD + }, PackageManager.MATCH_UNINSTALLED_PACKAGES); + for (PackageInfo pi : holding) { + if (!Objects.equals(pi.packageName, validPkg)) { + fail("The NETWORK_SETUP_WIZARD permission must not be held by " + pi.packageName + + " and must be revoked for security reasons [" + validPkg +"]"); + } + } + } } From d8eb370a89689cc349a6168f773ec4fa36203b7f Mon Sep 17 00:00:00 2001 From: Neil Fuller Date: Fri, 13 Jul 2018 20:04:45 +0100 Subject: [PATCH 0502/1109] Extend Uri tests The internal UriCodec class is being removed from libcore/ and the associated CTS tests are being removed. This change adds equivalent URI decoding tests to the UriTest CTS test class. Test: make droid && make cts Test: run cts-dev -m CtsNetTestCases -t android.net.cts.UriTest Bug: 111055375 Change-Id: Ided15d5abf8478064d193034e84c4dbe0689c6f0 --- .../cts/net/src/android/net/cts/UriTest.java | 61 +++++++++++++++---- 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/UriTest.java b/tests/cts/net/src/android/net/cts/UriTest.java index 05e826a2c4..611eae2590 100644 --- a/tests/cts/net/src/android/net/cts/UriTest.java +++ b/tests/cts/net/src/android/net/cts/UriTest.java @@ -158,22 +158,61 @@ public class UriTest extends AndroidTestCase { String encoded = Uri.encode("Bob:/", "/"); assertEquals(-1, encoded.indexOf(':')); assertTrue(encoded.indexOf('/') > -1); - assertDecode(null); - assertDecode(""); - assertDecode("Bob"); - assertDecode(":Bob"); - assertDecode("::Bob"); - assertDecode("Bob::Lee"); - assertDecode("Bob:Lee"); - assertDecode("Bob::"); - assertDecode("Bob:"); - assertDecode("::Bob::"); + assertEncodeDecodeRoundtripExact(null); + assertEncodeDecodeRoundtripExact(""); + assertEncodeDecodeRoundtripExact("Bob"); + assertEncodeDecodeRoundtripExact(":Bob"); + assertEncodeDecodeRoundtripExact("::Bob"); + assertEncodeDecodeRoundtripExact("Bob::Lee"); + assertEncodeDecodeRoundtripExact("Bob:Lee"); + assertEncodeDecodeRoundtripExact("Bob::"); + assertEncodeDecodeRoundtripExact("Bob:"); + assertEncodeDecodeRoundtripExact("::Bob::"); } - private void assertDecode(String s) { + private static void assertEncodeDecodeRoundtripExact(String s) { assertEquals(s, Uri.decode(Uri.encode(s, null))); } + public void testDecode_emptyString_returnsEmptyString() { + assertEquals("", Uri.decode("")); + } + + public void testDecode_null_returnsNull() { + assertNull(Uri.decode(null)); + } + + public void testDecode_wrongHexDigit() { + // %p in the end. + assertEquals("ab/$\u0102%\u0840\uFFFD\u0000", Uri.decode("ab%2f$%C4%82%25%e0%a1%80%p")); + } + + public void testDecode_secondHexDigitWrong() { + // %1p in the end. + assertEquals("ab/$\u0102%\u0840\uFFFD\u0001", Uri.decode("ab%2f$%c4%82%25%e0%a1%80%1p")); + } + + public void testDecode_endsWithPercent_appendsUnknownCharacter() { + // % in the end. + assertEquals("ab/$\u0102%\u0840\uFFFD", Uri.decode("ab%2f$%c4%82%25%e0%a1%80%")); + } + + public void testDecode_plusNotConverted() { + assertEquals("ab/$\u0102%+\u0840", Uri.decode("ab%2f$%c4%82%25+%e0%a1%80")); + } + + // Last character needs decoding (make sure we are flushing the buffer with chars to decode). + public void testDecode_lastCharacter() { + assertEquals("ab/$\u0102%\u0840", Uri.decode("ab%2f$%c4%82%25%e0%a1%80")); + } + + // Check that a second row of encoded characters is decoded properly (internal buffers are + // reset properly). + public void testDecode_secondRowOfEncoded() { + assertEquals("ab/$\u0102%\u0840aa\u0840", + Uri.decode("ab%2f$%c4%82%25%e0%a1%80aa%e0%a1%80")); + } + public void testFromFile() { File f = new File("/tmp/bob"); Uri uri = Uri.fromFile(f); From cc7747d2de2d28c520e53f135c1f8236d051709e Mon Sep 17 00:00:00 2001 From: Chenbo Feng Date: Tue, 24 Jul 2018 12:36:37 -0700 Subject: [PATCH 0503/1109] Skip the test if cannot open ctrl file The shell access to the proc/xt_qtaguid/ctrl file is blocked in next android release since no apps or users should directly read/write to those proc files anymore. This CTS test is checking some critical kernel behavior to make sure the xt_qtaguid module have specific kernel fixes. So if the ctrl file is not accessible, there is no way to verify those critical fixes, we can only skipped the test. These testcases are also added in VTS qtaguid test so we can still check the devices have those kernel fixes. Bug: 110906349 Test: atest CtsNativeNetTestCases Change-Id: Iae0512bb37f8b93577a134f15affb4f2a448be18 --- .../native/qtaguid/src/NativeQtaguidTest.cpp | 61 +++++++------------ 1 file changed, 21 insertions(+), 40 deletions(-) diff --git a/tests/cts/net/native/qtaguid/src/NativeQtaguidTest.cpp b/tests/cts/net/native/qtaguid/src/NativeQtaguidTest.cpp index 1892a44ebd..7dc6240667 100644 --- a/tests/cts/net/native/qtaguid/src/NativeQtaguidTest.cpp +++ b/tests/cts/net/native/qtaguid/src/NativeQtaguidTest.cpp @@ -18,36 +18,29 @@ #include #include #include +#include #include #include -#include #include #include -int hasQtaguidKernelSupport() { - struct utsname buf; - int kernel_version_major; - int kernel_version_minor; - - int ret = uname(&buf); - if (ret) { - ret = -errno; - return ret; - } - char dummy; - ret = sscanf(buf.release, "%d.%d%c", &kernel_version_major, &kernel_version_minor, &dummy); - if (ret < 3) - return -EINVAL; - - if ((kernel_version_major == 4 && kernel_version_minor < 9) || - (kernel_version_major < 4)) { - return 1; - } else { - return access("/proc/net/xt_qtaguid/ctrl", F_OK) != -1; - } +int canAccessQtaguidFile() { + int fd = open("/proc/net/xt_qtaguid/ctrl", O_RDONLY | O_CLOEXEC); + close(fd); + return fd != -1; } +#define SKIP_IF_QTAGUID_NOT_SUPPORTED() \ + do { \ + int res = canAccessQtaguidFile(); \ + ASSERT_LE(0, res); \ + if (!res) { \ + GTEST_LOG_(INFO) << "This test is skipped since kernel may not have the module\n"; \ + return; \ + } \ + } while (0) + int getCtrlSkInfo(int tag, uid_t uid, uint64_t* sk_addr, int* ref_cnt) { FILE *fp; fp = fopen("/proc/net/xt_qtaguid/ctrl", "r"); @@ -95,12 +88,8 @@ void checkNoSocketPointerLeaks(int family) { } TEST (NativeQtaguidTest, close_socket_without_untag) { - int res = hasQtaguidKernelSupport(); - ASSERT_LE(0, res); - if (!res) { - GTEST_LOG_(INFO) << "This test is skipped since kernel may not have the module\n"; - return; - } + SKIP_IF_QTAGUID_NOT_SUPPORTED(); + int sockfd = socket(AF_INET, SOCK_STREAM, 0); uid_t uid = getuid(); int tag = arc4random(); @@ -114,12 +103,8 @@ TEST (NativeQtaguidTest, close_socket_without_untag) { } TEST (NativeQtaguidTest, close_socket_without_untag_ipv6) { - int res = hasQtaguidKernelSupport(); - ASSERT_LE(0, res); - if (!res) { - GTEST_LOG_(INFO) << "This test is skipped since kernel may not have the module\n"; - return; - } + SKIP_IF_QTAGUID_NOT_SUPPORTED(); + int sockfd = socket(AF_INET6, SOCK_STREAM, 0); uid_t uid = getuid(); int tag = arc4random(); @@ -133,12 +118,8 @@ TEST (NativeQtaguidTest, close_socket_without_untag_ipv6) { } TEST (NativeQtaguidTest, no_socket_addr_leak) { - int res = hasQtaguidKernelSupport(); - ASSERT_LE(0, res); - if (!res) { - GTEST_LOG_(INFO) << "This test is skipped since kernel may not have the module\n"; - return; - } + SKIP_IF_QTAGUID_NOT_SUPPORTED(); + checkNoSocketPointerLeaks(AF_INET); checkNoSocketPointerLeaks(AF_INET6); } From 679ee7cbe7f5b2d08b7035580dd57084a41fe77f Mon Sep 17 00:00:00 2001 From: Adam Vartanian Date: Fri, 27 Jul 2018 11:44:06 +0100 Subject: [PATCH 0504/1109] CTS test for SslCertificate.getX509Certificate Bug: 111696337 Bug: 36984840 Test: cts -m CtsNetTestCases -t android.net.http Change-Id: I778a18fd3636efc1e60d61e6d2b78685635c07f8 --- .../android/net/http/cts/SslCertificateTest.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java b/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java index 70ae496356..95f415c58c 100644 --- a/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java +++ b/tests/cts/net/src/android/net/http/cts/SslCertificateTest.java @@ -230,6 +230,19 @@ public class SslCertificateTest extends TestCase { final String EXPECTED = "Issued to: c=ccc,o=testOName,ou=testUName,cn=testCName;\n" + "Issued by: e=aeei,c=adb,o=testOName,ou=testUName,cn=testCName;\n"; assertEquals(EXPECTED, ssl.toString()); + assertNull(ssl.getX509Certificate()); } + public void testGetX509Certificate() { + final String TO = "c=ccc,o=testOName,ou=testUName,cn=testCName"; + final String BY = "e=aeei,c=adb,o=testOName,ou=testUName,cn=testCName"; + Date validNotBefore = new Date(System.currentTimeMillis() - 1000); + Date validNotAfter = new Date(System.currentTimeMillis()); + SslCertificate ssl = new SslCertificate(TO, BY, validNotBefore, validNotAfter); + assertNull(ssl.getX509Certificate()); + + X509Certificate cert = new MockX509Certificate(); + ssl = new SslCertificate(cert); + assertSame(cert, ssl.getX509Certificate()); + } } From 497a93647cd9cb5fdce0e0b25c1e566107e8f7cd Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Tue, 19 Jun 2018 19:30:31 -0700 Subject: [PATCH 0505/1109] Use a different key for signing networkpolicy test app. One of the preparation steps for running cts involves loading up the sim card with the key used to sign CtsCarrierApiTestCases.apk. It means if the same key is used for signing networkpolicy test app too, then the app is considered as carrier privileged by the system and can't be forced into app standby state. Fixes: 77861812 Test: cts-tradefed run singleCommand cts-dev -m CtsHostsideNetworkTests -t \ com.android.cts.net.HostsideRestrictBackgroundNetworkTests#testDataSaverMode_disabled Change-Id: Iaa9f4fabe83430fa42b6f67c1025db41a5e1d938 Merged-In: Iaa9f4fabe83430fa42b6f67c1025db41a5e1d938 --- tests/cts/hostside/app2/Android.mk | 2 ++ tests/cts/hostside/certs/README | 2 ++ tests/cts/hostside/certs/cts-net-app.pk8 | Bin 0 -> 1219 bytes tests/cts/hostside/certs/cts-net-app.x509.pem | 19 ++++++++++++++++++ 4 files changed, 23 insertions(+) create mode 100644 tests/cts/hostside/certs/README create mode 100644 tests/cts/hostside/certs/cts-net-app.pk8 create mode 100644 tests/cts/hostside/certs/cts-net-app.x509.pem diff --git a/tests/cts/hostside/app2/Android.mk b/tests/cts/hostside/app2/Android.mk index 9a4a30fbff..5c0bae194b 100644 --- a/tests/cts/hostside/app2/Android.mk +++ b/tests/cts/hostside/app2/Android.mk @@ -32,4 +32,6 @@ LOCAL_DEX_PREOPT := false # Tag this module as a cts test artifact LOCAL_COMPATIBILITY_SUITE := cts vts general-tests +LOCAL_CERTIFICATE := cts/hostsidetests/net/certs/cts-net-app + include $(BUILD_CTS_SUPPORT_PACKAGE) diff --git a/tests/cts/hostside/certs/README b/tests/cts/hostside/certs/README new file mode 100644 index 0000000000..b660a82dc8 --- /dev/null +++ b/tests/cts/hostside/certs/README @@ -0,0 +1,2 @@ +# Generated with: +development/tools/make_key cts-net-app '/CN=cts-net-app' diff --git a/tests/cts/hostside/certs/cts-net-app.pk8 b/tests/cts/hostside/certs/cts-net-app.pk8 new file mode 100644 index 0000000000000000000000000000000000000000..1703e4ee340b7c7ab818097cefbbf95fb86f3747 GIT binary patch literal 1219 zcmV;!1U&mNf&{+;0RS)!1_>&LNQUrsW5^Br2+u}0)hbn0N#A&vRMl( z)K7&#gN-YqA(ePu&=E2o$Vjep&N^#?J+IQe_UD^8vWC4%PBxI-ME{s%p~72w0ZU@; zaXKTG43uCz5lGMl@ha*FIBFHPR{XV|cKf1`B_%f8?!Ujr zt-{>0C4_u?`%vIYq{z#o&|wc%#UbbC#EF~*3eXtI#Pu@b#2AEmesXH!;BA|+2B81W z!Zu8OMUNETxR$5$c?)i;hZYR4J*6YT$pCc&@}h3pQGsU#%?m@^a{>ba009Dm0RaHk zc>v0s8?m!kl+%O!>N@ze<-9;f(^2U#XFDru6^Rdi7GW7mTF+$(jvu=f&c6qwe0xQc z-YV8)osrJ&&LK`cr5XVSk|=+5h9S}kmdcGs++ig(JtFrKB&6at^XSEN7gbjf(l>>Q zW5q!7d>b5VnALd8DRw?XvqUfpAAaDQ)mpy#BAh*U&nzY5KA?dt?&F!_gTW_hO&aG? zFz!^L2yHTF#V@X&LqF|!Q4`{WkX^!rOP6AzE3-+ExKAD|AnK7^^w$v-bH;VQMuXQG z^wqpIj+;*3h|p36xkZ4_k2@ee;ehD~XA7iWt0O?}W4hlp!7008eHpZ&=5xtRJbcFmSVJik5H=O_+OcDr64K?)M2Tx(p#1Bj!W}szK*F#xG5_9njbtuN zvAj31ay#p;XUyF~^2T$(v1bpJYKX(0Hjh1=a0St$<@BH?5pD>(7CE0M%ug3w#-4iu zfq)5bl2l+u5>xWKztT8zHPHfrfdIA^X{1GXSD$}V6aG5WdD+aZ)3UOU)PA-Q{> z3qB8AR`51~p;B8g;f0T+gwBF{nn#RZ*xS3do08bdRK^ktwT+BuQ7nn@r4GbJz7x8u zX+HvifdH9pz)+xQ>TMce;8KGy?O90aj>ISS3b7$HM<}?=R_^2Dov>KX=fW4gZ0oL# z4TlXtL8u4+=w-H(!dkS=iZ?}Kj79RMiGFcJL@(@4Kz{D4>0IF9=(5M)>0ajZaHD0q hCv|>6qS`CJYwg-kjl|iF9l$*x Date: Thu, 23 Aug 2018 13:00:15 -0700 Subject: [PATCH 0506/1109] DO NOT MERGE: CDD Annotations for Section: 7.4.2 C-1-1: MUST implement the WifiAwareManager APIs as described in the SDK documentation. --> SingleDeviceTest C-1-4:MUST randomize the Wi-Fi Aware management interface address at intervals no longer then 30 minutes and whenever Wi-Fi Aware is enabled -->SingleDeviceTest#testAttachDiscoveryAddressChanges() CDD SECTION:7.4.1.1/C-1-1,C-1-3: Wifi Direct C-1-1: MUST implement the corresponding Android API as described in the SDK documentation. C-1-3: MUST support regular Wi-Fi operation. --> ConcurrencyTest 7.4.2.4/C-1-1,C-2-1: C-1-1: MUST implement the Passpoint related WifiManager APIs as described in the SDK documentation. C-1-2: MUST support IEEE 802.11u standard, specifically related to Network Discovery and Selection, such as Generic Advertisement Service (GAS) and Access Network Query Protocol (ANQP). --> Passpoint configuration tests Added C-0-3 to ConnectivityBackgroundTestActivity as well CDD VERSION: 8.1: https://source.android.com/compatibility/8.1/android-8.1-cdd Bug: 112612833 Test: make cts Change-Id: Ief11b3ae7899bfdca12a7cce63daca600b1f0cdf --- .../net/src/android/net/wifi/aware/cts/SingleDeviceTest.java | 4 ++++ tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java | 3 +++ .../net/src/android/net/wifi/cts/WifiConfigurationTest.java | 3 +++ tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java | 2 ++ tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java | 5 +++++ .../src/android/net/wifi/cts/WifiManager_WifiLockTest.java | 3 +++ 6 files changed, 20 insertions(+) diff --git a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java index 87e22d82b7..5dce5ab39d 100644 --- a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java +++ b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java @@ -41,6 +41,8 @@ import android.provider.Settings; import android.test.AndroidTestCase; import android.util.Log; +import com.android.compatibility.common.util.CddTest; + import java.util.ArrayDeque; import java.util.ArrayList; import java.util.HashSet; @@ -54,6 +56,7 @@ import java.util.concurrent.TimeUnit; * Wi-Fi Aware CTS test suite: single device testing. Performs tests on a single * device to validate Wi-Fi Aware. */ +@CddTest(requirement="7.4.2.3/C-1-1") public class SingleDeviceTest extends AndroidTestCase { private static final String TAG = "WifiAwareCtsTests"; @@ -485,6 +488,7 @@ public class SingleDeviceTest extends AndroidTestCase { * then the attach/destroy will not correspond to enable/disable and will not result in a new * MAC address being generated. */ + @CddTest(requirement="7.4.2.3/C-1-4") public void testAttachDiscoveryAddressChanges() { if (!TestUtils.shouldTestWifiAware(getContext())) { return; diff --git a/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java b/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java index a066ba80de..418788322e 100644 --- a/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java @@ -31,9 +31,12 @@ import static android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_STATE_DISABLED; import static android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_STATE_ENABLED; import android.test.AndroidTestCase; +import com.android.compatibility.common.util.CddTest; + import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +@CddTest(requirement="7.4.2.1/C-1-1,C-1-3") public class ConcurrencyTest extends AndroidTestCase { private class MySync { int expectedWifiState; diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java index 4480a24a9a..8b17a57425 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java @@ -23,6 +23,9 @@ import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.test.AndroidTestCase; +import com.android.compatibility.common.util.CddTest; + +@CddTest(requirement="7.4.2/C-1-1") public class WifiConfigurationTest extends AndroidTestCase { private WifiManager mWifiManager; @Override diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java index 5983cb72c2..c97f010556 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java @@ -29,9 +29,11 @@ import android.net.wifi.WifiSsid; import android.test.AndroidTestCase; import com.android.compatibility.common.util.PollingCheck; +import com.android.compatibility.common.util.CddTest; import java.util.concurrent.Callable; +@CddTest(requirement="7.4.2/C-1-1") public class WifiInfoTest extends AndroidTestCase { private static class MySync { int expectedState = STATE_NULL; diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 89daca21da..87239b4ca5 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -37,6 +37,7 @@ import android.provider.Settings; import android.test.AndroidTestCase; import android.util.Log; +import com.android.compatibility.common.util.CddTest; import com.android.compatibility.common.util.WifiConfigCreator; import java.net.HttpURLConnection; @@ -49,6 +50,7 @@ import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +@CddTest(requirement="7.4.2/C-1-1") public class WifiManagerTest extends AndroidTestCase { private static class MySync { int expectedState = STATE_NULL; @@ -586,6 +588,7 @@ public class WifiManagerTest extends AndroidTestCase { * * @throws Exception */ + @CddTest(requirement="7.4.2.4/C-1-1,C-1-2,C-2-1") public void testAddPasspointConfigWithUserCredential() throws Exception { if (!WifiFeature.isWifiSupported(getContext())) { // skip the test if WiFi is not supported @@ -600,6 +603,7 @@ public class WifiManagerTest extends AndroidTestCase { * * @throws Exception */ + @CddTest(requirement="7.4.2.4/C-1-1,C-1-2,C-2-1") public void testAddPasspointConfigWithCertCredential() throws Exception { if (!WifiFeature.isWifiSupported(getContext())) { // skip the test if WiFi is not supported @@ -614,6 +618,7 @@ public class WifiManagerTest extends AndroidTestCase { * * @throws Exception */ + @CddTest(requirement="7.4.2.4/C-1-1,C-1-2,C-2-1") public void testAddPasspointConfigWithSimCredential() throws Exception { if (!WifiFeature.isWifiSupported(getContext())) { // skip the test if WiFi is not supported diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java index 3cdd56af89..aeb1234dd3 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java @@ -21,6 +21,9 @@ import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.WifiLock; import android.test.AndroidTestCase; +import com.android.compatibility.common.util.CddTest; + +@CddTest(requirement="7.4.2/C-1-1") public class WifiManager_WifiLockTest extends AndroidTestCase { private static final String WIFI_TAG = "WifiManager_WifiLockTest"; From 6943e15b8cc826a0ea0ae6fa153fe3c511fd53d5 Mon Sep 17 00:00:00 2001 From: saurav subedi Date: Wed, 5 Sep 2018 17:32:32 -0700 Subject: [PATCH 0507/1109] DO NOT MERGE: CDD Annotations for Section: 7.4.7 Bug: 112612833 Test: make cts Change-Id: I7443794296f9364bc0e88e5ba3b717d6c01511a7 --- .../src/com/android/cts/net/hostside/DataSaverModeTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index 599a31ce1c..c24ca89e2f 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -22,6 +22,9 @@ import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELI import android.util.Log; +import com.android.compatibility.common.util.CddTest; + +@CddTest(requirement="7.4.7/C-1-1,H-1-1") public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase { private static final String[] REQUIRED_WHITELISTED_PACKAGES = { From 340047b18cd716c5aa3e26cbb697aad80e6637f6 Mon Sep 17 00:00:00 2001 From: Rebecca Silberstein Date: Fri, 27 Apr 2018 08:50:14 -0700 Subject: [PATCH 0508/1109] WifiManagerTest: allow for multiple modes Now that WifiService can/will support dual simultaneous mode operation, make sure the tests allow for it as well. Bug: 31346104 Bug: 115567184 Test: atest android.net.wifi.cts Change-Id: Id3aaacb3651568c18850a0fdf3832c0f52218cf2 Merged-In: Id3aaacb3651568c18850a0fdf3832c0f52218cf2 --- .../android/net/wifi/cts/WifiManagerTest.java | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 87239b4ca5..90540f4696 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -838,10 +838,9 @@ public class WifiManagerTest extends AndroidTestCase { TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot(); - // at this point, wifi should be off - assertFalse(mWifiManager.isWifiEnabled()); - stopLocalOnlyHotspot(callback, wifiEnabled); + + // wifi should either stay on, or come back on assertEquals(wifiEnabled, mWifiManager.isWifiEnabled()); } @@ -853,7 +852,7 @@ public class WifiManagerTest extends AndroidTestCase { * tethering is started. * Note: Location mode must be enabled for this test. */ - public void testSetWifiEnabledByAppDoesNotStopHotspot() { + public void testSetWifiEnabledByAppDoesNotStopHotspot() throws Exception { if (!WifiFeature.isWifiSupported(getContext())) { // skip the test if WiFi is not supported return; @@ -865,15 +864,18 @@ public class WifiManagerTest extends AndroidTestCase { boolean wifiEnabled = mWifiManager.isWifiEnabled(); + if (wifiEnabled) { + // disable wifi so we have something to turn on (some devices may be able to run + // simultaneous modes) + setWifiEnabled(false); + } + TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot(); - // at this point, wifi should be off - assertFalse(mWifiManager.isWifiEnabled()); // now we should fail to turn on wifi assertFalse(mWifiManager.setWifiEnabled(true)); stopLocalOnlyHotspot(callback, wifiEnabled); - assertEquals(wifiEnabled, mWifiManager.isWifiEnabled()); } /** @@ -897,9 +899,6 @@ public class WifiManagerTest extends AndroidTestCase { TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot(); - // at this point, wifi should be off - assertFalse(mWifiManager.isWifiEnabled()); - // now make a second request - this should fail. TestLocalOnlyHotspotCallback callback2 = new TestLocalOnlyHotspotCallback(mLOHSLock); try { @@ -908,9 +907,12 @@ public class WifiManagerTest extends AndroidTestCase { Log.d(TAG, "Caught the IllegalStateException we expected: called startLOHS twice"); caughtException = true; } + if (!caughtException) { + // second start did not fail, should clean up the hotspot. + stopLocalOnlyHotspot(callback2, wifiEnabled); + } assertTrue(caughtException); stopLocalOnlyHotspot(callback, wifiEnabled); - assertEquals(wifiEnabled, mWifiManager.isWifiEnabled()); } } From ab53484d7b7337ac6897facd74488411745041eb Mon Sep 17 00:00:00 2001 From: Jeff Vander Stoep Date: Wed, 11 Jul 2018 15:46:21 -0700 Subject: [PATCH 0509/1109] VpnTest: test getConnectionOwnerUid API Test connection->UID resolution for both UDP and TCP connections. Bug: 9496886 Bug: 109758967 Test: atest HostsideVpnTests Change-Id: Ic17c64df74f65d788fd3d95a25af3c5b44946881 --- .../com/android/cts/net/hostside/VpnTest.java | 49 +++++++++++++++++-- .../com/android/cts/net/HostsideVpnTests.java | 4 ++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java index bc982cec78..1ba701de29 100755 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java @@ -16,6 +16,7 @@ package com.android.cts.net.hostside; +import static android.os.Process.INVALID_UID; import static android.system.OsConstants.*; import android.content.Intent; @@ -36,6 +37,7 @@ import android.support.test.uiautomator.UiScrollable; import android.support.test.uiautomator.UiSelector; import android.system.ErrnoException; import android.system.Os; +import android.system.OsConstants; import android.system.StructPollfd; import android.test.InstrumentationTestCase; import android.test.MoreAsserts; @@ -353,7 +355,7 @@ public class VpnTest extends InstrumentationTestCase { MoreAsserts.assertEquals(data, read); } - private static void checkTcpReflection(String to, String expectedFrom) throws IOException { + private void checkTcpReflection(String to, String expectedFrom) throws IOException { // Exercise TCP over the VPN by "connecting to ourselves". We open a server socket and a // client socket, and connect the client socket to a remote host, with the port of the // server socket. The PacketReflector reflects the packets, changing the source addresses @@ -391,7 +393,8 @@ public class VpnTest extends InstrumentationTestCase { // Accept the connection on the server side. listen.setSoTimeout(SOCKET_TIMEOUT_MS); server = listen.accept(); - + checkConnectionOwnerUidTcp(client); + checkConnectionOwnerUidTcp(server); // Check that the source and peer addresses are as expected. assertEquals(expectedFrom, client.getLocalAddress().getHostAddress()); assertEquals(expectedFrom, server.getLocalAddress().getHostAddress()); @@ -424,7 +427,23 @@ public class VpnTest extends InstrumentationTestCase { } } - private static void checkUdpEcho(String to, String expectedFrom) throws IOException { + private void checkConnectionOwnerUidUdp(DatagramSocket s, boolean expectSuccess) { + final int expectedUid = expectSuccess ? Process.myUid() : INVALID_UID; + InetSocketAddress loc = new InetSocketAddress(s.getLocalAddress(), s.getLocalPort()); + InetSocketAddress rem = new InetSocketAddress(s.getInetAddress(), s.getPort()); + int uid = mCM.getConnectionOwnerUid(OsConstants.IPPROTO_UDP, loc, rem); + assertEquals(expectedUid, uid); + } + + private void checkConnectionOwnerUidTcp(Socket s) { + final int expectedUid = Process.myUid(); + InetSocketAddress loc = new InetSocketAddress(s.getLocalAddress(), s.getLocalPort()); + InetSocketAddress rem = new InetSocketAddress(s.getInetAddress(), s.getPort()); + int uid = mCM.getConnectionOwnerUid(OsConstants.IPPROTO_TCP, loc, rem); + assertEquals(expectedUid, uid); + } + + private void checkUdpEcho(String to, String expectedFrom) throws IOException { DatagramSocket s; InetAddress address = InetAddress.getByName(to); if (address instanceof Inet6Address) { // http://b/18094870 @@ -448,6 +467,7 @@ public class VpnTest extends InstrumentationTestCase { try { if (expectedFrom != null) { s.send(p); + checkConnectionOwnerUidUdp(s, true); s.receive(p); MoreAsserts.assertEquals(data, p.getData()); } else { @@ -455,7 +475,9 @@ public class VpnTest extends InstrumentationTestCase { s.send(p); s.receive(p); fail("Received unexpected reply"); - } catch(IOException expected) {} + } catch (IOException expected) { + checkConnectionOwnerUidUdp(s, false); + } } } finally { s.close(); @@ -580,4 +602,23 @@ public class VpnTest extends InstrumentationTestCase { checkNoTrafficOnVpn(); } + + public void testGetConnectionOwnerUidSecurity() throws Exception { + + if (!supportedHardware()) return; + + DatagramSocket s; + InetAddress address = InetAddress.getByName("localhost"); + s = new DatagramSocket(); + s.setSoTimeout(SOCKET_TIMEOUT_MS); + s.connect(address, 7); + InetSocketAddress loc = new InetSocketAddress(s.getLocalAddress(), s.getLocalPort()); + InetSocketAddress rem = new InetSocketAddress(s.getInetAddress(), s.getPort()); + try { + int uid = mCM.getConnectionOwnerUid(OsConstants.IPPROTO_TCP, loc, rem); + fail("Only an active VPN app may call this API."); + } catch (SecurityException expected) { + return; + } + } } diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java index 69b07af193..853668c719 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java @@ -44,4 +44,8 @@ public class HostsideVpnTests extends HostsideNetworkTestCase { public void testAppDisallowed() throws Exception { runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testAppDisallowed"); } + + public void testGetConnectionOwnerUidSecurity() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testGetConnectionOwnerUidSecurity"); + } } From cd79fb2af625ba62241652f91f13794b0316dc27 Mon Sep 17 00:00:00 2001 From: saurav subedi Date: Fri, 7 Sep 2018 10:57:01 -0700 Subject: [PATCH 0510/1109] DO NOT MERGE:CDD Annotation for 7.4.7/C-2-1 Devices that don't provide data saver mode must return RESTRICT_BACKGROUND_STATUS_DISABLED for the ConnectivityManager#getRestrictBackgroundStatus() Bug: 116495679 Test: make cts Change-Id: I81b52c9d26afcf51a7e416d20589c9c7cfb878f6 --- .../app/src/com/android/cts/net/hostside/DataSaverModeTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index c24ca89e2f..c3962fbbc3 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -24,7 +24,7 @@ import android.util.Log; import com.android.compatibility.common.util.CddTest; -@CddTest(requirement="7.4.7/C-1-1,H-1-1") +@CddTest(requirement="7.4.7/C-1-1,H-1-1,C-2-1") public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase { private static final String[] REQUIRED_WHITELISTED_PACKAGES = { From ff39f3fa71bbb38ea0ca37f67f6e0557e6a2d962 Mon Sep 17 00:00:00 2001 From: Jeff Vander Stoep Date: Thu, 20 Sep 2018 14:38:52 -0700 Subject: [PATCH 0511/1109] Move tests requiring /proc/sys/net access to hostside This access is going away for apps. Move these tests to hostside tests to be executed by the shell domain. Test: atest cts/hostsidetests/net/src/com/android/cts/net/ProcNetTest.java Test: atest android.net.cts.ConnectivityManagerTest Test: atest android.net.cts.IpSecSysctlTest Test: atest android.net.cts.MultinetworkSysctlTest Bug: 116053204 Change-Id: Id7e867184dd344a2d877515956e76019d627788b --- .../src/com/android/cts/net/ProcNetTest.java | 183 ++++++++++++++++++ .../net/cts/ConnectivityManagerTest.java | 65 ------- .../src/android/net/cts/IpSecSysctlTest.java | 45 ----- .../net/cts/MultinetworkSysctlTest.java | 73 ------- .../src/android/net/cts/SysctlBaseTest.java | 70 ------- 5 files changed, 183 insertions(+), 253 deletions(-) create mode 100644 tests/cts/hostside/src/com/android/cts/net/ProcNetTest.java delete mode 100644 tests/cts/net/src/android/net/cts/IpSecSysctlTest.java delete mode 100644 tests/cts/net/src/android/net/cts/MultinetworkSysctlTest.java delete mode 100644 tests/cts/net/src/android/net/cts/SysctlBaseTest.java 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()); - } -} From d502c991233b62f6fb12c96b6d79f1aef4cb9353 Mon Sep 17 00:00:00 2001 From: Jeff Vander Stoep Date: Fri, 28 Sep 2018 10:36:12 -0700 Subject: [PATCH 0512/1109] Refactor duplicate code into single function Address comments in aosp/763607 Bug: 116053204 Test: atest ProcNetTest Change-Id: Iec8b58b6499a7764b3757d4dd820e1f45a65e814 --- .../src/com/android/cts/net/ProcNetTest.java | 58 +++++++------------ 1 file changed, 22 insertions(+), 36 deletions(-) diff --git a/tests/cts/hostside/src/com/android/cts/net/ProcNetTest.java b/tests/cts/hostside/src/com/android/cts/net/ProcNetTest.java index 1335eb8011..19e61c62a0 100644 --- a/tests/cts/hostside/src/com/android/cts/net/ProcNetTest.java +++ b/tests/cts/hostside/src/com/android/cts/net/ProcNetTest.java @@ -22,16 +22,11 @@ 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; +import java.util.Arrays; +import java.util.List; +import java.util.ArrayList; /** * Host-side tests for values in /proc/net. @@ -62,6 +57,7 @@ public class ProcNetTest extends DeviceTestCase implements IBuildReceiver, IDevi private static final int IPV6_WIFI_ROUTER_SOLICITATIONS = -1; private ITestDevice mDevice; private IBuildInfo mBuild; + private String[] mSysctlDirs; /** * {@inheritDoc} @@ -83,8 +79,19 @@ public class ProcNetTest extends DeviceTestCase implements IBuildReceiver, IDevi @Override protected void setUp() throws Exception { super.setUp(); + mSysctlDirs = getSysctlDirs(); } + private String[] getSysctlDirs() throws Exception { + String interfaceDirs[] = mDevice.executeAdbCommand("shell", "ls", "-1", + IPV6_SYSCTL_DIR).split("\n"); + List interfaceDirsList = new ArrayList(Arrays.asList(interfaceDirs)); + interfaceDirsList.remove("all"); + interfaceDirsList.remove("lo"); + return interfaceDirsList.toArray(new String[interfaceDirsList.size()]); + } + + protected void assertLess(String sysctl, int a, int b) { assertTrue("value of " + sysctl + ": expected < " + b + " but was: " + a, a < b); } @@ -113,15 +120,7 @@ public class ProcNetTest extends DeviceTestCase implements IBuildReceiver, IDevi /** * 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 + * enabled. */ public void testProcSysctls() throws Exception { for (String sysctl : GLOBAL_SYSCTLS) { @@ -129,26 +128,18 @@ public class ProcNetTest extends DeviceTestCase implements IBuildReceiver, IDevi 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; - } + for (String interfaceDir : mSysctlDirs) { 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 */ + /** + * 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; - } + for (String interfaceDir : mSysctlDirs) { 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); @@ -163,12 +154,7 @@ public class ProcNetTest extends DeviceTestCase implements IBuildReceiver, IDevi * 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; - } + for (String interfaceDir : mSysctlDirs) { String path = IPV6_SYSCTL_DIR + "/" + interfaceDir + "/" + "router_solicitations"; int value = readIntFromPath(path); assertEquals(IPV6_WIFI_ROUTER_SOLICITATIONS, value); From 7f494f69183ac09fc94573e62f6eaa7dbc0ed054 Mon Sep 17 00:00:00 2001 From: xshu Date: Fri, 7 Sep 2018 11:30:10 -0700 Subject: [PATCH 0513/1109] CTS: Location scan is not disabled at screen off Location Wi-Fi scanning should not be turned off when the screen turns off. Bug: 113876483 Test: Run CTS, manually toggle location Wi-Fi scanning off right after the screen turns on and observe failure. Test: Run CTS with location Wi-Fi scanning initially turned off and observe failure. Test: Run CTS with location Wi-Fi scanning initially turned on and observe success. Change-Id: I092a3854b6365de72c2cfe38a55a0e1cedfcabd9 --- .../android/net/wifi/cts/WifiManagerTest.java | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index ea31fdffd6..3b8ad6ca65 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -38,6 +38,8 @@ import android.net.wifi.hotspot2.pps.HomeSp; import android.os.Process; import android.os.SystemClock; import android.provider.Settings; +import android.support.test.InstrumentationRegistry; +import android.support.test.uiautomator.UiDevice; import android.test.AndroidTestCase; import android.util.ArraySet; import android.util.Log; @@ -66,6 +68,7 @@ public class WifiManagerTest extends AndroidTestCase { private List mScanResults = null; private NetworkInfo mNetworkInfo; private Object mLOHSLock = new Object(); + private UiDevice mUiDevice; // Please refer to WifiManager private static final int MIN_RSSI = -100; @@ -90,6 +93,7 @@ public class WifiManagerTest extends AndroidTestCase { private static final int TIMEOUT_MSEC = 6000; private static final int WAIT_MSEC = 60; private static final int DURATION = 10000; + private static final int DURATION_SCREEN_TOGGLE = 2000; private static final int WIFI_SCAN_TEST_INTERVAL_MILLIS = 60 * 1000; private static final int WIFI_SCAN_TEST_CACHE_DELAY_MILLIS = 3 * 60 * 1000; private static final int WIFI_SCAN_TEST_ITERATIONS = 5; @@ -162,6 +166,8 @@ public class WifiManagerTest extends AndroidTestCase { mWifiLock.acquire(); if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true); + mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); + turnScreenOnNoDelay(); Thread.sleep(DURATION); assertTrue(mWifiManager.isWifiEnabled()); synchronized (mMySync) { @@ -1072,4 +1078,88 @@ public class WifiManagerTest extends AndroidTestCase { } } } + + private void turnScreenOnNoDelay() throws Exception { + mUiDevice.executeShellCommand("input keyevent KEYCODE_WAKEUP"); + mUiDevice.executeShellCommand("wm dismiss-keyguard"); + } + + private void turnScreenOn() throws Exception { + turnScreenOnNoDelay(); + // Since the screen on/off intent is ordered, they will not be sent right now. + Thread.sleep(DURATION_SCREEN_TOGGLE); + } + + private void turnScreenOff() throws Exception { + mUiDevice.executeShellCommand("input keyevent KEYCODE_SLEEP"); + // Since the screen on/off intent is ordered, they will not be sent right now. + Thread.sleep(DURATION_SCREEN_TOGGLE); + } + + /** + * Verify that Wi-Fi scanning is not turned off when the screen turns off while wifi is disabled + * but location is on. + * @throws Exception + */ + public void testScreenOffDoesNotTurnOffWifiScanningWhenWifiDisabled() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + if (!hasLocationFeature()) { + // skip the test if location is not supported + return; + } + if (!isLocationEnabled()) { + fail("Please enable location for this test - since Marshmallow WiFi scan results are" + + " empty when location is disabled!"); + } + if(!mWifiManager.isScanAlwaysAvailable()) { + fail("Please enable Wi-Fi scanning for this test!"); + } + setWifiEnabled(false); + turnScreenOn(); + assertWifiScanningIsOn(); + // Toggle screen and verify Wi-Fi scanning is still on. + turnScreenOff(); + assertWifiScanningIsOn(); + turnScreenOn(); + assertWifiScanningIsOn(); + } + + /** + * Verify that Wi-Fi scanning is not turned off when the screen turns off while wifi is enabled. + * @throws Exception + */ + public void testScreenOffDoesNotTurnOffWifiScanningWhenWifiEnabled() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + if (!hasLocationFeature()) { + // skip the test if location is not supported + return; + } + if (!isLocationEnabled()) { + fail("Please enable location for this test - since Marshmallow WiFi scan results are" + + " empty when location is disabled!"); + } + if(!mWifiManager.isScanAlwaysAvailable()) { + fail("Please enable Wi-Fi scanning for this test!"); + } + setWifiEnabled(true); + turnScreenOn(); + assertWifiScanningIsOn(); + // Toggle screen and verify Wi-Fi scanning is still on. + turnScreenOff(); + assertWifiScanningIsOn(); + turnScreenOn(); + assertWifiScanningIsOn(); + } + + private void assertWifiScanningIsOn() { + if(!mWifiManager.isScanAlwaysAvailable()) { + fail("Wi-Fi scanning should be on."); + } + } } From c7758c460ce66ae130ad7abfa9eb7bae3d495e95 Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Mon, 1 Oct 2018 14:02:44 -0700 Subject: [PATCH 0514/1109] [CTS] Clarify CTS assert message for missing RTT AP support Add a much more verbose message for the common failure case in which the CTS is run without an AP which supports IEEE 802.11mc / RTT. That may help speed up issue resolution. Bug: 116849381 Test: atest WifiRttTest Change-Id: I4ea3fbe17563f0087a013cbf48f7f601fec7e363 --- .../cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java b/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java index 74a0c3dfbc..20791c068e 100644 --- a/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java +++ b/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java @@ -16,11 +16,9 @@ package android.net.wifi.rtt.cts; -import android.content.IntentFilter; import android.net.wifi.ScanResult; import android.net.wifi.rtt.RangingRequest; import android.net.wifi.rtt.RangingResult; -import android.net.wifi.rtt.WifiRttManager; import com.android.compatibility.common.util.DeviceReportLog; import com.android.compatibility.common.util.ResultType; @@ -64,7 +62,10 @@ public class WifiRttTest extends TestBase { // Scan for IEEE 802.11mc supporting APs ScanResult testAp = scanForTestAp(NUM_SCANS_SEARCHING_FOR_IEEE80211MC_AP); - assertTrue("Cannot find test AP", testAp != null); + assertTrue( + "Cannot find any test APs which support RTT / IEEE 802.11mc - please verify that " + + "your test setup includes them!", + testAp != null); // Perform RTT operations RangingRequest request = new RangingRequest.Builder().addAccessPoint(testAp).build(); From f99027bf27c683164ff74a325eeb96c8b0624ca3 Mon Sep 17 00:00:00 2001 From: Pavel Maltsev Date: Fri, 5 Oct 2018 10:49:48 -0700 Subject: [PATCH 0515/1109] CTS to verify local-only hotspot started at 2Ghz The only exception is automotive builds which may start local-only hotspot at 5Ghz Bug:115666270 Test: run cts -m CtsNetTestCases -t android.net.wifi.cts.WifiManagerTest#testStartLocalOnlyHotspotSuccess Change-Id: Ic3df22dab4ee93b531b92e6ed38adfa2b75880c7 --- .../net/src/android/net/wifi/cts/WifiManagerTest.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 3b8ad6ca65..b09d4581b9 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -408,6 +408,10 @@ public class WifiManagerTest extends AndroidTestCase { return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION); } + private boolean hasAutomotiveFeature() { + return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); + } + /** * test point of wifiManager NetWork: * 1.add NetWork @@ -847,6 +851,11 @@ public class WifiManagerTest extends AndroidTestCase { // check if we got the callback assertTrue(callback.onStartedCalled); assertNotNull(callback.reservation.getWifiConfiguration()); + if (!hasAutomotiveFeature()) { + assertEquals( + WifiConfiguration.AP_BAND_2GHZ, + callback.reservation.getWifiConfiguration().apBand); + } assertFalse(callback.onFailedCalled); assertFalse(callback.onStoppedCalled); } From 0b72fa9cfe8ebe5726057e238a1eaeb948eb5d27 Mon Sep 17 00:00:00 2001 From: Neil Fuller Date: Thu, 4 Oct 2018 10:52:12 +0100 Subject: [PATCH 0516/1109] Remove explicit dependency on conscrypt The dependency is unnecessary as by default conscrypt is included in the "standard libraries". Test: build Bug: 113148576 Change-Id: I30d68049215c61931bdd7aa5e2a0f125e6d1bf90 --- tests/cts/net/Android.mk | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index 1430071997..6967adb57b 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -26,7 +26,6 @@ LOCAL_MULTILIB := both LOCAL_JAVA_LIBRARIES := \ voip-common \ - conscrypt \ org.apache.http.legacy \ android.test.base.stubs \ From 2a41b1cdda8f5b3647619d10a0c0f859a79cfb74 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Thu, 18 Oct 2018 17:20:47 +0900 Subject: [PATCH 0517/1109] Add Uri tests for IPv6 literal adresses Bug: 25540738 Test: this Change-Id: Id63a5dd17293014218df78bcb440993cc5f3beb8 --- .../cts/net/src/android/net/cts/UriTest.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/UriTest.java b/tests/cts/net/src/android/net/cts/UriTest.java index 080f00bee2..1dfe43dd7f 100644 --- a/tests/cts/net/src/android/net/cts/UriTest.java +++ b/tests/cts/net/src/android/net/cts/UriTest.java @@ -22,6 +22,7 @@ import android.os.Parcel; import android.test.AndroidTestCase; import java.io.File; import java.util.Arrays; +import java.util.ArrayList; public class UriTest extends AndroidTestCase { public void testParcelling() { @@ -73,6 +74,12 @@ public class UriTest extends AndroidTestCase { assertEquals("new", b.getFragment()); assertEquals("bar", b.getSchemeSpecificPart()); assertEquals("foo", b.getScheme()); + + a = Uri.fromParts("scheme", "[2001:db8::dead:e1f]/foo", "bar"); + b = a.buildUpon().fragment("qux").build(); + assertEquals("qux", b.getFragment()); + assertEquals("[2001:db8::dead:e1f]/foo", b.getSchemeSpecificPart()); + assertEquals("scheme", b.getScheme()); } public void testStringUri() { @@ -120,6 +127,38 @@ public class UriTest extends AndroidTestCase { assertEquals("a.foo.com", uri.getHost()); assertEquals(-1, uri.getPort()); assertEquals("\\.example.com/path", uri.getPath()); + + uri = Uri.parse("https://[2001:db8::dead:e1f]/foo"); + assertEquals("[2001:db8::dead:e1f]", uri.getAuthority()); + assertNull(uri.getUserInfo()); + assertEquals("[2001:db8::dead:e1f]", uri.getHost()); + assertEquals(-1, uri.getPort()); + assertEquals("/foo", uri.getPath()); + assertEquals(null, uri.getFragment()); + assertEquals("//[2001:db8::dead:e1f]/foo", uri.getSchemeSpecificPart()); + + uri = Uri.parse("https://[2001:db8::dead:e1f]/#foo"); + assertEquals("[2001:db8::dead:e1f]", uri.getAuthority()); + assertNull(uri.getUserInfo()); + assertEquals("[2001:db8::dead:e1f]", uri.getHost()); + assertEquals(-1, uri.getPort()); + assertEquals("/", uri.getPath()); + assertEquals("foo", uri.getFragment()); + assertEquals("//[2001:db8::dead:e1f]/", uri.getSchemeSpecificPart()); + + uri = Uri.parse( + "https://some:user@[2001:db8::dead:e1f]:1234/foo?corge=thud&corge=garp#bar"); + assertEquals("some:user@[2001:db8::dead:e1f]:1234", uri.getAuthority()); + assertEquals("some:user", uri.getUserInfo()); + assertEquals("[2001:db8::dead:e1f]", uri.getHost()); + assertEquals(1234, uri.getPort()); + assertEquals("/foo", uri.getPath()); + assertEquals("bar", uri.getFragment()); + assertEquals("//some:user@[2001:db8::dead:e1f]:1234/foo?corge=thud&corge=garp", + uri.getSchemeSpecificPart()); + assertEquals("corge=thud&corge=garp", uri.getQuery()); + assertEquals("thud", uri.getQueryParameter("corge")); + assertEquals(Arrays.asList("thud", "garp"), uri.getQueryParameters("corge")); } public void testCompareTo() { @@ -174,6 +213,7 @@ public class UriTest extends AndroidTestCase { assertEncodeDecodeRoundtripExact("Bob::"); assertEncodeDecodeRoundtripExact("Bob:"); assertEncodeDecodeRoundtripExact("::Bob::"); + assertEncodeDecodeRoundtripExact("https:/some:user@[2001:db8::dead:e1f]:1234/foo#bar"); } private static void assertEncodeDecodeRoundtripExact(String s) { From c1ba8dd9acd0e91b19d131e95961279fa6ac2eaa Mon Sep 17 00:00:00 2001 From: Tony Huang Date: Thu, 8 Nov 2018 17:13:07 +0800 Subject: [PATCH 0518/1109] Add test for Uri.toSafeString Due to exposing api of toSafeString, add coresponding testing for it. Bug: 119153962 Test: atest UriTest Change-Id: I156b2b03ee9c1d4a05ac635b4f684c5b4dcfca08 --- .../cts/net/src/android/net/cts/UriTest.java | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/UriTest.java b/tests/cts/net/src/android/net/cts/UriTest.java index 1dfe43dd7f..5344f93df9 100644 --- a/tests/cts/net/src/android/net/cts/UriTest.java +++ b/tests/cts/net/src/android/net/cts/UriTest.java @@ -504,4 +504,78 @@ public class UriTest extends AndroidTestCase { Uri.parse("HTTP://USER@WWW.ANDROID.COM:100/ABOUT?foo=blah@bar=bleh#c") .normalizeScheme()); } + + public void testToSafeString_tel() { + checkToSafeString("tel:xxxxxx", "tel:Google"); + checkToSafeString("tel:xxxxxxxxxx", "tel:1234567890"); + checkToSafeString("tEl:xxx.xxx-xxxx", "tEl:123.456-7890"); + } + + public void testToSafeString_sip() { + checkToSafeString("sip:xxxxxxx@xxxxxxx.xxxxxxxx", "sip:android@android.com:1234"); + checkToSafeString("sIp:xxxxxxx@xxxxxxx.xxx", "sIp:android@android.com"); + } + + public void testToSafeString_sms() { + checkToSafeString("sms:xxxxxx", "sms:123abc"); + checkToSafeString("smS:xxx.xxx-xxxx", "smS:123.456-7890"); + } + + public void testToSafeString_smsto() { + checkToSafeString("smsto:xxxxxx", "smsto:123abc"); + checkToSafeString("SMSTo:xxx.xxx-xxxx", "SMSTo:123.456-7890"); + } + + public void testToSafeString_mailto() { + checkToSafeString("mailto:xxxxxxx@xxxxxxx.xxx", "mailto:android@android.com"); + checkToSafeString("Mailto:xxxxxxx@xxxxxxx.xxxxxxxxxx", + "Mailto:android@android.com/secret"); + } + + public void testToSafeString_nfc() { + checkToSafeString("nfc:xxxxxx", "nfc:123abc"); + checkToSafeString("nfc:xxx.xxx-xxxx", "nfc:123.456-7890"); + checkToSafeString("nfc:xxxxxxx@xxxxxxx.xxx", "nfc:android@android.com"); + } + + public void testToSafeString_http() { + checkToSafeString("http://www.android.com/...", "http://www.android.com"); + checkToSafeString("HTTP://www.android.com/...", "HTTP://www.android.com"); + checkToSafeString("http://www.android.com/...", "http://www.android.com/"); + checkToSafeString("http://www.android.com/...", "http://www.android.com/secretUrl?param"); + checkToSafeString("http://www.android.com/...", + "http://user:pwd@www.android.com/secretUrl?param"); + checkToSafeString("http://www.android.com/...", + "http://user@www.android.com/secretUrl?param"); + checkToSafeString("http://www.android.com/...", "http://www.android.com/secretUrl?param"); + checkToSafeString("http:///...", "http:///path?param"); + checkToSafeString("http:///...", "http://"); + checkToSafeString("http://:12345/...", "http://:12345/"); + } + + public void testToSafeString_https() { + checkToSafeString("https://www.android.com/...", "https://www.android.com/secretUrl?param"); + checkToSafeString("https://www.android.com:8443/...", + "https://user:pwd@www.android.com:8443/secretUrl?param"); + checkToSafeString("https://www.android.com/...", "https://user:pwd@www.android.com"); + checkToSafeString("Https://www.android.com/...", "Https://user:pwd@www.android.com"); + } + + public void testToSafeString_ftp() { + checkToSafeString("ftp://ftp.android.com/...", "ftp://ftp.android.com/"); + checkToSafeString("ftP://ftp.android.com/...", "ftP://anonymous@ftp.android.com/"); + checkToSafeString("ftp://ftp.android.com:2121/...", + "ftp://root:love@ftp.android.com:2121/"); + } + + public void testToSafeString_notSupport() { + checkToSafeString("unsupported://ajkakjah/askdha/secret?secret", + "unsupported://ajkakjah/askdha/secret?secret"); + checkToSafeString("unsupported:ajkakjah/askdha/secret?secret", + "unsupported:ajkakjah/askdha/secret?secret"); + } + + private void checkToSafeString(String expectedSafeString, String original) { + assertEquals(expectedSafeString, Uri.parse(original).toSafeString()); + } } From 9d7688dd9e7d0d4007fee8693c65ef0beb56748d Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Thu, 1 Nov 2018 15:14:44 -0700 Subject: [PATCH 0519/1109] WifiManagerTest: Remove tests for deprecated API's Remove/Modify tests that are invoking the deprecated API's. Use the shell automator to toggle wifi state. CTS tests for the replacement API surface (i.e NetworkRequest & NetworkSuggestion) will be added later. Bug: 115504728 Test: `atest android.net.wifi.cts.WifiManagerTest` Change-Id: I04b3e1572ddfd31b28639185e5cf54dd70a1ae42 --- .../android/net/wifi/cts/WifiManagerTest.java | 187 +++--------------- 1 file changed, 30 insertions(+), 157 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index b09d4581b9..bfb9970bd3 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -41,9 +41,11 @@ import android.provider.Settings; import android.support.test.InstrumentationRegistry; import android.support.test.uiautomator.UiDevice; import android.test.AndroidTestCase; +import android.text.TextUtils; import android.util.ArraySet; import android.util.Log; +import com.android.compatibility.common.util.SystemUtil; import com.android.compatibility.common.util.WifiConfigCreator; import java.net.HttpURLConnection; @@ -83,9 +85,6 @@ public class WifiManagerTest extends AndroidTestCase { private static final String TAG = "WifiManagerTest"; private static final String SSID1 = "\"WifiManagerTest\""; - private static final String SSID2 = "\"WifiManagerTestModified\""; - private static final String PROXY_TEST_SSID = "SomeProxyAp"; - private static final String ADD_NETWORK_EXCEPTION_SUBSTR = "addNetwork"; // A full single scan duration is about 6-7 seconds if country code is set // to US. If country code is set to world mode (00), we would expect a scan // duration of roughly 8 seconds. So we set scan timeout as 9 seconds here. @@ -198,8 +197,8 @@ public class WifiManagerTest extends AndroidTestCase { } else { mMySync.expectedState = (enable ? STATE_WIFI_ENABLED : STATE_WIFI_DISABLED); } - // now trigger the change - assertTrue(mWifiManager.setWifiEnabled(enable)); + // now trigger the change using shell commands. + SystemUtil.runShellCommand("svc wifi " + (enable ? "enable" : "disable")); waitForExpectedWifiState(enable); } } @@ -274,20 +273,13 @@ public class WifiManagerTest extends AndroidTestCase { } /** - * test point of wifiManager actions: - * 1.reconnect - * 2.reassociate - * 3.disconnect - * 4.createWifiLock + * Test creation of WifiManager Lock. */ - public void testWifiManagerActions() throws Exception { + public void testWifiManagerLock() throws Exception { if (!WifiFeature.isWifiSupported(getContext())) { // skip the test if WiFi is not supported return; } - assertTrue(mWifiManager.reconnect()); - assertTrue(mWifiManager.reassociate()); - assertTrue(mWifiManager.disconnect()); final String TAG = "Test"; assertNotNull(mWifiManager.createWifiLock(TAG)); assertNotNull(mWifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, TAG)); @@ -412,125 +404,6 @@ public class WifiManagerTest extends AndroidTestCase { return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); } - /** - * test point of wifiManager NetWork: - * 1.add NetWork - * 2.update NetWork - * 3.remove NetWork - * 4.enable NetWork - * 5.disable NetWork - * 6.configured Networks - * 7.save configure; - */ - public void testWifiManagerNetWork() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - - // store the list of enabled networks, so they can be re-enabled after test completes - Set enabledSsids = getEnabledNetworks(mWifiManager.getConfiguredNetworks()); - try { - WifiConfiguration wifiConfiguration; - // add a WifiConfig - final int notExist = -1; - List wifiConfiguredNetworks = mWifiManager.getConfiguredNetworks(); - int pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); - if (notExist != pos) { - wifiConfiguration = wifiConfiguredNetworks.get(pos); - mWifiManager.removeNetwork(wifiConfiguration.networkId); - } - pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); - assertEquals(notExist, pos); - final int size = wifiConfiguredNetworks.size(); - - wifiConfiguration = new WifiConfiguration(); - wifiConfiguration.SSID = SSID1; - wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); - int netId = mWifiManager.addNetwork(wifiConfiguration); - assertTrue(existSSID(SSID1)); - - wifiConfiguredNetworks = mWifiManager.getConfiguredNetworks(); - assertEquals(size + 1, wifiConfiguredNetworks.size()); - pos = findConfiguredNetworks(SSID1, wifiConfiguredNetworks); - assertTrue(notExist != pos); - - // Enable & disable network - boolean disableOthers = true; - assertTrue(mWifiManager.enableNetwork(netId, disableOthers)); - wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); - assertEquals(Status.ENABLED, wifiConfiguration.status); - - assertTrue(mWifiManager.disableNetwork(netId)); - wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos); - assertEquals(Status.DISABLED, wifiConfiguration.status); - - // Update a WifiConfig - wifiConfiguration = wifiConfiguredNetworks.get(pos); - wifiConfiguration.SSID = SSID2; - netId = mWifiManager.updateNetwork(wifiConfiguration); - assertFalse(existSSID(SSID1)); - assertTrue(existSSID(SSID2)); - - // Remove a WifiConfig - assertTrue(mWifiManager.removeNetwork(netId)); - assertFalse(mWifiManager.removeNetwork(notExist)); - assertFalse(existSSID(SSID1)); - assertFalse(existSSID(SSID2)); - - assertTrue(mWifiManager.saveConfiguration()); - } finally { - reEnableNetworks(enabledSsids, mWifiManager.getConfiguredNetworks()); - mWifiManager.saveConfiguration(); - } - } - - /** - * Verifies that addNetwork() fails for WifiConfigurations containing a non-null http proxy when - * the caller doesn't have OVERRIDE_WIFI_CONFIG permission, DeviceOwner or ProfileOwner device - * management policies - */ - public void testSetHttpProxy_PermissionFail() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - WifiConfigCreator configCreator = new WifiConfigCreator(getContext()); - boolean exceptionThrown = false; - try { - configCreator.addHttpProxyNetworkVerifyAndRemove( - PROXY_TEST_SSID, TEST_PAC_URL); - } catch (IllegalStateException e) { - // addHttpProxyNetworkVerifyAndRemove throws three IllegalStateException, - // expect it to throw for the addNetwork operation - if (e.getMessage().contains(ADD_NETWORK_EXCEPTION_SUBSTR)) { - exceptionThrown = true; - } - } - assertTrue(exceptionThrown); - } - - private Set getEnabledNetworks(List configuredNetworks) { - Set ssids = new HashSet(); - for (WifiConfiguration wifiConfig : configuredNetworks) { - if (Status.ENABLED == wifiConfig.status || Status.CURRENT == wifiConfig.status) { - ssids.add(wifiConfig.SSID); - Log.i(TAG, String.format("remembering enabled network %s", wifiConfig.SSID)); - } - } - return ssids; - } - - private void reEnableNetworks(Set enabledSsids, - List configuredNetworks) { - for (WifiConfiguration wifiConfig : configuredNetworks) { - if (enabledSsids.contains(wifiConfig.SSID)) { - mWifiManager.enableNetwork(wifiConfig.networkId, false); - Log.i(TAG, String.format("re-enabling network %s", wifiConfig.SSID)); - } - } - } - public void testSignal() { if (!WifiFeature.isWifiSupported(getContext())) { // skip the test if WiFi is not supported @@ -902,37 +775,37 @@ public class WifiManagerTest extends AndroidTestCase { } /** - * Verify calls to setWifiEnabled from a non-settings app while softap mode is active do not - * exit softap mode. - * - * This test uses the LocalOnlyHotspot API to enter softap mode. This should also be true when - * tethering is started. - * Note: Location mode must be enabled for this test. + * Verify calls to deprecated API's all fail for non-settings apps targeting >= Q SDK. */ - public void testSetWifiEnabledByAppDoesNotStopHotspot() throws Exception { + public void testDeprecatedApis() throws Exception { if (!WifiFeature.isWifiSupported(getContext())) { // skip the test if WiFi is not supported return; } - // check that softap mode is supported by the device - if (!mWifiManager.isPortableHotspotSupported()) { - return; - } + setWifiEnabled(true); + connectWifi(); // ensures that there is at-least 1 saved network on the device. + + WifiConfiguration wifiConfiguration = new WifiConfiguration(); + wifiConfiguration.SSID = SSID1; + wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); + + assertEquals(WifiConfiguration.INVALID_NETWORK_ID, + mWifiManager.addNetwork(wifiConfiguration)); + assertEquals(WifiConfiguration.INVALID_NETWORK_ID, + mWifiManager.updateNetwork(wifiConfiguration)); + assertFalse(mWifiManager.enableNetwork(0, true)); + assertFalse(mWifiManager.disableNetwork(0)); + assertFalse(mWifiManager.removeNetwork(0)); + assertFalse(mWifiManager.disconnect()); + assertFalse(mWifiManager.reconnect()); + assertFalse(mWifiManager.reassociate()); + assertTrue(mWifiManager.getConfiguredNetworks().isEmpty()); boolean wifiEnabled = mWifiManager.isWifiEnabled(); - - if (wifiEnabled) { - // disable wifi so we have something to turn on (some devices may be able to run - // simultaneous modes) - setWifiEnabled(false); - } - - TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot(); - - // now we should fail to turn on wifi - assertFalse(mWifiManager.setWifiEnabled(true)); - - stopLocalOnlyHotspot(callback, wifiEnabled); + // now we should fail to toggle wifi state. + assertFalse(mWifiManager.setWifiEnabled(!wifiEnabled)); + Thread.sleep(DURATION); + assertEquals(wifiEnabled, mWifiManager.isWifiEnabled()); } /** From d0a2b9d50a5b438e0e293a5f10176e5b57ed71dd Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Wed, 14 Nov 2018 14:58:07 -0800 Subject: [PATCH 0520/1109] WifiManagerTest: Test for new privileged permission Add a new test to ensure that the NETWORK_MANAGED_PROVISIONING is only granted to the correct app. Bug: 115980767 Test: atest WifiManagerTest Change-Id: Ifca1fcd81e201134bbb4173c3f142cca91ed49f9 --- .../android/net/wifi/cts/WifiManagerTest.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index b09d4581b9..40e25ad66c 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -99,6 +99,8 @@ public class WifiManagerTest extends AndroidTestCase { private static final int WIFI_SCAN_TEST_ITERATIONS = 5; private static final String TEST_PAC_URL = "http://www.example.com/proxy.pac"; + private static final String MANAGED_PROVISIONING_PACKAGE_NAME + = "com.android.managedprovisioning"; private IntentFilter mIntentFilter; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @@ -1088,6 +1090,41 @@ public class WifiManagerTest extends AndroidTestCase { } } + /** + * Verify that the {@link android.Manifest.permission#NETWORK_MANAGED_PROVISIONING} permission + * is only held by the device managed provisioning application. + *

    + * Only the ManagedProvisioning app should ever attempt to acquire this + * permission, since it would give those apps extremely broad access to connectivity + * functionality. The permission is intended to be granted to only the device managed + * provisioning. + */ + public void testNetworkManagedProvisioningPermission() { + final PackageManager pm = getContext().getPackageManager(); + + // TODO(b/115980767): Using hardcoded package name. Need a better mechanism to find the + // managed provisioning app. + // Ensure that the package exists. + final Intent intent = new Intent(Intent.ACTION_MAIN); + intent.setPackage(MANAGED_PROVISIONING_PACKAGE_NAME); + final ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DISABLED_COMPONENTS); + String validPkg = ""; + if (ri != null) { + validPkg = ri.activityInfo.packageName; + } + + final List holding = pm.getPackagesHoldingPermissions(new String[] { + android.Manifest.permission.NETWORK_MANAGED_PROVISIONING + }, PackageManager.MATCH_UNINSTALLED_PACKAGES); + for (PackageInfo pi : holding) { + if (!Objects.equals(pi.packageName, validPkg)) { + fail("The NETWORK_MANAGED_PROVISIONING permission must not be held by " + + pi.packageName + " and must be revoked for security reasons [" + + validPkg +"]"); + } + } + } + private void turnScreenOnNoDelay() throws Exception { mUiDevice.executeShellCommand("input keyevent KEYCODE_WAKEUP"); mUiDevice.executeShellCommand("wm dismiss-keyguard"); From de0f268f789222dd17d3c28c0f07656f2c168d81 Mon Sep 17 00:00:00 2001 From: markchien Date: Wed, 21 Nov 2018 22:56:31 +0800 Subject: [PATCH 0521/1109] Exempt adb socket for hostside VpnTest Vpn test would destroy socket. If adb run over network, adb socket would be killed during Vpn test. Then, test stop due to adb disconnect. Bug: 119382723 Test: - build pass - run cts -m CtsHostsideNetworkTests -t com.android.cts.net.HostsideVpnTests Change-Id: I91b4ab018a9e7fc73dcb7969e4a6520d6b27d629 --- tests/cts/hostside/app/Android.mk | 3 ++- .../com/android/cts/net/hostside/VpnTest.java | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/tests/cts/hostside/app/Android.mk b/tests/cts/hostside/app/Android.mk index c03e70bcb0..62e0172817 100644 --- a/tests/cts/hostside/app/Android.mk +++ b/tests/cts/hostside/app/Android.mk @@ -19,7 +19,8 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests -LOCAL_SDK_VERSION := current +#LOCAL_SDK_VERSION := current +LOCAL_PRIVATE_PLATFORM_APIS := true LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util ctstestrunner ub-uiautomator \ CtsHostsideNetworkTestsAidl diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java index 1ba701de29..48f0afb61e 100755 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java @@ -30,6 +30,7 @@ import android.net.NetworkRequest; import android.net.VpnService; import android.os.ParcelFileDescriptor; import android.os.Process; +import android.os.SystemProperties; import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiObject; import android.support.test.uiautomator.UiObjectNotFoundException; @@ -559,6 +560,14 @@ public class VpnTest extends InstrumentationTestCase { public void testDefault() throws Exception { if (!supportedHardware()) return; + // If adb TCP port opened, this test may running by adb over network. + // All of socket would be destroyed in this test. So this test don't + // support adb over network, see b/119382723. + if (SystemProperties.getInt("persist.adb.tcp.port", -1) > -1 + || SystemProperties.getInt("service.adb.tcp.port", -1) > -1) { + Log.i(TAG, "adb is running over the network, so skip this test"); + return; + } FileDescriptor fd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS); @@ -576,6 +585,7 @@ public class VpnTest extends InstrumentationTestCase { FileDescriptor fd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS); + // Shell app must not be put in here or it would kill the ADB-over-network use case String allowedApps = mRemoteSocketFactoryClient.getPackageName() + "," + mPackageName; startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"}, new String[] {"192.0.2.0/24", "2001:db8::/32"}, @@ -593,6 +603,12 @@ public class VpnTest extends InstrumentationTestCase { FileDescriptor remoteFd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS); String disallowedApps = mRemoteSocketFactoryClient.getPackageName() + "," + mPackageName; + // If adb TCP port opened, this test may running by adb over TCP. + // Add com.android.shell appllication into blacklist to exclude adb socket for VPN test, + // see b/119382723. + // Note: The test don't support running adb over network for root device + disallowedApps = disallowedApps + ",com.android.shell"; + Log.i(TAG, "Append shell app to disallowedApps: " + disallowedApps); startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"}, new String[] {"192.0.2.0/24", "2001:db8::/32"}, "", disallowedApps); From 30897c29ef24b47a6a227d0716c811ee81e7bc59 Mon Sep 17 00:00:00 2001 From: Kweku Adams Date: Mon, 19 Nov 2018 14:53:32 -0800 Subject: [PATCH 0522/1109] Tests for app idle whitelisting. Ensuring that app idle network whitelisting works as expected and does not override other power saving restrictions. Bug: 117846754 Bug: 111423978 Test: atest CtsHostsideNetworkTests and atest NetworkPolicyManagerServiceTest Change-Id: I09172184e2fe543d6723639e5e62ae6afd5a6087 --- .../net/hostside/AbstractAppIdleTestCase.java | 19 +++++ ...ractRestrictBackgroundNetworkTestCase.java | 22 ++++- .../cts/net/hostside/MixedModesTest.java | 80 +++++++++++++++++++ ...ostsideRestrictBackgroundNetworkTests.java | 25 ++++++ 4 files changed, 142 insertions(+), 4 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java index 0e141c05ad..7bf7bd44f4 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java @@ -175,6 +175,25 @@ abstract class AbstractAppIdleTestCase extends AbstractRestrictBackgroundNetwork assertBackgroundNetworkAccess(true); } + public void testAppIdleNetworkAccess_idleWhitelisted() throws Exception { + if (!isSupported()) return; + + setAppIdle(true); + assertAppIdle(true); + assertBackgroundNetworkAccess(false); + + addAppIdleWhitelist(mUid); + assertBackgroundNetworkAccess(true); + + removeAppIdleWhitelist(mUid); + assertBackgroundNetworkAccess(false); + + // Make sure whitelisting a random app doesn't affect the tested app. + addAppIdleWhitelist(mUid + 1); + assertBackgroundNetworkAccess(false); + removeAppIdleWhitelist(mUid + 1); + } + public void testAppIdle_toast() throws Exception { if (!isSupported()) return; diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 5232372047..ec5a877757 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -26,10 +26,6 @@ import static android.os.BatteryManager.BATTERY_PLUGGED_WIRELESS; import static com.android.compatibility.common.util.SystemUtil.runShellCommand; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; - import android.app.ActivityManager; import android.app.Instrumentation; import android.app.NotificationManager; @@ -53,6 +49,10 @@ import android.test.InstrumentationTestCase; import android.text.TextUtils; import android.util.Log; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + /** * Superclass for tests related to background network restrictions. */ @@ -744,6 +744,20 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation assertRestrictBackground("restrict-background-blacklist", uid, expected); } + protected void addAppIdleWhitelist(int uid) throws Exception { + executeShellCommand("cmd netpolicy add app-idle-whitelist " + uid); + assertAppIdleWhitelist(uid, true); + } + + protected void removeAppIdleWhitelist(int uid) throws Exception { + executeShellCommand("cmd netpolicy remove app-idle-whitelist " + uid); + assertAppIdleWhitelist(uid, false); + } + + protected void assertAppIdleWhitelist(int uid, boolean expected) throws Exception { + assertRestrictBackground("app-idle-whitelist", uid, expected); + } + private void assertRestrictBackground(String list, int uid, boolean expected) throws Exception { final int maxTries = 5; boolean actual = false; diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java index 87f9d7738d..74875cd2c9 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java @@ -306,4 +306,84 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { setBatterySaverMode(false); } } + + /** + * Tests that the app idle whitelist works as expected when doze and appIdle mode are enabled. + */ + public void testDozeAndAppIdle_appIdleWhitelist() throws Exception { + if (!isSupported()) { + return; + } + + setDozeMode(true); + setAppIdle(true); + + try { + assertBackgroundNetworkAccess(false); + + // UID still shouldn't have access because of Doze. + addAppIdleWhitelist(mUid); + assertBackgroundNetworkAccess(false); + + removeAppIdleWhitelist(mUid); + assertBackgroundNetworkAccess(false); + } finally { + setAppIdle(false); + setDozeMode(false); + } + } + + public void testAppIdleAndDoze_tempPowerSaveAndAppIdleWhitelists() throws Exception { + if (!isSupported()) { + return; + } + + setDozeMode(true); + setAppIdle(true); + + try { + assertBackgroundNetworkAccess(false); + + addAppIdleWhitelist(mUid); + assertBackgroundNetworkAccess(false); + + addTempPowerSaveModeWhitelist(TEST_APP2_PKG, TEMP_POWERSAVE_WHITELIST_DURATION_MS); + assertBackgroundNetworkAccess(true); + + // Wait until the whitelist duration is expired. + SystemClock.sleep(TEMP_POWERSAVE_WHITELIST_DURATION_MS); + assertBackgroundNetworkAccess(false); + } finally { + setAppIdle(false); + setDozeMode(false); + removeAppIdleWhitelist(mUid); + } + } + + public void testAppIdleAndBatterySaver_tempPowerSaveAndAppIdleWhitelists() throws Exception { + if (!isSupported()) { + return; + } + + setBatterySaverMode(true); + setAppIdle(true); + + try { + assertBackgroundNetworkAccess(false); + + addAppIdleWhitelist(mUid); + assertBackgroundNetworkAccess(false); + + addTempPowerSaveModeWhitelist(TEST_APP2_PKG, TEMP_POWERSAVE_WHITELIST_DURATION_MS); + assertBackgroundNetworkAccess(true); + + // Wait until the whitelist duration is expired. + SystemClock.sleep(TEMP_POWERSAVE_WHITELIST_DURATION_MS); + assertBackgroundNetworkAccess(false); + } finally { + setAppIdle(false); + setBatterySaverMode(false); + removeAppIdleWhitelist(mUid); + } + } } diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java index fe9d36ce1d..5f5ea43d67 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java @@ -156,6 +156,11 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC "testBackgroundNetworkAccess_enabled"); } + public void testAppIdleMetered_idleWhitelisted() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleMeteredTest", + "testAppIdleNetworkAccess_idleWhitelisted"); + } + // TODO: currently power-save mode and idle uses the same whitelist, so this test would be // redundant (as it would be testing the same as testBatterySaverMode_reinstall()) // public void testAppIdle_reinstall() throws Exception { @@ -181,6 +186,11 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC "testBackgroundNetworkAccess_enabled"); } + public void testAppIdleNonMetered_idleWhitelisted() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleNonMeteredTest", + "testAppIdleNetworkAccess_idleWhitelisted"); + } + public void testAppIdleNonMetered_whenCharging() throws Exception { runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleNonMeteredTest", "testAppIdleNetworkAccess_whenCharging"); @@ -281,6 +291,21 @@ public class HostsideRestrictBackgroundNetworkTests extends HostsideNetworkTestC "testAppIdleAndBatterySaver_tempPowerSaveWhitelists"); } + public void testDozeAndAppIdle_appIdleWhitelist() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".MixedModesTest", + "testDozeAndAppIdle_appIdleWhitelist"); + } + + public void testAppIdleAndDoze_tempPowerSaveAndAppIdleWhitelists() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".MixedModesTest", + "testAppIdleAndDoze_tempPowerSaveAndAppIdleWhitelists"); + } + + public void testAppIdleAndBatterySaver_tempPowerSaveAndAppIdleWhitelists() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".MixedModesTest", + "testAppIdleAndBatterySaver_tempPowerSaveAndAppIdleWhitelists"); + } + /******************* * Helper methods. * *******************/ From af95fad957196933570b974635d7499370e5b2fa Mon Sep 17 00:00:00 2001 From: Rebecca Silberstein Date: Fri, 27 Apr 2018 08:50:14 -0700 Subject: [PATCH 0523/1109] WifiManagerTest: allow for multiple modes Now that WifiService can/will support dual simultaneous mode operation, make sure the tests allow for it as well. Bug: 31346104 Bug: 115567184 Test: atest android.net.wifi.cts Change-Id: Id3aaacb3651568c18850a0fdf3832c0f52218cf2 Merged-In: Id3aaacb3651568c18850a0fdf3832c0f52218cf2 --- .../android/net/wifi/cts/WifiManagerTest.java | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index b2d912e56c..44b49c0274 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -825,10 +825,9 @@ public class WifiManagerTest extends AndroidTestCase { TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot(); - // at this point, wifi should be off - assertFalse(mWifiManager.isWifiEnabled()); - stopLocalOnlyHotspot(callback, wifiEnabled); + + // wifi should either stay on, or come back on assertEquals(wifiEnabled, mWifiManager.isWifiEnabled()); } @@ -840,23 +839,31 @@ public class WifiManagerTest extends AndroidTestCase { * tethering is started. * Note: Location mode must be enabled for this test. */ - public void testSetWifiEnabledByAppDoesNotStopHotspot() { - // first check that softap mode is supported by the device + + public void testSetWifiEnabledByAppDoesNotStopHotspot() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + // check that softap mode is supported by the device if (!mWifiManager.isPortableHotspotSupported()) { return; } boolean wifiEnabled = mWifiManager.isWifiEnabled(); + if (wifiEnabled) { + // disable wifi so we have something to turn on (some devices may be able to run + // simultaneous modes) + setWifiEnabled(false); + } + TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot(); - // at this point, wifi should be off - assertFalse(mWifiManager.isWifiEnabled()); // now we should fail to turn on wifi assertFalse(mWifiManager.setWifiEnabled(true)); stopLocalOnlyHotspot(callback, wifiEnabled); - assertEquals(wifiEnabled, mWifiManager.isWifiEnabled()); } /** @@ -876,9 +883,6 @@ public class WifiManagerTest extends AndroidTestCase { TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot(); - // at this point, wifi should be off - assertFalse(mWifiManager.isWifiEnabled()); - // now make a second request - this should fail. TestLocalOnlyHotspotCallback callback2 = new TestLocalOnlyHotspotCallback(mLOHSLock); try { @@ -887,9 +891,12 @@ public class WifiManagerTest extends AndroidTestCase { Log.d(TAG, "Caught the IllegalStateException we expected: called startLOHS twice"); caughtException = true; } + if (!caughtException) { + // second start did not fail, should clean up the hotspot. + stopLocalOnlyHotspot(callback2, wifiEnabled); + } assertTrue(caughtException); stopLocalOnlyHotspot(callback, wifiEnabled); - assertEquals(wifiEnabled, mWifiManager.isWifiEnabled()); } } From 4b1386285a7444fbb1d853228a2cac8ea88865f6 Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 28 Nov 2018 09:25:43 -0800 Subject: [PATCH 0524/1109] Scan Optimization: Check set device mobility permission is granted to <= 1 app Add a new CTS test to ensure that set device mobility permission is granted to at most 1 app. Bug: 120097108 Test: "atest WifiManagerTest" after installing app with new permission granted Change-Id: Ifda2163da6da9e9365c440d47031d25f92c6c375 --- .../android/net/wifi/cts/WifiManagerTest.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index deaa64421c..8ea72e00e9 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -58,6 +58,7 @@ import java.util.Objects; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; public class WifiManagerTest extends AndroidTestCase { private static class MySync { @@ -998,6 +999,30 @@ public class WifiManagerTest extends AndroidTestCase { } } + /** + * Verify that the {@link android.Manifest.permission#WIFI_SET_DEVICE_MOBILITY_STATE} permission + * is held by at most one application. + */ + public void testWifiSetDeviceMobilityStatePermission() { + final PackageManager pm = getContext().getPackageManager(); + + final List holding = pm.getPackagesHoldingPermissions(new String[] { + android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE + }, PackageManager.MATCH_UNINSTALLED_PACKAGES); + + List uniquePackageNames = holding + .stream() + .map(pi -> pi.packageName) + .distinct() + .collect(Collectors.toList()); + + if (uniquePackageNames.size() > 1) { + fail("The WIFI_SET_DEVICE_MOBILITY_STATE permission must not be held by more than one " + + "application, but is held by " + uniquePackageNames.size() + " applications: " + + String.join(", ", uniquePackageNames)); + } + } + private void turnScreenOnNoDelay() throws Exception { mUiDevice.executeShellCommand("input keyevent KEYCODE_WAKEUP"); mUiDevice.executeShellCommand("wm dismiss-keyguard"); From 3c5f35a38ea554c942309440a2d12ad1da4e3f78 Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Wed, 21 Nov 2018 14:38:40 +0800 Subject: [PATCH 0525/1109] Test for asynchronous DNS query API Add basic test for asynchronous DNS query API Test: build atest CtsNativeNetDnsTestCases Change-Id: Ib757ba8f0128d3efe7dfbcbfb45d36e4350834f9 --- tests/cts/net/native/dns_async/Android.bp | 36 +++++ .../cts/net/native/dns_async/AndroidTest.xml | 29 ++++ .../dns_async/src/NativeDnsAsyncTest.cpp | 148 ++++++++++++++++++ 3 files changed, 213 insertions(+) create mode 100644 tests/cts/net/native/dns_async/Android.bp create mode 100644 tests/cts/net/native/dns_async/AndroidTest.xml create mode 100644 tests/cts/net/native/dns_async/src/NativeDnsAsyncTest.cpp diff --git a/tests/cts/net/native/dns_async/Android.bp b/tests/cts/net/native/dns_async/Android.bp new file mode 100644 index 0000000000..2b9346fc0b --- /dev/null +++ b/tests/cts/net/native/dns_async/Android.bp @@ -0,0 +1,36 @@ +cc_defaults { + name: "dns_async_defaults", + + cflags: [ + "-fstack-protector-all", + "-g", + "-Wall", + "-Wextra", + "-Werror", + "-fno-builtin", + ], + srcs: [ + "src/NativeDnsAsyncTest.cpp", + ], + shared_libs: [ + "liblog", + "libutils", + "libandroid", + ], +} + +cc_test { + name: "CtsNativeNetDnsTestCases", + defaults: ["dns_async_defaults"], + multilib: { + lib32: { + suffix: "32", + }, + lib64: { + suffix: "64", + }, + }, + test_suites: [ + "cts", + ], +} \ No newline at end of file diff --git a/tests/cts/net/native/dns_async/AndroidTest.xml b/tests/cts/net/native/dns_async/AndroidTest.xml new file mode 100644 index 0000000000..e092b36186 --- /dev/null +++ b/tests/cts/net/native/dns_async/AndroidTest.xml @@ -0,0 +1,29 @@ + + + + diff --git a/tests/cts/net/native/dns_async/src/NativeDnsAsyncTest.cpp b/tests/cts/net/native/dns_async/src/NativeDnsAsyncTest.cpp new file mode 100644 index 0000000000..087eb5ed5a --- /dev/null +++ b/tests/cts/net/native/dns_async/src/NativeDnsAsyncTest.cpp @@ -0,0 +1,148 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include /* poll */ +#include +#include + +#include +#include + +namespace { +constexpr int MAXPACKET = 8 * 1024; +constexpr int PTON_MAX = 16; + +int getAsyncResponse(int fd, int timeoutMs, int* rcode, u_char* buf, int bufLen) { + struct pollfd wait_fd[1]; + wait_fd[0].fd = fd; + wait_fd[0].events = POLLIN; + short revents; + int ret; + ret = poll(wait_fd, 1, timeoutMs); + revents = wait_fd[0].revents; + if (revents & POLLIN) { + int n = android_res_nresult(fd, rcode, buf, bufLen); + return n; + } + + return -1; +} + +std::vector extractIpAddressAnswers(u_char* buf, int bufLen, int ipType) { + ns_msg handle; + if (ns_initparse((const uint8_t*) buf, bufLen, &handle) < 0) { + return {}; + } + int ancount = ns_msg_count(handle, ns_s_an); + ns_rr rr; + std::vector answers; + for (int i = 0; i < ancount; i++) { + if (ns_parserr(&handle, ns_s_an, i, &rr) < 0) { + continue; + } + const u_char* rdata = ns_rr_rdata(rr); + char buffer[INET6_ADDRSTRLEN]; + if (inet_ntop(ipType, (const char*) rdata, buffer, sizeof(buffer))) { + answers.push_back(buffer); + } + } + return answers; +} + +void expectAnswersValid(int fd, int ipType, int expectedRcode) { + int rcode = -1; + u_char buf[MAXPACKET] = {}; + int res = getAsyncResponse(fd, 10000, &rcode, buf, MAXPACKET); + EXPECT_GT(res, 0); + EXPECT_EQ(rcode, expectedRcode); + + + if (expectedRcode == NOERROR) { + auto answers = extractIpAddressAnswers(buf, res, ipType); + EXPECT_GT(answers.size(), 0U); + for (auto &answer : answers) { + char pton[PTON_MAX]; + EXPECT_EQ(1, inet_pton(ipType, answer.c_str(), pton)); + } + } +} + +} // namespace + +TEST (NativeDnsAsyncTest, Async_Query) { + // V4 + int fd = android_res_nquery(NETWORK_UNSPECIFIED ,"www.google.com", ns_c_in, ns_t_a); + EXPECT_GT(fd, 0); + expectAnswersValid(fd, AF_INET, NOERROR); + + // V6 + fd = android_res_nquery(NETWORK_UNSPECIFIED ,"www.google.com", ns_c_in, ns_t_aaaa); + EXPECT_GT(fd, 0); + expectAnswersValid(fd, AF_INET6, NOERROR); +} + +TEST (NativeDnsAsyncTest, Async_Send) { + // V4 + u_char buf[MAXPACKET] = {}; + int len = res_mkquery(QUERY, "www.youtube.com", + ns_c_in, ns_t_a, nullptr, 0, nullptr, buf, sizeof(buf)); + EXPECT_GT(len, 0); + int fd = android_res_nsend(NETWORK_UNSPECIFIED , buf, len); + EXPECT_GT(fd, 0); + expectAnswersValid(fd, AF_INET, NOERROR); + + // V6 + memset(buf, 0, MAXPACKET); + len = res_mkquery(QUERY, "www.youtube.com", + ns_c_in, ns_t_aaaa, nullptr, 0, nullptr, buf, sizeof(buf)); + EXPECT_GT(len, 0); + fd = android_res_nsend(NETWORK_UNSPECIFIED , buf, len); + EXPECT_GT(fd, 0); + expectAnswersValid(fd, AF_INET6, NOERROR); +} + +TEST (NativeDnsAsyncTest, Async_NXDOMAIN) { + u_char buf[MAXPACKET] = {}; + int len = res_mkquery(QUERY, "test-nx.metric.gstatic.com", + ns_c_in, ns_t_a, nullptr, 0, nullptr, buf, sizeof(buf)); + EXPECT_GT(len, 0); + int fd = android_res_nsend(NETWORK_UNSPECIFIED , buf, len); + EXPECT_GT(fd, 0); + expectAnswersValid(fd, AF_INET, NXDOMAIN); +} + +TEST (NativeDnsAsyncTest, Async_Cancel) { + int fd = android_res_nquery(NETWORK_UNSPECIFIED ,"www.google.com", ns_c_in, ns_t_a); + int rcode = -1; + u_char buf[MAXPACKET] = {}; + android_res_cancel(fd); + + int res = android_res_nresult(fd, &rcode, buf, MAXPACKET); + EXPECT_EQ(res, -EBADF); +} + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} From 7131af6b93596886333b22511f836e34bdc46e9c Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Fri, 12 Oct 2018 13:17:47 +0100 Subject: [PATCH 0526/1109] Add tests for InetAddresses.parseNumericAddress() Test: run cts -m CtsNetTestCases Bug: 78686891 Change-Id: I1e121ab3fd619964625c4b51e0b7280eef001775 --- tests/cts/net/Android.mk | 4 +- .../android/net/cts/InetAddressesTest.java | 134 ++++++++++++++++++ 2 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 tests/cts/net/src/android/net/cts/InetAddressesTest.java diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index 6967adb57b..bb1f4c73c4 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -45,7 +45,9 @@ LOCAL_STATIC_JAVA_LIBRARIES := \ ctstestserver \ mockwebserver \ junit \ - truth-prebuilt + junit-params \ + truth-prebuilt \ + # uncomment when b/13249961 is fixed #LOCAL_SDK_VERSION := current diff --git a/tests/cts/net/src/android/net/cts/InetAddressesTest.java b/tests/cts/net/src/android/net/cts/InetAddressesTest.java new file mode 100644 index 0000000000..7837ce9ed5 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/InetAddressesTest.java @@ -0,0 +1,134 @@ +/* + * 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.net.InetAddresses; +import java.net.InetAddress; +import junitparams.JUnitParamsRunner; +import junitparams.Parameters; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +@RunWith(JUnitParamsRunner.class) +public class InetAddressesTest { + + public static String[][] validNumericAddressesAndStringRepresentation() { + return new String[][] { + // Regular IPv4. + { "1.2.3.4", "1.2.3.4" }, + + // Regular IPv6. + { "2001:4860:800d::68", "2001:4860:800d::68" }, + { "1234:5678::9ABC:DEF0", "1234:5678::9abc:def0" }, + { "2001:cdba:9abc:5678::", "2001:cdba:9abc:5678::" }, + { "::2001:cdba:9abc:5678", "::2001:cdba:9abc:5678" }, + { "64:ff9b::1.2.3.4", "64:ff9b::102:304" }, + + { "::9abc:5678", "::154.188.86.120" }, + + // Mapped IPv4 + { "::ffff:127.0.0.1", "127.0.0.1" }, + + // Android does not recognize Octal (leading 0) cases: they are treated as decimal. + { "0177.00.00.01", "177.0.0.1" }, + + // Verify that examples from JavaDoc work correctly. + { "192.0.2.1", "192.0.2.1" }, + { "2001:db8::1:2", "2001:db8::1:2" }, + }; + } + + public static String[] invalidNumericAddresses() { + return new String[] { + "", + " ", + "\t", + "\n", + "1.2.3.4.", + "1.2.3", + "1.2", + "1", + "1234", + "0", + "0x1.0x2.0x3.0x4", + "0x7f.0x00.0x00.0x01", + "0256.00.00.01", + "fred", + "www.google.com", + // IPv6 encoded for use in URL as defined in RFC 2732 + "[fe80::6:2222]", + }; + } + + @Parameters(method = "validNumericAddressesAndStringRepresentation") + @Test + public void parseNumericAddress(String address, String expectedString) { + InetAddress inetAddress = InetAddresses.parseNumericAddress(address); + assertEquals(expectedString, inetAddress.getHostAddress()); + } + + @Parameters(method = "invalidNumericAddresses") + @Test + public void test_parseNonNumericAddress(String address) { + try { + InetAddress inetAddress = InetAddresses.parseNumericAddress(address); + fail(String.format( + "Address %s is not numeric but was parsed as %s", address, inetAddress)); + } catch (IllegalArgumentException e) { + assertThat(e.getMessage()).contains(address); + } + } + + @Test + public void test_parseNumericAddress_null() { + try { + InetAddress inetAddress = InetAddresses.parseNumericAddress(null); + fail(String.format("null is not numeric but was parsed as %s", inetAddress)); + } catch (NullPointerException e) { + // expected + } + } + + @Parameters(method = "validNumericAddressesAndStringRepresentation") + @Test + public void test_isNumericAddress(String address, String unused) { + assertTrue("expected '" + address + "' to be treated as numeric", + InetAddresses.isNumericAddress(address)); + } + + @Parameters(method = "invalidNumericAddresses") + @Test + public void test_isNotNumericAddress(String address) { + assertFalse("expected '" + address + "' to be treated as non-numeric", + InetAddresses.isNumericAddress(address)); + } + + @Test + public void test_isNumericAddress_null() { + try { + InetAddresses.isNumericAddress(null); + fail("expected null to throw a NullPointerException"); + } catch (NullPointerException e) { + // expected + } + } +} From c2b211f450420c80418b6b0f0cddefc57a765864 Mon Sep 17 00:00:00 2001 From: Julien Desprez Date: Mon, 17 Dec 2018 12:45:11 -0800 Subject: [PATCH 0527/1109] Tag modules for their sim card required Test: tf/cts unit tests ./cts-tradefed run cts-dev -m CtsNetTestCases --shard-count 2 (with and without sim card) ./cts-tradefed run cts-dev -m CtsCarrierApiTestCases --shard-count 2 (with and without uicc sim card) Bug: 69367250 Change-Id: Idcd35b9345be32658a1fd44027b03e5a47ff7e88 --- tests/cts/net/AndroidTest.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/cts/net/AndroidTest.xml b/tests/cts/net/AndroidTest.xml index 1326970462..76ff1674f6 100644 --- a/tests/cts/net/AndroidTest.xml +++ b/tests/cts/net/AndroidTest.xml @@ -15,6 +15,8 @@

    - * Only Settings, SysUi and shell apps should ever attempt to acquire this - * permission, since it would give those apps extremely broad access to connectivity + * Only Settings, SysUi, NetworkStack and shell apps should ever attempt to acquire + * this permission, since it would give those apps extremely broad access to connectivity * functionality. The permission is intended to be granted to only those apps with direct user * access and no others. */ @@ -886,6 +886,7 @@ public class WifiManagerTest extends AndroidTestCase { allowedUIDs.add(Process.SYSTEM_UID); allowedUIDs.add(Process.SHELL_UID); allowedUIDs.add(Process.PHONE_UID); + allowedUIDs.add(Process.NETWORK_STACK_UID); // only quick settings is allowed to bind to the BIND_QUICK_SETTINGS_TILE permission, using // this fact to determined allowed package name for sysui From 823149f58f674bb653b0ff00fecf89d46fde572d Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 6 Feb 2019 11:42:55 -0800 Subject: [PATCH 0545/1109] Grant CTS test APK ACCESS_BACKGROUND_LOCATION permission Fixed broken CTS tests due to missing permissions. Bug: 123622071 Test: cts-tradefed, run cts -m CtsNetTestCases Change-Id: I6ddd2afbae6f685c018fd53d988e543ddbcfec04 --- tests/cts/net/AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index 0bfb650882..2a57c101b2 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -22,6 +22,7 @@ + From ccef9c809333f890641409dc0a3cb077e85a7943 Mon Sep 17 00:00:00 2001 From: Chenbo Feng Date: Tue, 22 Jan 2019 17:36:16 -0800 Subject: [PATCH 0546/1109] Add checks for detailed uid stats Get the detailed network stats for the test uid and check if the detail stats is consistent with the per uid stats. This test is necessary since the new devices may get detailed network stats and per uid total stats from different eBPF maps. Test: atest TrafficStatsTest Bug: 79171384 Change-Id: I04533e9fa146e052bdc3787ec6b1f8dad9c19fb7 --- .../src/android/net/cts/TrafficStatsTest.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java index a8743fad7f..af096da089 100755 --- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java +++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java @@ -16,6 +16,7 @@ package android.net.cts; +import android.net.NetworkStats; import android.net.TrafficStats; import android.os.Process; import android.test.AndroidTestCase; @@ -99,6 +100,7 @@ public class TrafficStatsTest extends AndroidTestCase { final int byteCount = 1024; final int packetCount = 1024; + TrafficStats.startDataProfiling(null); final ServerSocket server = new ServerSocket(0); new Thread("TrafficStatsTest.testTrafficStatsForLocalhost") { @Override @@ -153,6 +155,7 @@ public class TrafficStatsTest extends AndroidTestCase { Thread.sleep(1000); } catch (InterruptedException e) { } + NetworkStats testStats = TrafficStats.stopDataProfiling(null); long mobileTxPacketsAfter = TrafficStats.getMobileTxPackets(); long mobileRxPacketsAfter = TrafficStats.getMobileRxPackets(); @@ -194,6 +197,24 @@ public class TrafficStatsTest extends AndroidTestCase { Log.i(LOG_TAG, "lingering traffic data: " + deltaTxOtherPackets + "/" + deltaRxOtherPackets); } + // Check the per uid stats read from data profiling have the stats expected. The data + // profiling snapshot is generated from readNetworkStatsDetail() method in + // networkStatsService and in this way we can verify the detail networkStats of a given uid + // is correct. + NetworkStats.Entry entry = testStats.getTotal(null, Process.myUid()); + assertTrue("txPackets detail: " + entry.txPackets + " uidTxPackets: " + uidTxDeltaPackets, + entry.txPackets >= packetCount + minExpectedExtraPackets + && entry.txPackets <= uidTxDeltaPackets); + assertTrue("rxPackets detail: " + entry.rxPackets + " uidRxPackets: " + uidRxDeltaPackets, + entry.rxPackets >= packetCount + minExpectedExtraPackets + && entry.rxPackets <= uidRxDeltaPackets); + assertTrue("txBytes detail: " + entry.txBytes + " uidTxDeltaBytes: " + uidTxDeltaBytes, + entry.txBytes >= tcpPacketToIpBytes(packetCount, byteCount) + + tcpPacketToIpBytes(minExpectedExtraPackets, 0) && entry.txBytes <= uidTxDeltaBytes); + assertTrue("rxBytes detail: " + entry.rxBytes + " uidRxDeltaBytes: " + uidRxDeltaBytes, + entry.rxBytes >= tcpPacketToIpBytes(packetCount, byteCount) + + tcpPacketToIpBytes(minExpectedExtraPackets, 0) && entry.rxBytes <= uidRxDeltaBytes); + assertTrue("uidtxp: " + uidTxPacketsBefore + " -> " + uidTxPacketsAfter + " delta=" + uidTxDeltaPackets + " Wanted: " + uidTxDeltaPackets + ">=" + packetCount + "+" + minExpectedExtraPackets + " && " + uidTxDeltaPackets + "<=" + packetCount + "+" + packetCount + "+" + maxExpectedExtraPackets + "+" + deltaTxOtherPackets, From 17ef99be740500c9755ac31718ecaca7631fb93b Mon Sep 17 00:00:00 2001 From: "jungyee.yoo" Date: Tue, 22 Jan 2019 15:43:24 +0900 Subject: [PATCH 0547/1109] Add sleep to avoid calling stopLocalOnlyHotspot before TetherController initialization. Bug: 123205589 Test: run cts-on-gsi -m -m CtsNetTestCases -t android.net.wifi.cts.WifiManagerTest#testStartLocalOnlyHotspotSingleRequestByApps Bug: 123379970 Test: run cts-on-gsi -m -m CtsNetTestCases -t ndroid.net.wifi.cts.WifiManagerTest#testStartLocalOnlyHotspotSuccess Change-Id: I7506c3037dc5368d69330acc47c97c765185870f --- .../android/net/wifi/cts/WifiManagerTest.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index af91fbfb15..2ed012491e 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -874,6 +874,15 @@ public class WifiManagerTest extends AndroidTestCase { TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot(); + // add sleep to avoid calling stopLocalOnlyHotspot before TetherController initialization. + // TODO: remove this sleep as soon as b/124330089 is fixed. + try { + Log.d(TAG, "Sleep for 2 seconds"); + Thread.sleep(2000); + } catch (InterruptedException e) { + Log.d(TAG, "Thread InterruptedException!"); + } + stopLocalOnlyHotspot(callback, wifiEnabled); // wifi should either stay on, or come back on @@ -949,6 +958,15 @@ public class WifiManagerTest extends AndroidTestCase { } assertTrue(caughtException); + // add sleep to avoid calling stopLocalOnlyHotspot before TetherController initialization. + // TODO: remove this sleep as soon as b/124330089 is fixed. + try { + Log.d(TAG, "Sleep for 2 seconds"); + Thread.sleep(2000); + } catch (InterruptedException e) { + Log.d(TAG, "Thread InterruptedException!"); + } + stopLocalOnlyHotspot(callback, wifiEnabled); } } From 2186a943d32a9c4433d19d5d97d702b6531ff73d Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Fri, 15 Feb 2019 17:58:15 -0800 Subject: [PATCH 0548/1109] Add permissions needed for WifiManager.getConnectionInfo().getSSID(). Fixes: 124383293 Test: atest com.android.cts.net.HostsideRestrictBackgroundNetworkTests Change-Id: I3145e4ba1e768b7bb3c89867e36b506a90b87506 --- tests/cts/hostside/app/AndroidManifest.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/cts/hostside/app/AndroidManifest.xml b/tests/cts/hostside/app/AndroidManifest.xml index 2553f475aa..b91f39d36e 100644 --- a/tests/cts/hostside/app/AndroidManifest.xml +++ b/tests/cts/hostside/app/AndroidManifest.xml @@ -23,6 +23,8 @@ + + From 54c6488a76a552af10d23790929f8f9be32f5458 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Thu, 14 Feb 2019 17:43:43 +0800 Subject: [PATCH 0549/1109] p2p: add cts coverage for WifiP2pConfig.Builder Bug: 123780303 Test: cts - atest CtsNetTestCases:android.net.wifi.cts.WifiP2pConfigTest Change-Id: I8529bf725c648e499acd6017ee57fe3db7422fef --- tests/cts/net/src/android/net/wifi/OWNERS | 5 ++ .../cts/net/src/android/net/wifi/aware/OWNERS | 1 - .../net/wifi/p2p/cts/WifiP2pConfigTest.java | 62 +++++++++++++++++++ tests/cts/net/src/android/net/wifi/rtt/OWNERS | 1 - 4 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 tests/cts/net/src/android/net/wifi/OWNERS delete mode 100644 tests/cts/net/src/android/net/wifi/aware/OWNERS create mode 100644 tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pConfigTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/rtt/OWNERS diff --git a/tests/cts/net/src/android/net/wifi/OWNERS b/tests/cts/net/src/android/net/wifi/OWNERS new file mode 100644 index 0000000000..4a6001bcfe --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/OWNERS @@ -0,0 +1,5 @@ +etancohen@google.com +lorenzo@google.com +mplass@google.com +rpius@google.com +satk@google.com diff --git a/tests/cts/net/src/android/net/wifi/aware/OWNERS b/tests/cts/net/src/android/net/wifi/aware/OWNERS deleted file mode 100644 index cf116f89dd..0000000000 --- a/tests/cts/net/src/android/net/wifi/aware/OWNERS +++ /dev/null @@ -1 +0,0 @@ -etancohen@google.com diff --git a/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pConfigTest.java b/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pConfigTest.java new file mode 100644 index 0000000000..639db8a7c3 --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pConfigTest.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2019 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.wifi.p2p.cts; + +import android.net.MacAddress; +import android.net.wifi.p2p.WifiP2pConfig; +import android.net.wifi.p2p.WifiP2pGroup; +import android.test.AndroidTestCase; + +public class WifiP2pConfigTest extends AndroidTestCase { + static final String TEST_NETWORK_NAME = "DIRECT-xy-Hello"; + static final String TEST_PASSPHRASE = "8etterW0r1d"; + static final int TEST_OWNER_BAND = WifiP2pConfig.GROUP_OWNER_BAND_5GHZ; + static final int TEST_OWNER_FREQ = 2447; + static final String TEST_DEVICE_ADDRESS = "aa:bb:cc:dd:ee:ff"; + + public void testWifiP2pConfigBuilderForPersist() { + WifiP2pConfig.Builder builder = new WifiP2pConfig.Builder(); + builder.setNetworkName(TEST_NETWORK_NAME) + .setPassphrase(TEST_PASSPHRASE) + .setGroupOperatingBand(TEST_OWNER_BAND) + .setDeviceAddress(MacAddress.fromString(TEST_DEVICE_ADDRESS)) + .enablePersistentMode(true); + WifiP2pConfig config = builder.build(); + + assertTrue(config.deviceAddress.equals(TEST_DEVICE_ADDRESS)); + assertTrue(config.networkName.equals(TEST_NETWORK_NAME)); + assertTrue(config.passphrase.equals(TEST_PASSPHRASE)); + assertEquals(config.groupOwnerBand, TEST_OWNER_BAND); + assertEquals(config.netId, WifiP2pGroup.PERSISTENT_NET_ID); + } + + public void testWifiP2pConfigBuilderForNonPersist() { + WifiP2pConfig.Builder builder = new WifiP2pConfig.Builder(); + builder.setNetworkName(TEST_NETWORK_NAME) + .setPassphrase(TEST_PASSPHRASE) + .setGroupOperatingFrequency(TEST_OWNER_FREQ) + .setDeviceAddress(MacAddress.fromString(TEST_DEVICE_ADDRESS)) + .enablePersistentMode(false); + WifiP2pConfig config = builder.build(); + + assertTrue(config.deviceAddress.equals(TEST_DEVICE_ADDRESS)); + assertTrue(config.networkName.equals(TEST_NETWORK_NAME)); + assertTrue(config.passphrase.equals(TEST_PASSPHRASE)); + assertEquals(config.groupOwnerBand, TEST_OWNER_FREQ); + assertEquals(config.netId, WifiP2pGroup.TEMPORARY_NET_ID); + } +} diff --git a/tests/cts/net/src/android/net/wifi/rtt/OWNERS b/tests/cts/net/src/android/net/wifi/rtt/OWNERS deleted file mode 100644 index cf116f89dd..0000000000 --- a/tests/cts/net/src/android/net/wifi/rtt/OWNERS +++ /dev/null @@ -1 +0,0 @@ -etancohen@google.com From db6c9fd35a0eaf441273a1ff937de323dbd6286a Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Thu, 14 Feb 2019 14:27:13 +0800 Subject: [PATCH 0550/1109] p2p: add cts coverage for new WifiP2pManager API Bug: 123781797 Test: cts - atest CtsNetTestCases:android.net.wifi.cts.ConcurrencyTest Change-Id: Id37429c48e6e784bfe1cc6de0378f5213991c241 --- .../android/net/wifi/cts/ConcurrencyTest.java | 320 +++++++++++++++++- 1 file changed, 304 insertions(+), 16 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java b/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java index 5e91366a9d..c80e3720c5 100644 --- a/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java @@ -16,36 +16,66 @@ package android.net.wifi.cts; +import static org.junit.Assert.assertNotEquals; + import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.PackageManager; import android.net.ConnectivityManager; import android.net.ConnectivityManager.NetworkCallback; import android.net.Network; import android.net.NetworkCapabilities; +import android.net.NetworkInfo; import android.net.NetworkRequest; import android.net.wifi.WifiManager; import android.net.wifi.p2p.WifiP2pManager; -import static android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_STATE_DISABLED; -import static android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_STATE_ENABLED; +import android.provider.Settings; import android.test.AndroidTestCase; +import android.util.Log; import com.android.compatibility.common.util.SystemUtil; +import java.util.Arrays; +import java.util.BitSet; +import java.util.LinkedList; +import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; public class ConcurrencyTest extends AndroidTestCase { private class MySync { - int expectedWifiState; - int expectedP2pState; + static final int WIFI_STATE = 0; + static final int P2P_STATE = 1; + static final int DISCOVERY_STATE = 2; + static final int NETWORK_INFO = 3; + + public BitSet pendingSync = new BitSet(); + + public int expectedWifiState; + public int expectedP2pState; + public int expectedDiscoveryState; + public NetworkInfo expectedNetworkInfo; + } + + private class MyResponse { + public boolean valid = false; + + public boolean success; + public int p2pState; + public int discoveryState; + public NetworkInfo networkInfo; } private WifiManager mWifiManager; + private WifiP2pManager mWifiP2pManager; + private WifiP2pManager.Channel mWifiP2pChannel; private MySync mMySync = new MySync(); + private MyResponse mMyResponse = new MyResponse(); - private static final String TAG = "WifiInfoTest"; + private static final String TAG = "ConcurrencyTest"; private static final int TIMEOUT_MSEC = 6000; private static final int WAIT_MSEC = 60; private static final int DURATION = 10000; @@ -56,16 +86,33 @@ public class ConcurrencyTest extends AndroidTestCase { final String action = intent.getAction(); if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { synchronized (mMySync) { + mMySync.pendingSync.set(MySync.WIFI_STATE); mMySync.expectedWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_DISABLED); mMySync.notify(); } } else if(action.equals(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION)) { synchronized (mMySync) { + mMySync.pendingSync.set(MySync.P2P_STATE); mMySync.expectedP2pState = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, WifiP2pManager.WIFI_P2P_STATE_DISABLED); mMySync.notify(); } + } else if (action.equals(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION)) { + synchronized (mMySync) { + mMySync.pendingSync.set(MySync.DISCOVERY_STATE); + mMySync.expectedDiscoveryState = intent.getIntExtra( + WifiP2pManager.EXTRA_DISCOVERY_STATE, + WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED); + mMySync.notify(); + } + } else if (action.equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) { + synchronized (mMySync) { + mMySync.pendingSync.set(MySync.NETWORK_INFO); + mMySync.expectedNetworkInfo = (NetworkInfo) intent.getExtra( + WifiP2pManager.EXTRA_NETWORK_INFO, null); + mMySync.notify(); + } } } }; @@ -81,6 +128,8 @@ public class ConcurrencyTest extends AndroidTestCase { mIntentFilter = new IntentFilter(); mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); + mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION); + mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); mContext.registerReceiver(mReceiver, mIntentFilter); mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); @@ -92,6 +141,8 @@ public class ConcurrencyTest extends AndroidTestCase { assertTrue(!mWifiManager.isWifiEnabled()); mMySync.expectedWifiState = WifiManager.WIFI_STATE_DISABLED; mMySync.expectedP2pState = WifiP2pManager.WIFI_P2P_STATE_DISABLED; + mMySync.expectedDiscoveryState = WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED; + mMySync.expectedNetworkInfo = null; } @Override @@ -108,16 +159,66 @@ public class ConcurrencyTest extends AndroidTestCase { super.tearDown(); } - private void waitForBroadcasts() { + private boolean waitForBroadcasts(List waitSyncList) { synchronized (mMySync) { long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; - while (System.currentTimeMillis() < timeout - && (mMySync.expectedWifiState != WifiManager.WIFI_STATE_ENABLED || - mMySync.expectedP2pState != WifiP2pManager.WIFI_P2P_STATE_ENABLED)) { + while (System.currentTimeMillis() < timeout) { + List handledSyncList = waitSyncList.stream() + .filter(w -> mMySync.pendingSync.get(w)) + .collect(Collectors.toList()); + handledSyncList.forEach(w -> mMySync.pendingSync.clear(w)); + waitSyncList.removeAll(handledSyncList); + if (waitSyncList.isEmpty()) { + break; + } try { mMySync.wait(WAIT_MSEC); } catch (InterruptedException e) { } } + if (!waitSyncList.isEmpty()) { + Log.i(TAG, "Missing broadcast: " + waitSyncList); + } + return waitSyncList.isEmpty(); + } + } + + private boolean waitForBroadcasts(int waitSingleSync) { + return waitForBroadcasts( + new LinkedList(Arrays.asList(waitSingleSync))); + } + + private boolean waitForServiceResponse(MyResponse waitResponse) { + synchronized (waitResponse) { + long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; + while (System.currentTimeMillis() < timeout) { + try { + waitResponse.wait(WAIT_MSEC); + } catch (InterruptedException e) { } + + if (waitResponse.valid) { + return true; + } + } + return false; + } + } + + // Return true if location is enabled. + private boolean isLocationEnabled() { + return Settings.Secure.getInt(getContext().getContentResolver(), + Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF) + != Settings.Secure.LOCATION_MODE_OFF; + } + + // Returns true if the device has location feature. + private boolean hasLocationFeature() { + return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION); + } + + private void resetResponse(MyResponse responseObj) { + synchronized (responseObj) { + responseObj.valid = false; + responseObj.networkInfo = null; } } @@ -148,25 +249,212 @@ public class ConcurrencyTest extends AndroidTestCase { cm.unregisterNetworkCallback(networkCallback); } - public void testConcurrency() { + private boolean setupWifiP2p() { // Cannot support p2p alone if (!WifiFeature.isWifiSupported(getContext())) { assertTrue(!WifiFeature.isP2pSupported(getContext())); - return; + return false; } if (!WifiFeature.isP2pSupported(getContext())) { // skip the test if p2p is not supported + return false; + } + + if (!hasLocationFeature()) { + Log.d(TAG, "Skipping test as location is not supported"); + return false; + } + if (!isLocationEnabled()) { + fail("Please enable location for this test - since P-release WiFi Direct" + + " needs Location enabled."); + } + + long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; + while (!mWifiManager.isWifiEnabled() && System.currentTimeMillis() < timeout) { + try { + enableWifi(); + } catch (InterruptedException e) { } + } + + assertTrue(mWifiManager.isWifiEnabled()); + + assertTrue(waitForBroadcasts( + new LinkedList( + Arrays.asList(MySync.WIFI_STATE, MySync.P2P_STATE)))); + + assertEquals(WifiManager.WIFI_STATE_ENABLED, mMySync.expectedWifiState); + assertEquals(WifiP2pManager.WIFI_P2P_STATE_ENABLED, mMySync.expectedP2pState); + + mWifiP2pManager = + (WifiP2pManager) getContext().getSystemService(Context.WIFI_P2P_SERVICE); + mWifiP2pChannel = mWifiP2pManager.initialize( + getContext(), getContext().getMainLooper(), null); + + assertNotNull(mWifiP2pManager); + assertNotNull(mWifiP2pChannel); + + assertTrue(waitForBroadcasts(MySync.NETWORK_INFO)); + // wait for changing to EnabledState + assertNotNull(mMySync.expectedNetworkInfo); + assertTrue(mMySync.expectedNetworkInfo.isAvailable()); + + return true; + } + + public void testConcurrency() { + if (!setupWifiP2p()) { return; } - // Enable wifi - SystemUtil.runShellCommand("svc wifi enable"); + resetResponse(mMyResponse); + mWifiP2pManager.requestP2pState(mWifiP2pChannel, new WifiP2pManager.P2pStateListener() { + @Override + public void onP2pStateAvailable(int state) { + synchronized (mMyResponse) { + mMyResponse.valid = true; + mMyResponse.p2pState = state; + mMyResponse.notify(); + } + } + }); + assertTrue(waitForServiceResponse(mMyResponse)); + assertEquals(WifiP2pManager.WIFI_P2P_STATE_ENABLED, mMyResponse.p2pState); + } - waitForBroadcasts(); + public void testRequestDiscoveryState() { + if (!setupWifiP2p()) { + return; + } - assertTrue(mMySync.expectedWifiState == WifiManager.WIFI_STATE_ENABLED); - assertTrue(mMySync.expectedP2pState == WifiP2pManager.WIFI_P2P_STATE_ENABLED); + resetResponse(mMyResponse); + mWifiP2pManager.requestDiscoveryState( + mWifiP2pChannel, new WifiP2pManager.DiscoveryStateListener() { + @Override + public void onDiscoveryStateAvailable(int state) { + synchronized (mMyResponse) { + mMyResponse.valid = true; + mMyResponse.discoveryState = state; + mMyResponse.notify(); + } + } + }); + assertTrue(waitForServiceResponse(mMyResponse)); + assertEquals(WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED, mMyResponse.discoveryState); + + resetResponse(mMyResponse); + mWifiP2pManager.discoverPeers(mWifiP2pChannel, new WifiP2pManager.ActionListener() { + @Override + public void onSuccess() { + synchronized (mMyResponse) { + mMyResponse.valid = true; + mMyResponse.success = true; + mMyResponse.notify(); + } + } + + @Override + public void onFailure(int reason) { + synchronized (mMyResponse) { + Log.d(TAG, "discoveryPeers failure reason: " + reason); + mMyResponse.valid = true; + mMyResponse.success = false; + mMyResponse.notify(); + } + } + }); + assertTrue(waitForServiceResponse(mMyResponse)); + assertTrue(mMyResponse.success); + assertTrue(waitForBroadcasts(MySync.DISCOVERY_STATE)); + + resetResponse(mMyResponse); + mWifiP2pManager.requestDiscoveryState(mWifiP2pChannel, + new WifiP2pManager.DiscoveryStateListener() { + @Override + public void onDiscoveryStateAvailable(int state) { + synchronized (mMyResponse) { + mMyResponse.valid = true; + mMyResponse.discoveryState = state; + mMyResponse.notify(); + } + } + }); + assertTrue(waitForServiceResponse(mMyResponse)); + assertEquals(WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED, mMyResponse.discoveryState); + + mWifiP2pManager.stopPeerDiscovery(mWifiP2pChannel, null); + } + + public void testRequestNetworkInfo() { + if (!setupWifiP2p()) { + return; + } + + resetResponse(mMyResponse); + mWifiP2pManager.requestNetworkInfo(mWifiP2pChannel, + new WifiP2pManager.NetworkInfoListener() { + @Override + public void onNetworkInfoAvailable(NetworkInfo info) { + synchronized (mMyResponse) { + mMyResponse.valid = true; + mMyResponse.networkInfo = info; + mMyResponse.notify(); + } + } + }); + assertTrue(waitForServiceResponse(mMyResponse)); + assertNotNull(mMyResponse.networkInfo); + // The state might be IDLE, DISCONNECTED, FAILED before a connection establishment. + // Just ensure the state is NOT CONNECTED. + assertNotEquals(NetworkInfo.DetailedState.CONNECTED, + mMySync.expectedNetworkInfo.getDetailedState()); + + resetResponse(mMyResponse); + mWifiP2pManager.createGroup(mWifiP2pChannel, new WifiP2pManager.ActionListener() { + @Override + public void onSuccess() { + synchronized (mMyResponse) { + mMyResponse.valid = true; + mMyResponse.success = true; + mMyResponse.notify(); + } + } + + @Override + public void onFailure(int reason) { + synchronized (mMyResponse) { + Log.d(TAG, "createGroup failure reason: " + reason); + mMyResponse.valid = true; + mMyResponse.success = false; + mMyResponse.notify(); + } + } + }); + assertTrue(waitForServiceResponse(mMyResponse)); + assertTrue(mMyResponse.success); + assertTrue(waitForBroadcasts(MySync.NETWORK_INFO)); + assertNotNull(mMySync.expectedNetworkInfo); + assertEquals(NetworkInfo.DetailedState.CONNECTED, + mMySync.expectedNetworkInfo.getDetailedState()); + + resetResponse(mMyResponse); + mWifiP2pManager.requestNetworkInfo(mWifiP2pChannel, + new WifiP2pManager.NetworkInfoListener() { + @Override + public void onNetworkInfoAvailable(NetworkInfo info) { + synchronized (mMyResponse) { + mMyResponse.valid = true; + mMyResponse.networkInfo = info; + mMyResponse.notify(); + } + } + }); + assertTrue(waitForServiceResponse(mMyResponse)); + assertNotNull(mMyResponse.networkInfo); + assertEquals(NetworkInfo.DetailedState.CONNECTED, + mMyResponse.networkInfo.getDetailedState()); + + mWifiP2pManager.removeGroup(mWifiP2pChannel, null); } } From 328a891956b7c0729cb652f79ce1504648da03e0 Mon Sep 17 00:00:00 2001 From: Ricky Wai Date: Wed, 20 Feb 2019 15:46:43 +0000 Subject: [PATCH 0551/1109] Make net cts not using isolated storage Disabling isolated storage so existing tests can still write files to /sdcard and shell can read it successfully. Bug: 124651276 Test: atest android.net.cts.NetworkWatchlistTest#testGetWatchlistConfigHash Change-Id: I6c40d1ae12fc2cff76c976c11650423df5ce044f --- tests/cts/net/AndroidTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/cts/net/AndroidTest.xml b/tests/cts/net/AndroidTest.xml index 76ff1674f6..ff93afc375 100644 --- a/tests/cts/net/AndroidTest.xml +++ b/tests/cts/net/AndroidTest.xml @@ -26,5 +26,6 @@ diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java index 7c9ce8f833..a2443b391a 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java @@ -128,7 +128,7 @@ abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiRec protected void runDeviceTests(String packageName, String testClassName, String methodName) throws DeviceNotAvailableException { RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(packageName, - "android.support.test.runner.AndroidJUnitRunner", getDevice().getIDevice()); + "androidx.test.runner.AndroidJUnitRunner", getDevice().getIDevice()); if (testClassName != null) { if (methodName != null) { From e1a851f029730532fef7f315b4787131c899075d Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Wed, 27 Feb 2019 18:15:17 +0800 Subject: [PATCH 0557/1109] Minor change for jni cts test of asynchronous DNS query API Test: build atest MultinetworkApiTest Change-Id: I644adb74b841d70bb3396104fb483793a25cd36a --- tests/cts/net/jni/NativeMultinetworkJni.cpp | 42 +++++++++++---------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/tests/cts/net/jni/NativeMultinetworkJni.cpp b/tests/cts/net/jni/NativeMultinetworkJni.cpp index 332148bf39..d1a92a47a1 100644 --- a/tests/cts/net/jni/NativeMultinetworkJni.cpp +++ b/tests/cts/net/jni/NativeMultinetworkJni.cpp @@ -42,7 +42,7 @@ if (actual < expected) { \ jniThrowExceptionFmt(env, "java/lang/AssertionError", \ "%s:%d: %s EXPECT_GE: expected %d, got %d", \ - __FILE__, __LINE__, expected, actual); \ + __FILE__, __LINE__, msg, expected, actual); \ } \ } while (0) @@ -65,7 +65,7 @@ } while (0) static const int MAXPACKET = 8 * 1024; -static const int TIMEOUT_MS = 2000; +static const int TIMEOUT_MS = 15000; static const char kHostname[] = "connectivitycheck.android.com"; static const char kNxDomainName[] = "test1-nx.metric.gstatic.com"; static const char kGoogleName[] = "www.google.com"; @@ -82,23 +82,29 @@ int getAsyncResponse(JNIEnv* env, int fd, int timeoutMs, int* rcode, uint8_t* bu int n = android_res_nresult(fd, rcode, buf, bufLen); // Verify that android_res_nresult() closed the fd char dummy; - EXPECT_EQ(env, -1, read(fd, &dummy, sizeof dummy), "res_nresult check for closing fd"); + EXPECT_EQ(env, -1, read(fd, &dummy, sizeof(dummy)), "res_nresult check for closing fd"); EXPECT_EQ(env, EBADF, errno, "res_nresult check for errno"); return n; } - return -EREMOTEIO; + return -ETIMEDOUT; } int extractIpAddressAnswers(uint8_t* buf, size_t bufLen, int family) { ns_msg handle; if (ns_initparse((const uint8_t*) buf, bufLen, &handle) < 0) { - return -EREMOTEIO; + return -errno; } const int ancount = ns_msg_count(handle, ns_s_an); + // Answer count = 0 is valid(e.g. response of query with root) + if (!ancount) { + return 0; + } ns_rr rr; + bool hasValidAns = false; for (int i = 0; i < ancount; i++) { if (ns_parserr(&handle, ns_s_an, i, &rr) < 0) { + // If there is no valid answer, test will fail. continue; } const uint8_t* rdata = ns_rr_rdata(rr); @@ -106,8 +112,9 @@ int extractIpAddressAnswers(uint8_t* buf, size_t bufLen, int family) { if (inet_ntop(family, (const char*) rdata, buffer, sizeof(buffer)) == NULL) { return -errno; } + hasValidAns = true; } - return 0; + return hasValidAns ? 0 : -EBADMSG; } int expectAnswersValid(JNIEnv* env, int fd, int family, int expectedRcode) { @@ -117,10 +124,8 @@ int expectAnswersValid(JNIEnv* env, int fd, int family, int expectedRcode) { if (res < 0) { return res; } - if(rcode != expectedRcode) { - ALOGD("rcode:%d, expectedRcode = %d", rcode, expectedRcode); - return -EREMOTEIO; - } + + EXPECT_EQ(env, expectedRcode, rcode, "rcode is not expected"); if (expectedRcode == ns_r_noerror && res > 0) { return extractIpAddressAnswers(buf, res, family); @@ -151,8 +156,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runResNqueryCheck( "v4 res_nquery check answers"); // V4 NXDOMAIN - fd = android_res_nquery(handle, kNxDomainName, ns_c_in, ns_t_a, - ANDROID_RESOLV_NO_CACHE_LOOKUP); + fd = android_res_nquery(handle, kNxDomainName, ns_c_in, ns_t_a, 0); EXPECT_GE(env, fd, 0, "v4 res_nquery NXDOMAIN"); EXPECT_EQ(env, 0, expectAnswersValid(env, fd, AF_INET, ns_r_nxdomain), "v4 res_nquery NXDOMAIN check answers"); @@ -164,8 +168,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runResNqueryCheck( "v6 res_nquery check answers"); // V6 NXDOMAIN - fd = android_res_nquery(handle, kNxDomainName, ns_c_in, ns_t_aaaa, - ANDROID_RESOLV_NO_CACHE_LOOKUP); + fd = android_res_nquery(handle, kNxDomainName, ns_c_in, ns_t_aaaa, 0); EXPECT_GE(env, fd, 0, "v6 res_nquery NXDOMAIN"); EXPECT_EQ(env, 0, expectAnswersValid(env, fd, AF_INET, ns_r_nxdomain), "v6 res_nquery NXDOMAIN check answers"); @@ -201,7 +204,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runResNsendCheck( memset(buf1, 0, sizeof(buf1)); len1 = makeQuery(kNxDomainName, ns_t_a, buf1, sizeof(buf1)); EXPECT_GT(env, len1, 0, "v4 res_mkquery NXDOMAIN"); - fd1 = android_res_nsend(handle, buf1, len1, ANDROID_RESOLV_NO_CACHE_LOOKUP); + fd1 = android_res_nsend(handle, buf1, len1, 0); EXPECT_GE(env, fd1, 0, "v4 res_nsend NXDOMAIN"); EXPECT_EQ(env, 0, expectAnswersValid(env, fd1, AF_INET, ns_r_nxdomain), "v4 res_nsend NXDOMAIN check answers"); @@ -224,11 +227,11 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runResNsendCheck( EXPECT_EQ(env, 0, expectAnswersValid(env, fd1, AF_INET6, ns_r_noerror), "v6 res_nsend 1st check answers"); - // // V6 NXDOMAIN + // V6 NXDOMAIN memset(buf1, 0, sizeof(buf1)); len1 = makeQuery(kNxDomainName, ns_t_aaaa, buf1, sizeof(buf1)); EXPECT_GT(env, len1, 0, "v6 res_mkquery NXDOMAIN"); - fd1 = android_res_nsend(handle, buf1, len1, ANDROID_RESOLV_NO_CACHE_LOOKUP); + fd1 = android_res_nsend(handle, buf1, len1, 0); EXPECT_GE(env, fd1, 0, "v6 res_nsend NXDOMAIN"); EXPECT_EQ(env, 0, expectAnswersValid(env, fd1, AF_INET6, ns_r_nxdomain), "v6 res_nsend NXDOMAIN check answers"); @@ -245,8 +248,9 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runResNcancelCheck( int rcode = -1; uint8_t buf[MAXPACKET] = {}; android_res_cancel(fd); - android_res_cancel(fd); + EXPECT_EQ(env, -EBADF, android_res_nresult(fd, &rcode, buf, MAXPACKET), "res_cancel"); + android_res_cancel(fd); EXPECT_EQ(env, -EBADF, android_res_nresult(fd, &rcode, buf, MAXPACKET), "res_cancel"); return 0; } @@ -269,7 +273,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runResNapiMalformedCheck fd = android_res_nquery(handle, exceedingLabelQuery.c_str(), ns_c_in, ns_t_a, 0); EXPECT_EQ(env, -EMSGSIZE, fd, "res_nquery exceedingLabelQuery"); - fd = android_res_nquery(handle, exceedingDomainQuery.c_str(), ns_c_in, ns_t_a, 0); + fd = android_res_nquery(handle, exceedingDomainQuery.c_str(), ns_c_in, ns_t_aaaa, 0); EXPECT_EQ(env, -EMSGSIZE, fd, "res_nquery exceedingDomainQuery"); uint8_t buf[10] = {}; From 77dbefc0f828e7c00307f4b599291079ed15468d Mon Sep 17 00:00:00 2001 From: Dongwon Kang Date: Tue, 26 Feb 2019 15:40:02 -0800 Subject: [PATCH 0558/1109] Add rtsp uri test cases for Uri.toSafeString() Test: atest CtsNetTestCases:android.net.cts.UriTest Bug: 123669012 Change-Id: I6dac4028fd9eb6b9240a87d9e41f9dafc34bbabe --- tests/cts/net/src/android/net/cts/UriTest.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/UriTest.java b/tests/cts/net/src/android/net/cts/UriTest.java index 5344f93df9..40b8fb7259 100644 --- a/tests/cts/net/src/android/net/cts/UriTest.java +++ b/tests/cts/net/src/android/net/cts/UriTest.java @@ -568,6 +568,15 @@ public class UriTest extends AndroidTestCase { "ftp://root:love@ftp.android.com:2121/"); } + public void testToSafeString_rtsp() { + checkToSafeString("rtsp://rtsp.android.com/...", "rtsp://rtsp.android.com/"); + checkToSafeString("rtsp://rtsp.android.com/...", "rtsp://rtsp.android.com/video.mov"); + checkToSafeString("rtsp://rtsp.android.com/...", "rtsp://rtsp.android.com/video.mov?param"); + checkToSafeString("RtsP://rtsp.android.com/...", "RtsP://anonymous@rtsp.android.com/"); + checkToSafeString("rtsp://rtsp.android.com:2121/...", + "rtsp://username:password@rtsp.android.com:2121/"); + } + public void testToSafeString_notSupport() { checkToSafeString("unsupported://ajkakjah/askdha/secret?secret", "unsupported://ajkakjah/askdha/secret?secret"); From 0c6f9ef7c80e318e848c94dbd3dee426fa35666c Mon Sep 17 00:00:00 2001 From: Yichun Li Date: Tue, 26 Feb 2019 18:03:52 -0800 Subject: [PATCH 0559/1109] Backfill OWNERS for CTS module CtsHostsideNetworkTests You're receiving this CL because you're the owner of CtsHostsideNetworkTests as per http://go/cts-test-owners. Please refer to the following doc for more details on why we are backfilling OWNERS file: http://go/backfill-cts-owners. Test: Ignored Bug: 126563878 Change-Id: Ib239888264404f6acd265f9923d8c2c4eb988797 --- tests/cts/hostside/OWNERS | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 tests/cts/hostside/OWNERS diff --git a/tests/cts/hostside/OWNERS b/tests/cts/hostside/OWNERS new file mode 100644 index 0000000000..52c8053323 --- /dev/null +++ b/tests/cts/hostside/OWNERS @@ -0,0 +1,4 @@ +# Bug component: 61373 +sudheersai@google.com +lorenzo@google.com +jchalard@google.com From 420804ce3e68183b019b217064af1c417496c3e0 Mon Sep 17 00:00:00 2001 From: Brett Chabot Date: Thu, 28 Feb 2019 10:01:06 -0800 Subject: [PATCH 0560/1109] Migrate cts/tests/tests/net to androidx.test See go/jetpack-test-android-migration Test: m -j CtsNetTestCases Change-Id: I4a76e9b9410f94e297bca4287f450fe3b72fb409 Merged-In: If102677e4cdc4361b5d93283c4d6140dc477a94a --- tests/cts/net/Android.mk | 4 ++-- tests/cts/net/AndroidManifest.xml | 2 +- .../android/net/cts/ConnectivityManagerTest.java | 15 +++++++-------- .../net/src/android/net/cts/MacAddressTest.java | 6 ++++-- .../src/android/net/cts/NetworkWatchlistTest.java | 8 ++++---- 5 files changed, 18 insertions(+), 17 deletions(-) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index bb1f4c73c4..2084dbc357 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -40,8 +40,8 @@ LOCAL_PACKAGE_NAME := CtsNetTestCases LOCAL_STATIC_JAVA_LIBRARIES := \ core-tests-support \ - compatibility-device-util \ - ctstestrunner \ + compatibility-device-util-axt \ + ctstestrunner-axt \ ctstestserver \ mockwebserver \ junit \ diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index 0bfb650882..b261b39885 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -42,7 +42,7 @@ - Date: Wed, 26 Dec 2018 16:08:09 -0800 Subject: [PATCH 0561/1109] [Wifi] Update CTS test for Wifi Locks This commit adds CTS test cases for High-Perf and Low-Latency wifi locks. Bug: 34905427 Bug: 116512430 Test: atest WifiManager_WifiLockTest Change-Id: I94cb7fc0aa7876d6796eca6ca97b744dc009ef3e --- .../wifi/cts/WifiManager_WifiLockTest.java | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java index 3cdd56af89..e08a972bd0 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java @@ -25,13 +25,27 @@ public class WifiManager_WifiLockTest extends AndroidTestCase { private static final String WIFI_TAG = "WifiManager_WifiLockTest"; - public void testWifiLock() { + /** + * Verify acquire and release of High Performance wifi locks + */ + public void testHiPerfWifiLock() { + testWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF); + } + + /** + * Verify acquire and release of Low latency wifi locks + */ + public void testLowLatencyWifiLock() { + testWifiLock(WifiManager.WIFI_MODE_FULL_LOW_LATENCY); + } + + private void testWifiLock(int lockType) { if (!WifiFeature.isWifiSupported(getContext())) { // skip the test if WiFi is not supported return; } WifiManager wm = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); - WifiLock wl = wm.createWifiLock(WIFI_TAG); + WifiLock wl = wm.createWifiLock(lockType, WIFI_TAG); wl.setReferenceCounted(true); assertFalse(wl.isHeld()); @@ -55,7 +69,7 @@ public class WifiManager_WifiLockTest extends AndroidTestCase { // expected } - wl = wm.createWifiLock(WIFI_TAG); + wl = wm.createWifiLock(lockType, WIFI_TAG); wl.setReferenceCounted(false); assertFalse(wl.isHeld()); wl.acquire(); From c626be0dc78d8ffa9d30c63455aa48900023ffec Mon Sep 17 00:00:00 2001 From: Brett Chabot Date: Tue, 12 Feb 2019 20:46:59 -0800 Subject: [PATCH 0562/1109] Migrate cts/tests/tests/net to androidx.test See go/jetpack-test-android-migration This is the internal version of aosp/915793 Exempt-From-Owner-Approval: already reviewed in aosp Test: m -j CtsNetTestCases Change-Id: If102677e4cdc4361b5d93283c4d6140dc477a94a --- tests/cts/net/Android.mk | 4 ++-- tests/cts/net/AndroidManifest.xml | 2 +- .../android/net/cts/ConnectivityManagerTest.java | 15 +++++++-------- .../net/src/android/net/cts/MacAddressTest.java | 6 ++++-- .../src/android/net/cts/NetworkWatchlistTest.java | 8 ++++---- .../src/android/net/wifi/cts/WifiManagerTest.java | 8 ++------ 6 files changed, 20 insertions(+), 23 deletions(-) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index bb1f4c73c4..2084dbc357 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -40,8 +40,8 @@ LOCAL_PACKAGE_NAME := CtsNetTestCases LOCAL_STATIC_JAVA_LIBRARIES := \ core-tests-support \ - compatibility-device-util \ - ctstestrunner \ + compatibility-device-util-axt \ + ctstestrunner-axt \ ctstestserver \ mockwebserver \ junit \ diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index 2a57c101b2..630de7e08f 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -43,7 +43,7 @@ - Date: Fri, 1 Mar 2019 13:25:23 -0800 Subject: [PATCH 0563/1109] Migrate remaining cts to androidx.test. See go/jetpack-test-android-migration Exempt-From-Owner-Approval: automated package name refactoring; already reviewed+merged internally Test: m cts Change-Id: I6877435bf0436b8ef1dd252b225eac2908e78b71 Merged-In: I092c369229f8cb4c13827cbad4fd162622ac7849 --- tests/cts/hostside/app/Android.mk | 2 +- tests/cts/hostside/app/AndroidManifest.xml | 2 +- .../src/com/android/cts/net/HostsideNetworkTestCase.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/cts/hostside/app/Android.mk b/tests/cts/hostside/app/Android.mk index 62e0172817..11f6bb1460 100644 --- a/tests/cts/hostside/app/Android.mk +++ b/tests/cts/hostside/app/Android.mk @@ -21,7 +21,7 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests #LOCAL_SDK_VERSION := current LOCAL_PRIVATE_PLATFORM_APIS := true -LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util ctstestrunner ub-uiautomator \ +LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util-axt ctstestrunner-axt ub-uiautomator \ CtsHostsideNetworkTestsAidl LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs diff --git a/tests/cts/hostside/app/AndroidManifest.xml b/tests/cts/hostside/app/AndroidManifest.xml index 2553f475aa..ba0e242ab9 100644 --- a/tests/cts/hostside/app/AndroidManifest.xml +++ b/tests/cts/hostside/app/AndroidManifest.xml @@ -45,7 +45,7 @@ diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java index 7c9ce8f833..a2443b391a 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java @@ -128,7 +128,7 @@ abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiRec protected void runDeviceTests(String packageName, String testClassName, String methodName) throws DeviceNotAvailableException { RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(packageName, - "android.support.test.runner.AndroidJUnitRunner", getDevice().getIDevice()); + "androidx.test.runner.AndroidJUnitRunner", getDevice().getIDevice()); if (testClassName != null) { if (methodName != null) { From 7513ebc64fe46b38944e4f97995e0d8a23969e2c Mon Sep 17 00:00:00 2001 From: Benedict Wong Date: Mon, 4 Mar 2019 11:57:19 -0800 Subject: [PATCH 0564/1109] Remove point-to-point assertion in IpSecManagerTunnelTest This change removes the requirement for IPsec interfaces to be point-to-point. The two implementations (VTI vs XFRMI) have different point-to-point values, and as such, this assertion is no longer valid. Bug: 126578549 Test: Ran tests against XFRM-I kernels Change-Id: I0597e0aa86ccea2cd28d7c5e02063c788ddb08b8 --- tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java index 95ca25ce64..5dc9b63b87 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java @@ -127,7 +127,6 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { // Check interface was created NetworkInterface netIntf = NetworkInterface.getByName(tunnelIntf.getInterfaceName()); - assertTrue(netIntf.isPointToPoint()); assertNotNull(netIntf); // Add addresses and check From a0629ad8b9680949d4b62a7fd953dd17d5b8f6d2 Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Thu, 24 Jan 2019 14:21:06 +0800 Subject: [PATCH 0565/1109] Minor changes and more cts tests for DnsResolver Test: built, flashed, booted atest DnsResolverTest Change-Id: I39f24b9751ab507bf7fc6bcd90376fafc60221b8 --- .../src/android/net/cts/DnsResolverTest.java | 215 +++++++++++++----- 1 file changed, 161 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 2e40584ecb..308f1edb0c 100644 --- a/tests/cts/net/src/android/net/cts/DnsResolverTest.java +++ b/tests/cts/net/src/android/net/cts/DnsResolverTest.java @@ -17,16 +17,16 @@ package android.net.cts; import static android.net.DnsResolver.CLASS_IN; -import static android.net.DnsResolver.TYPE_A; -import static android.net.DnsResolver.TYPE_AAAA; import static android.net.DnsResolver.FLAG_NO_CACHE_LOOKUP; +import static android.net.DnsResolver.TYPE_AAAA; +import android.annotation.NonNull; import android.content.Context; import android.net.ConnectivityManager; +import android.net.DnsPacket; import android.net.DnsResolver; import android.net.Network; import android.net.NetworkCapabilities; -import android.net.NetworkUtils; import android.os.Handler; import android.os.Looper; import android.system.ErrnoException; @@ -35,14 +35,18 @@ import android.util.Log; import java.net.InetAddress; import java.util.ArrayList; +import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; public class DnsResolverTest extends AndroidTestCase { private static final String TAG = "DnsResolverTest"; private static final char[] HEX_CHARS = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + static final int TIMEOUT_MS = 12_000; + private ConnectivityManager mCM; private Handler mHandler; private DnsResolver mDns; @@ -54,7 +58,7 @@ public class DnsResolverTest extends AndroidTestCase { mDns = DnsResolver.getInstance(); } - private static String bytesArrayToHexString(byte[] bytes) { + private static String byteArrayToHexString(byte[] bytes) { char[] hexChars = new char[bytes.length * 2]; for (int i = 0; i < bytes.length; ++i) { int b = bytes[i] & 0xFF; @@ -77,85 +81,188 @@ public class DnsResolverTest extends AndroidTestCase { assertTrue( "This test requires that at least one network be connected. " + - "Please ensure that the device is connected to a network.", + "Please ensure that the device is connected to a network.", testableNetworks.size() >= 1); return testableNetworks.toArray(new Network[0]); } public void testInetAddressQuery() throws ErrnoException { + final String dname = "www.google.com"; + final String msg = "InetAddress query " + dname; for (Network network : getTestableNetworks()) { - CountDownLatch latch = new CountDownLatch(1); - final int TIMEOUT_MS = 5_000; - final String dname = "www.google.com"; + final CountDownLatch latch = new CountDownLatch(1); + final AtomicReference> answers = new AtomicReference<>(); mDns.query(network, dname, FLAG_NO_CACHE_LOOKUP, mHandler, answerList -> { - if (answerList.size() != 0) { - latch.countDown(); + answers.set(answerList); for (InetAddress addr : answerList) { - Log.e(TAG, "Reported addr:" + addr.toString()); + Log.d(TAG, "Reported addr:" + addr.toString()); } + latch.countDown(); } - } ); - String msg = "InetAddress query " + dname + " but no valid answer after " - + TIMEOUT_MS + "ms."; try { - assertTrue(msg, latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - } catch (InterruptedException e) {} + assertTrue(msg + " but no valid answer after " + TIMEOUT_MS + "ms.", + latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); + assertGreaterThan(msg + " returned 0 result", answers.get().size(), 0); + } catch (InterruptedException e) { + } + } + } + + static private void assertGreaterThan(String msg, int a, int b) { + assertTrue(msg + ": " + a + " > " + b, a > b); + } + + static private void assertValidAnswer(String msg, @NonNull DnsAnswer ans) { + // Check rcode field.(0, No error condition). + assertTrue(msg + " Response error, rcode: " + ans.getRcode(), ans.getRcode() == 0); + // Check answer counts. + assertTrue(msg + " No answer found", ans.getANCount() > 0); + // Check question counts. + assertTrue(msg + " No question found", ans.getQDCount() > 0); + } + + static private void assertValidEmptyAnswer(String msg, @NonNull DnsAnswer ans) { + // Check rcode field.(0, No error condition). + assertTrue(msg + " Response error, rcode: " + ans.getRcode(), ans.getRcode() == 0); + // Check answer counts. Expect 0 answer. + assertTrue(msg + " Not an empty answer", ans.getANCount() == 0); + // Check question counts. + assertTrue(msg + " No question found", ans.getQDCount() > 0); + } + + private class DnsAnswer extends DnsPacket { + DnsAnswer(@NonNull byte[] data) throws ParseException { + super(data); + // Check QR field.(query (0), or a response (1)). + if ((mHeader.flags & (1 << 15)) == 0) { + throw new ParseException("Not an answer packet"); + } + } + + int getRcode() { + return mHeader.rcode; + } + int getANCount(){ + return mHeader.getRecordCount(ANSECTION); + } + int getQDCount(){ + return mHeader.getRecordCount(QDSECTION); } } public void testRawQuery() throws ErrnoException { + final String dname = "www.google.com"; + final String msg = "Raw query " + dname; for (Network network : getTestableNetworks()) { - CountDownLatch latch = new CountDownLatch(1); - final int TIMEOUT_MS = 5_000; - final String dname = "www.google.com"; - - mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, mHandler, answer -> { - if (answer != null) { - latch.countDown(); - Log.e(TAG, "Reported blob:" + bytesArrayToHexString(answer)); + final CountDownLatch latch = new CountDownLatch(1); + mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, mHandler, + answer -> { + if (answer == null) { + fail(msg + " no answer returned"); + } + try { + assertValidAnswer(msg, new DnsAnswer(answer)); + Log.d(TAG, "Reported blob:" + byteArrayToHexString(answer)); + latch.countDown(); + } catch (DnsPacket.ParseException e) { + fail(msg + e.getMessage()); + } } - } ); - String msg = "Raw query " + dname + " but no valid answer after " + TIMEOUT_MS + "ms."; try { - assertTrue(msg, latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - } catch (InterruptedException e) {} + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); + } catch (InterruptedException e) { + } } } public void testRawQueryWithBlob() throws ErrnoException { + final byte[] blob = new byte[]{ + /* Header */ + 0x55, 0x66, /* Transaction ID */ + 0x01, 0x00, /* Flags */ + 0x00, 0x01, /* Questions */ + 0x00, 0x00, /* Answer RRs */ + 0x00, 0x00, /* Authority RRs */ + 0x00, 0x00, /* Additional RRs */ + /* Queries */ + 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65, + 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */ + 0x00, 0x01, /* Type */ + 0x00, 0x01 /* Class */ + }; + final String msg = "Raw query with blob " + byteArrayToHexString(blob); for (Network network : getTestableNetworks()) { - CountDownLatch latch = new CountDownLatch(1); - final int TIMEOUT_MS = 5_000; - final byte[] blob = new byte[] { - /* Header */ - 0x55, 0x66, /* Transaction ID */ - 0x01, 0x00, /* Flags */ - 0x00, 0x01, /* Questions */ - 0x00, 0x00, /* Answer RRs */ - 0x00, 0x00, /* Authority RRs */ - 0x00, 0x00, /* Additional RRs */ - /* Queries */ - 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65, - 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */ - 0x00, 0x01, /* Type */ - 0x00, 0x01 /* Class */ - }; - + final CountDownLatch latch = new CountDownLatch(1); mDns.query(network, blob, FLAG_NO_CACHE_LOOKUP, mHandler, answer -> { - if (answer != null) { - latch.countDown(); - Log.e(TAG, "Reported blob:" + bytesArrayToHexString(answer)); + if (answer == null) { + fail(msg + " no answer returned"); + } + try { + assertValidAnswer(msg, new DnsAnswer(answer)); + Log.d(TAG, "Reported blob:" + byteArrayToHexString(answer)); + latch.countDown(); + } catch (DnsPacket.ParseException e) { + fail(msg + e.getMessage()); + } } - } ); - String msg = "Raw query with blob " + bytesArrayToHexString(blob) + - " but no valid answer after " + TIMEOUT_MS + "ms."; try { - assertTrue(msg, latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - } catch (InterruptedException e) {} + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); + } catch (InterruptedException e) { + } + } + } + + public void testEmptyQuery() throws ErrnoException { + final String dname = ""; + final String msg = "Raw query empty dname(ROOT)"; + for (Network network : getTestableNetworks()) { + final CountDownLatch latch = new CountDownLatch(1); + mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, mHandler, + answer -> { + if (answer == null) { + fail(msg + " no answer returned"); + } + try { + // Except no answer record because of querying with empty dname(ROOT) + assertValidEmptyAnswer(msg, new DnsAnswer(answer)); + latch.countDown(); + } catch (DnsPacket.ParseException e) { + fail(msg + e.getMessage()); + } + } + ); + try { + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); + } catch (InterruptedException e) { + } + } + } + + public void testNXQuery() throws ErrnoException { + final String dname = "test1-nx.metric.gstatic.com"; + final String msg = "InetAddress query " + dname; + for (Network network : getTestableNetworks()) { + final CountDownLatch latch = new CountDownLatch(1); + mDns.query(network, dname, FLAG_NO_CACHE_LOOKUP, mHandler, answerList -> { + if (answerList.size() == 0) { + latch.countDown(); + return; + } + fail(msg + " but get valid answers"); + } + ); + try { + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); + } catch (InterruptedException e) { + } } } } From c45065bdeae7c4b3104bf76d11b98b2ad7246e6b Mon Sep 17 00:00:00 2001 From: Brett Chabot Date: Wed, 6 Mar 2019 15:52:42 -0800 Subject: [PATCH 0566/1109] DO NOT MERGE - Migrate remaining cts to androidx.test. See go/jetpack-test-android-migration Test: m cts Exempt-From-Owner-Approval: automated refactoring, has already been reviewed by owners downstream Bug: 127482512 Change-Id: If72aed95ef9e436bcc6e063abc0478eca365cc9b --- tests/cts/hostside/app/Android.mk | 2 +- tests/cts/hostside/app/AndroidManifest.xml | 2 +- .../com/android/cts/net/HostsideNetworkTestCase.java | 2 +- tests/cts/net/Android.mk | 4 ++-- tests/cts/net/AndroidManifest.xml | 2 +- .../src/android/net/cts/ConnectivityManagerTest.java | 12 +++++++----- .../cts/net/src/android/net/cts/MacAddressTest.java | 6 ++++-- .../src/android/net/cts/NetworkWatchlistTest.java | 8 ++++---- 8 files changed, 21 insertions(+), 17 deletions(-) diff --git a/tests/cts/hostside/app/Android.mk b/tests/cts/hostside/app/Android.mk index c03e70bcb0..6d89e58576 100644 --- a/tests/cts/hostside/app/Android.mk +++ b/tests/cts/hostside/app/Android.mk @@ -20,7 +20,7 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests LOCAL_SDK_VERSION := current -LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util ctstestrunner ub-uiautomator \ +LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util-axt ctstestrunner-axt ub-uiautomator \ CtsHostsideNetworkTestsAidl LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs diff --git a/tests/cts/hostside/app/AndroidManifest.xml b/tests/cts/hostside/app/AndroidManifest.xml index 2553f475aa..ba0e242ab9 100644 --- a/tests/cts/hostside/app/AndroidManifest.xml +++ b/tests/cts/hostside/app/AndroidManifest.xml @@ -45,7 +45,7 @@ diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java index 7c9ce8f833..a2443b391a 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java @@ -128,7 +128,7 @@ abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiRec protected void runDeviceTests(String packageName, String testClassName, String methodName) throws DeviceNotAvailableException { RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(packageName, - "android.support.test.runner.AndroidJUnitRunner", getDevice().getIDevice()); + "androidx.test.runner.AndroidJUnitRunner", getDevice().getIDevice()); if (testClassName != null) { if (methodName != null) { diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index 1430071997..45941a79e1 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -41,8 +41,8 @@ LOCAL_PACKAGE_NAME := CtsNetTestCases LOCAL_STATIC_JAVA_LIBRARIES := \ core-tests-support \ - compatibility-device-util \ - ctstestrunner \ + compatibility-device-util-axt \ + ctstestrunner-axt \ ctstestserver \ mockwebserver \ junit \ diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index 0bfb650882..b261b39885 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -42,7 +42,7 @@ - Date: Tue, 12 Mar 2019 16:41:39 -0700 Subject: [PATCH 0567/1109] Removed Passpoint tests from WifiManagerTest Passpoint APIs require NETWORK_SETTINGS permission, which the CTS verifier cannot acquire. Bug: 127824266 Test: atest WifiManagerTest Change-Id: I1c69ae748318c0c5431326be77f8b1a942a1f2db --- .../android/net/wifi/cts/WifiManagerTest.java | 158 ------------------ 1 file changed, 158 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index a66fcdb0ba..8e66cb8953 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -509,164 +509,6 @@ public class WifiManagerTest extends AndroidTestCase { assertTrue(i < 15); } - /** - * Verify Passpoint configuration management APIs (add, remove, get) for a Passpoint - * configuration with an user credential. - * - * @throws Exception - */ - public void testAddPasspointConfigWithUserCredential() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - testAddPasspointConfig(generatePasspointConfig(generateUserCredential())); - } - - /** - * Verify Passpoint configuration management APIs (add, remove, get) for a Passpoint - * configuration with a certificate credential. - * - * @throws Exception - */ - public void testAddPasspointConfigWithCertCredential() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - testAddPasspointConfig(generatePasspointConfig(generateCertCredential())); - } - - /** - * Verify Passpoint configuration management APIs (add, remove, get) for a Passpoint - * configuration with a SIm credential. - * - * @throws Exception - */ - public void testAddPasspointConfigWithSimCredential() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - testAddPasspointConfig(generatePasspointConfig(generateSimCredential())); - } - - /** - * Helper function for generating a {@link PasspointConfiguration} for testing. - * - * @return {@link PasspointConfiguration} - */ - private PasspointConfiguration generatePasspointConfig(Credential credential) { - PasspointConfiguration config = new PasspointConfiguration(); - config.setCredential(credential); - - // Setup HomeSp. - HomeSp homeSp = new HomeSp(); - homeSp.setFqdn("Test.com"); - homeSp.setFriendlyName("Test Provider"); - homeSp.setRoamingConsortiumOis(new long[] {0x11223344}); - config.setHomeSp(homeSp); - - return config; - } - - /** - * Helper function for generating an user credential for testing. - * - * @return {@link Credential} - */ - private Credential generateUserCredential() { - Credential credential = new Credential(); - credential.setRealm("test.net"); - Credential.UserCredential userCred = new Credential.UserCredential(); - userCred.setEapType(21 /* EAP_TTLS */); - userCred.setUsername("username"); - userCred.setPassword("password"); - userCred.setNonEapInnerMethod("PAP"); - credential.setUserCredential(userCred); - credential.setCaCertificate(FakeKeys.CA_PUBLIC_CERT); - return credential; - } - - /** - * Helper function for generating a certificate credential for testing. - * - * @return {@link Credential} - */ - private Credential generateCertCredential() throws Exception { - Credential credential = new Credential(); - credential.setRealm("test.net"); - Credential.CertificateCredential certCredential = new Credential.CertificateCredential(); - certCredential.setCertType("x509v3"); - certCredential.setCertSha256Fingerprint( - MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded())); - credential.setCertCredential(certCredential); - credential.setCaCertificate(FakeKeys.CA_PUBLIC_CERT); - credential.setClientCertificateChain(new X509Certificate[] {FakeKeys.CLIENT_CERT}); - credential.setClientPrivateKey(FakeKeys.RSA_KEY1); - return credential; - } - - /** - * Helper function for generating a SIM credential for testing. - * - * @return {@link Credential} - */ - private Credential generateSimCredential() throws Exception { - Credential credential = new Credential(); - credential.setRealm("test.net"); - Credential.SimCredential simCredential = new Credential.SimCredential(); - simCredential.setImsi("1234*"); - simCredential.setEapType(18 /* EAP_SIM */); - credential.setSimCredential(simCredential); - return credential; - } - - /** - * Helper function verifying Passpoint configuration management APIs (add, remove, get) for - * a given configuration. - * - * @param config The configuration to test with - */ - private void testAddPasspointConfig(PasspointConfiguration config) throws Exception { - try { - - // obtain number of passpoint networks already present in device (preloaded) - List preConfigList = mWifiManager.getPasspointConfigurations(); - int numOfNetworks = preConfigList.size(); - - // add new (test) configuration - mWifiManager.addOrUpdatePasspointConfiguration(config); - - // Certificates and keys will be set to null after it is installed to the KeyStore by - // WifiManager. Reset them in the expected config so that it can be used to compare - // against the retrieved config. - config.getCredential().setCaCertificate(null); - config.getCredential().setClientCertificateChain(null); - config.getCredential().setClientPrivateKey(null); - - // retrieve the configuration and verify it. The retrieved list may not be in order - - // check all configs to see if any match - List configList = mWifiManager.getPasspointConfigurations(); - assertEquals(numOfNetworks + 1, configList.size()); - - boolean anyMatch = false; - for (PasspointConfiguration passpointConfiguration : configList) { - if (passpointConfiguration.equals(config)) { - anyMatch = true; - break; - } - } - assertTrue(anyMatch); - - // remove the (test) configuration and verify number of installed configurations - mWifiManager.removePasspointConfiguration(config.getHomeSp().getFqdn()); - assertEquals(mWifiManager.getPasspointConfigurations().size(), numOfNetworks); - } catch (UnsupportedOperationException e) { - // Passpoint build config |config_wifi_hotspot2_enabled| is disabled, so noop. - } - } - public class TestLocalOnlyHotspotCallback extends WifiManager.LocalOnlyHotspotCallback { Object hotspotLock; WifiManager.LocalOnlyHotspotReservation reservation = null; From 3953e40365470b468db1e95e3a47ed627a5cae39 Mon Sep 17 00:00:00 2001 From: paulhu Date: Thu, 14 Mar 2019 10:30:06 +0800 Subject: [PATCH 0568/1109] Fix API Review issues. Modify the method name in LinkProperties. Bug: 126699682 Test: make cts passed. Change-Id: I3729e8915a8eff36e8de9035b5bf1571f8609e42 --- tests/cts/net/src/android/net/cts/DnsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/DnsTest.java b/tests/cts/net/src/android/net/cts/DnsTest.java index 84231c25a8..746dcb0a1c 100644 --- a/tests/cts/net/src/android/net/cts/DnsTest.java +++ b/tests/cts/net/src/android/net/cts/DnsTest.java @@ -287,7 +287,7 @@ public class DnsTest extends AndroidTestCase { final NetworkCallback callback = new NetworkCallback() { @Override public void onLinkPropertiesChanged(Network network, LinkProperties lp) { - if (lp.hasGlobalIPv6Address()) { + if (lp.hasGlobalIpv6Address()) { latch.countDown(); } } From e451659573add8b4479b4553d1d785b0f825bd5c Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Wed, 13 Mar 2019 23:58:13 -0700 Subject: [PATCH 0569/1109] Wifi: Add CTS test for WifiManager.MulticastLock This commit adds the CTS tests for the class WifiManager.MulticastLock Bug: 124017617 Test: atest android.net.wifi.cts Change-Id: I6e7a6e70f350dcd23fe541ef746770e3561d49e6 --- tests/cts/net/AndroidManifest.xml | 1 + .../net/wifi/cts/MulticastLockTest.java | 77 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 tests/cts/net/src/android/net/wifi/cts/MulticastLockTest.java diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index 630de7e08f..dbd8fef08e 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -31,6 +31,7 @@ + diff --git a/tests/cts/net/src/android/net/wifi/cts/MulticastLockTest.java b/tests/cts/net/src/android/net/wifi/cts/MulticastLockTest.java new file mode 100644 index 0000000000..54fe9c72a9 --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/cts/MulticastLockTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2019 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.wifi.cts; + +import android.content.Context; +import android.net.wifi.WifiManager; +import android.net.wifi.WifiManager.MulticastLock; +import android.test.AndroidTestCase; + +public class MulticastLockTest extends AndroidTestCase { + + private static final String WIFI_TAG = "MulticastLockTest"; + + /** + * Verify acquire and release of Multicast locks + */ + public void testMulticastLock() { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + WifiManager wm = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); + MulticastLock mcl = wm.createMulticastLock(WIFI_TAG); + + mcl.setReferenceCounted(true); + assertFalse(mcl.isHeld()); + mcl.acquire(); + assertTrue(mcl.isHeld()); + mcl.release(); + assertFalse(mcl.isHeld()); + mcl.acquire(); + mcl.acquire(); + assertTrue(mcl.isHeld()); + mcl.release(); + assertTrue(mcl.isHeld()); + mcl.release(); + assertFalse(mcl.isHeld()); + assertNotNull(mcl.toString()); + try { + mcl.release(); + fail("should throw out exception because release is called" + +" a greater number of times than acquire"); + } catch (RuntimeException e) { + // expected + } + + mcl = wm.createMulticastLock(WIFI_TAG); + mcl.setReferenceCounted(false); + assertFalse(mcl.isHeld()); + mcl.acquire(); + assertTrue(mcl.isHeld()); + mcl.release(); + assertFalse(mcl.isHeld()); + mcl.acquire(); + mcl.acquire(); + assertTrue(mcl.isHeld()); + mcl.release(); + assertFalse(mcl.isHeld()); + assertNotNull(mcl.toString()); + // releasing again after release: but ignored for non-referenced locks + mcl.release(); + } +} From e16d426550b6683e4abf9dc70004d00bad548804 Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Thu, 14 Mar 2019 14:31:28 -0700 Subject: [PATCH 0570/1109] Wifi: Rename class name WifiManager_WifiLockTest This commit renames both the class name and the file name from WifiManager_WifiLockTest into WifiLockTest since WifiManager is implied from the package and directory hierarchy. Bug: 34905427 Test: atest android.net.wifi.cts Change-Id: Iaade2ba98cb1608384c2527eddb29bb6d020bf78 --- .../{WifiManager_WifiLockTest.java => WifiLockTest.java} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename tests/cts/net/src/android/net/wifi/cts/{WifiManager_WifiLockTest.java => WifiLockTest.java} (93%) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiLockTest.java similarity index 93% rename from tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java rename to tests/cts/net/src/android/net/wifi/cts/WifiLockTest.java index e08a972bd0..0703e6096b 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiLockTest.java @@ -21,9 +21,9 @@ import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.WifiLock; import android.test.AndroidTestCase; -public class WifiManager_WifiLockTest extends AndroidTestCase { +public class WifiLockTest extends AndroidTestCase { - private static final String WIFI_TAG = "WifiManager_WifiLockTest"; + private static final String WIFI_TAG = "WifiLockTest"; /** * Verify acquire and release of High Performance wifi locks @@ -82,7 +82,7 @@ public class WifiManager_WifiLockTest extends AndroidTestCase { wl.release(); assertFalse(wl.isHeld()); assertNotNull(wl.toString()); - // should be ignored + // releasing again after release: but ignored for non-referenced locks wl.release(); } } From 0d952ca8473b208c71b8c86843c17ac3952eb84a Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Fri, 15 Mar 2019 08:32:54 -0700 Subject: [PATCH 0571/1109] WifiManagerTest: Enforce a min number of suggestions per app The enforced number is set at 50. Also, removed the usage of a deprecated API in WifiManagerTest. Bug: 126536466 Test: atest WifiManagerTest Change-Id: I3a1ab4150cbbecef1157152c51b1148e1e2360ca --- .../android/net/wifi/cts/WifiManagerTest.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 8e66cb8953..93795b2bf0 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -94,6 +94,8 @@ public class WifiManagerTest extends AndroidTestCase { private static final int WIFI_SCAN_TEST_CACHE_DELAY_MILLIS = 3 * 60 * 1000; private static final int WIFI_SCAN_TEST_ITERATIONS = 5; + private static final int ENFORCED_NUM_NETWORK_SUGGESTIONS_PER_APP = 50; + private static final String TEST_PAC_URL = "http://www.example.com/proxy.pac"; private static final String MANAGED_PROVISIONING_PACKAGE_NAME = "com.android.managedprovisioning"; @@ -246,7 +248,6 @@ public class WifiManagerTest extends AndroidTestCase { private void connectWifi() throws Exception { synchronized (mMySync) { if (mNetworkInfo.getState() == NetworkInfo.State.CONNECTED) return; - assertTrue(mWifiManager.reconnect()); long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; while (System.currentTimeMillis() < timeout && mNetworkInfo.getState() != NetworkInfo.State.CONNECTED) @@ -982,6 +983,19 @@ public class WifiManagerTest extends AndroidTestCase { assertWifiScanningIsOn(); } + /** + * Verify that the platform supports a reasonable number of suggestions per app. + * @throws Exception + */ + public void testMaxNumberOfNetworkSuggestionsPerApp() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + assertTrue(mWifiManager.getMaxNumberOfNetworkSuggestionsPerApp() + > ENFORCED_NUM_NETWORK_SUGGESTIONS_PER_APP); + } + private void assertWifiScanningIsOn() { if(!mWifiManager.isScanAlwaysAvailable()) { fail("Wi-Fi scanning should be on."); From 26cc1b4a04e57ffefc6291851d3179962e27a2f1 Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Wed, 6 Mar 2019 16:52:03 +0800 Subject: [PATCH 0572/1109] Improve test for the changing of DnsResolver 1. Done for some code-style nits. 2. Update tests because AnswerCallback of DnsResolver is changed. Bug: 124882626 Test: built, flashed, booted atest DnsResolverTest Change-Id: Ie862c7ea5077f56fd9a4d96baf3f466b65db93d8 --- .../src/android/net/cts/DnsResolverTest.java | 207 +++++++++++------- 1 file changed, 131 insertions(+), 76 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/DnsResolverTest.java b/tests/cts/net/src/android/net/cts/DnsResolverTest.java index 308f1edb0c..643d54216a 100644 --- a/tests/cts/net/src/android/net/cts/DnsResolverTest.java +++ b/tests/cts/net/src/android/net/cts/DnsResolverTest.java @@ -18,15 +18,18 @@ package android.net.cts; import static android.net.DnsResolver.CLASS_IN; import static android.net.DnsResolver.FLAG_NO_CACHE_LOOKUP; +import static android.net.DnsResolver.TYPE_A; import static android.net.DnsResolver.TYPE_AAAA; import android.annotation.NonNull; +import android.annotation.Nullable; import android.content.Context; import android.net.ConnectivityManager; import android.net.DnsPacket; import android.net.DnsResolver; import android.net.Network; import android.net.NetworkCapabilities; +import android.net.ParseException; import android.os.Handler; import android.os.Looper; import android.system.ErrnoException; @@ -86,41 +89,55 @@ public class DnsResolverTest extends AndroidTestCase { return testableNetworks.toArray(new Network[0]); } - public void testInetAddressQuery() throws ErrnoException { + public void testQueryWithInetAddressCallback() { final String dname = "www.google.com"; - final String msg = "InetAddress query " + dname; + final String msg = "Query with InetAddressAnswerCallback " + dname; for (Network network : getTestableNetworks()) { final CountDownLatch latch = new CountDownLatch(1); final AtomicReference> answers = new AtomicReference<>(); - - mDns.query(network, dname, FLAG_NO_CACHE_LOOKUP, mHandler, answerList -> { - answers.set(answerList); - for (InetAddress addr : answerList) { - Log.d(TAG, "Reported addr:" + addr.toString()); - } - latch.countDown(); + final DnsResolver.InetAddressAnswerCallback callback = + new DnsResolver.InetAddressAnswerCallback() { + @Override + public void onAnswer(@NonNull List answerList) { + answers.set(answerList); + for (InetAddress addr : answerList) { + Log.d(TAG, "Reported addr: " + addr.toString()); } - ); + latch.countDown(); + } + + @Override + public void onParseException(@NonNull ParseException e) { + fail(msg + e.getMessage()); + } + + @Override + public void onQueryException(@NonNull ErrnoException e) { + fail(msg + e.getMessage()); + } + }; + mDns.query(network, dname, CLASS_IN, TYPE_A, FLAG_NO_CACHE_LOOKUP, mHandler, callback); try { assertTrue(msg + " but no valid answer after " + TIMEOUT_MS + "ms.", latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); assertGreaterThan(msg + " returned 0 result", answers.get().size(), 0); } catch (InterruptedException e) { + fail(msg + " Waiting for DNS lookup was interrupted"); } } } - static private void assertGreaterThan(String msg, int a, int b) { - assertTrue(msg + ": " + a + " > " + b, a > b); + static private void assertGreaterThan(String msg, int first, int second) { + assertTrue(msg + " Excepted " + first + " to be greater than " + second, first > second); } static private void assertValidAnswer(String msg, @NonNull DnsAnswer ans) { // Check rcode field.(0, No error condition). assertTrue(msg + " Response error, rcode: " + ans.getRcode(), ans.getRcode() == 0); // Check answer counts. - assertTrue(msg + " No answer found", ans.getANCount() > 0); + assertGreaterThan(msg + " No answer found", ans.getANCount(), 0); // Check question counts. - assertTrue(msg + " No question found", ans.getQDCount() > 0); + assertGreaterThan(msg + " No question found", ans.getQDCount(), 0); } static private void assertValidEmptyAnswer(String msg, @NonNull DnsAnswer ans) { @@ -129,10 +146,10 @@ public class DnsResolverTest extends AndroidTestCase { // Check answer counts. Expect 0 answer. assertTrue(msg + " Not an empty answer", ans.getANCount() == 0); // Check question counts. - assertTrue(msg + " No question found", ans.getQDCount() > 0); + assertGreaterThan(msg + " No question found", ans.getQDCount(), 0); } - private class DnsAnswer extends DnsPacket { + private static class DnsAnswer extends DnsPacket { DnsAnswer(@NonNull byte[] data) throws ParseException { super(data); // Check QR field.(query (0), or a response (1)). @@ -152,34 +169,56 @@ public class DnsResolverTest extends AndroidTestCase { } } - public void testRawQuery() throws ErrnoException { + class RawAnswerCallbackImpl extends DnsResolver.RawAnswerCallback { + private final CountDownLatch mLatch = new CountDownLatch(1); + private final String mMsg; + RawAnswerCallbackImpl(String msg) { + this.mMsg = msg; + } + + public boolean waitForAnswer() throws InterruptedException { + return mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS); + } + + @Override + public void onAnswer(@NonNull byte[] answer) { + try { + assertValidAnswer(mMsg, new DnsAnswer(answer)); + Log.d(TAG, "Reported blob: " + byteArrayToHexString(answer)); + mLatch.countDown(); + } catch (ParseException e) { + fail(mMsg + e.getMessage()); + } + } + + @Override + public void onParseException(@NonNull ParseException e) { + fail(mMsg + e.getMessage()); + } + + @Override + public void onQueryException(@NonNull ErrnoException e) { + fail(mMsg + e.getMessage()); + } + } + + public void testQueryWithRawAnswerCallback() { final String dname = "www.google.com"; - final String msg = "Raw query " + dname; + final String msg = "Query with RawAnswerCallback " + dname; for (Network network : getTestableNetworks()) { - final CountDownLatch latch = new CountDownLatch(1); - mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, mHandler, - answer -> { - if (answer == null) { - fail(msg + " no answer returned"); - } - try { - assertValidAnswer(msg, new DnsAnswer(answer)); - Log.d(TAG, "Reported blob:" + byteArrayToHexString(answer)); - latch.countDown(); - } catch (DnsPacket.ParseException e) { - fail(msg + e.getMessage()); - } - } - ); + final RawAnswerCallbackImpl callback = new RawAnswerCallbackImpl(msg); + mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, + mHandler, callback); try { assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", - latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); + callback.waitForAnswer()); } catch (InterruptedException e) { + fail(msg + " Waiting for DNS lookup was interrupted"); } } } - public void testRawQueryWithBlob() throws ErrnoException { + public void testQueryBlobWithRawAnswerCallback() { final byte[] blob = new byte[]{ /* Header */ 0x55, 0x66, /* Transaction ID */ @@ -194,74 +233,90 @@ public class DnsResolverTest extends AndroidTestCase { 0x00, 0x01, /* Type */ 0x00, 0x01 /* Class */ }; - final String msg = "Raw query with blob " + byteArrayToHexString(blob); + final String msg = "Query with RawAnswerCallback " + byteArrayToHexString(blob); for (Network network : getTestableNetworks()) { - final CountDownLatch latch = new CountDownLatch(1); - mDns.query(network, blob, FLAG_NO_CACHE_LOOKUP, mHandler, answer -> { - if (answer == null) { - fail(msg + " no answer returned"); - } - try { - assertValidAnswer(msg, new DnsAnswer(answer)); - Log.d(TAG, "Reported blob:" + byteArrayToHexString(answer)); - latch.countDown(); - } catch (DnsPacket.ParseException e) { - fail(msg + e.getMessage()); - } - } - ); + final RawAnswerCallbackImpl callback = new RawAnswerCallbackImpl(msg); + mDns.query(network, blob, FLAG_NO_CACHE_LOOKUP, mHandler, callback); try { assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", - latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); + callback.waitForAnswer()); } catch (InterruptedException e) { + fail(msg + " Waiting for DNS lookup was interrupted"); } } } - public void testEmptyQuery() throws ErrnoException { + public void testQueryRoot() { final String dname = ""; - final String msg = "Raw query empty dname(ROOT)"; + final String msg = "Query with RawAnswerCallback empty dname(ROOT) "; for (Network network : getTestableNetworks()) { final CountDownLatch latch = new CountDownLatch(1); - mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, mHandler, - answer -> { - if (answer == null) { - fail(msg + " no answer returned"); - } - try { - // Except no answer record because of querying with empty dname(ROOT) - assertValidEmptyAnswer(msg, new DnsAnswer(answer)); - latch.countDown(); - } catch (DnsPacket.ParseException e) { - fail(msg + e.getMessage()); - } + final DnsResolver.RawAnswerCallback callback = new DnsResolver.RawAnswerCallback() { + @Override + public void onAnswer(@NonNull byte[] answer) { + try { + // Except no answer record because of querying with empty dname(ROOT) + assertValidEmptyAnswer(msg, new DnsAnswer(answer)); + latch.countDown(); + } catch (ParseException e) { + fail(msg + e.getMessage()); } - ); + } + + @Override + public void onParseException(@NonNull ParseException e) { + fail(msg + e.getMessage()); + } + + @Override + public void onQueryException(@NonNull ErrnoException e) { + fail(msg + e.getMessage()); + } + }; + mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, + mHandler, callback); try { - assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + assertTrue(msg + "but no answer after " + TIMEOUT_MS + "ms.", latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); } catch (InterruptedException e) { + fail(msg + "Waiting for DNS lookup was interrupted"); } } } - public void testNXQuery() throws ErrnoException { + public void testQueryNXDomain() { final String dname = "test1-nx.metric.gstatic.com"; - final String msg = "InetAddress query " + dname; + final String msg = "Query with InetAddressAnswerCallback " + dname; for (Network network : getTestableNetworks()) { final CountDownLatch latch = new CountDownLatch(1); - mDns.query(network, dname, FLAG_NO_CACHE_LOOKUP, mHandler, answerList -> { - if (answerList.size() == 0) { - latch.countDown(); - return; - } - fail(msg + " but get valid answers"); + final DnsResolver.InetAddressAnswerCallback callback = + new DnsResolver.InetAddressAnswerCallback() { + @Override + public void onAnswer(@NonNull List answerList) { + if (answerList.size() == 0) { + latch.countDown(); + return; } - ); + fail(msg + " but get valid answers"); + } + + @Override + public void onParseException(@NonNull ParseException e) { + fail(msg + e.getMessage()); + } + + @Override + public void onQueryException(@NonNull ErrnoException e) { + fail(msg + e.getMessage()); + } + }; + mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, + mHandler, callback); try { assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); } catch (InterruptedException e) { + fail(msg + " Waiting for DNS lookup was interrupted"); } } } From 24c8d2ab38ae4a78d1223e320ec5597c8d784d76 Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Thu, 7 Mar 2019 19:04:04 +0800 Subject: [PATCH 0573/1109] Alter CTS tests for change of async DNS API Bug: 124882626 Test: built, flashed, booted atest DnsResolverTest Change-Id: If823a27773cc778fba49db02045b77222c4cd1af --- .../net/src/android/net/cts/DnsResolverTest.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/DnsResolverTest.java b/tests/cts/net/src/android/net/cts/DnsResolverTest.java index 643d54216a..6fbe586bb4 100644 --- a/tests/cts/net/src/android/net/cts/DnsResolverTest.java +++ b/tests/cts/net/src/android/net/cts/DnsResolverTest.java @@ -40,6 +40,7 @@ import java.net.InetAddress; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; @@ -51,14 +52,14 @@ public class DnsResolverTest extends AndroidTestCase { static final int TIMEOUT_MS = 12_000; private ConnectivityManager mCM; - private Handler mHandler; + private Executor mExecutor; private DnsResolver mDns; protected void setUp() throws Exception { super.setUp(); mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); - mHandler = new Handler(Looper.getMainLooper()); mDns = DnsResolver.getInstance(); + mExecutor = new Handler(Looper.getMainLooper())::post; } private static String byteArrayToHexString(byte[] bytes) { @@ -116,7 +117,8 @@ public class DnsResolverTest extends AndroidTestCase { fail(msg + e.getMessage()); } }; - mDns.query(network, dname, CLASS_IN, TYPE_A, FLAG_NO_CACHE_LOOKUP, mHandler, callback); + mDns.query(network, dname, CLASS_IN, TYPE_A, FLAG_NO_CACHE_LOOKUP, + mExecutor, callback); try { assertTrue(msg + " but no valid answer after " + TIMEOUT_MS + "ms.", latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); @@ -208,7 +210,7 @@ public class DnsResolverTest extends AndroidTestCase { for (Network network : getTestableNetworks()) { final RawAnswerCallbackImpl callback = new RawAnswerCallbackImpl(msg); mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, - mHandler, callback); + mExecutor, callback); try { assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", callback.waitForAnswer()); @@ -236,7 +238,7 @@ public class DnsResolverTest extends AndroidTestCase { final String msg = "Query with RawAnswerCallback " + byteArrayToHexString(blob); for (Network network : getTestableNetworks()) { final RawAnswerCallbackImpl callback = new RawAnswerCallbackImpl(msg); - mDns.query(network, blob, FLAG_NO_CACHE_LOOKUP, mHandler, callback); + mDns.query(network, blob, FLAG_NO_CACHE_LOOKUP, mExecutor, callback); try { assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", callback.waitForAnswer()); @@ -274,7 +276,7 @@ public class DnsResolverTest extends AndroidTestCase { } }; mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, - mHandler, callback); + mExecutor, callback); try { assertTrue(msg + "but no answer after " + TIMEOUT_MS + "ms.", latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); @@ -311,7 +313,7 @@ public class DnsResolverTest extends AndroidTestCase { } }; mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, - mHandler, callback); + mExecutor, callback); try { assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); From 361584140b7d6c7ab117a4181045c57e551e5dbc Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Fri, 8 Mar 2019 16:41:03 +0800 Subject: [PATCH 0574/1109] Add cancel test cases for async DNS API Bug: 124882626 Test: built, flashed, booted atest DnsResolverTest Change-Id: I9b496821e422f71009319eeefc6f3c6c1e249111 --- .../src/android/net/cts/DnsResolverTest.java | 162 +++++++++++++++++- 1 file changed, 155 insertions(+), 7 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/DnsResolverTest.java b/tests/cts/net/src/android/net/cts/DnsResolverTest.java index 6fbe586bb4..f6cc76852b 100644 --- a/tests/cts/net/src/android/net/cts/DnsResolverTest.java +++ b/tests/cts/net/src/android/net/cts/DnsResolverTest.java @@ -17,9 +17,11 @@ package android.net.cts; import static android.net.DnsResolver.CLASS_IN; +import static android.net.DnsResolver.FLAG_EMPTY; import static android.net.DnsResolver.FLAG_NO_CACHE_LOOKUP; import static android.net.DnsResolver.TYPE_A; import static android.net.DnsResolver.TYPE_AAAA; +import static android.system.OsConstants.EBADF; import android.annotation.NonNull; import android.annotation.Nullable; @@ -30,6 +32,7 @@ import android.net.DnsResolver; import android.net.Network; import android.net.NetworkCapabilities; import android.net.ParseException; +import android.os.CancellationSignal; import android.os.Handler; import android.os.Looper; import android.system.ErrnoException; @@ -50,6 +53,7 @@ public class DnsResolverTest extends AndroidTestCase { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; static final int TIMEOUT_MS = 12_000; + static final int CANCEL_RETRY_TIMES = 5; private ConnectivityManager mCM; private Executor mExecutor; @@ -118,7 +122,7 @@ public class DnsResolverTest extends AndroidTestCase { } }; mDns.query(network, dname, CLASS_IN, TYPE_A, FLAG_NO_CACHE_LOOKUP, - mExecutor, callback); + mExecutor, null, callback); try { assertTrue(msg + " but no valid answer after " + TIMEOUT_MS + "ms.", latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); @@ -174,12 +178,19 @@ public class DnsResolverTest extends AndroidTestCase { class RawAnswerCallbackImpl extends DnsResolver.RawAnswerCallback { private final CountDownLatch mLatch = new CountDownLatch(1); private final String mMsg; - RawAnswerCallbackImpl(String msg) { + private final int mTimeout; + + RawAnswerCallbackImpl(@NonNull String msg, int timeout) { this.mMsg = msg; + this.mTimeout = timeout; + } + + RawAnswerCallbackImpl(@NonNull String msg) { + this(msg, TIMEOUT_MS); } public boolean waitForAnswer() throws InterruptedException { - return mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS); + return mLatch.await(mTimeout, TimeUnit.MILLISECONDS); } @Override @@ -210,7 +221,7 @@ public class DnsResolverTest extends AndroidTestCase { for (Network network : getTestableNetworks()) { final RawAnswerCallbackImpl callback = new RawAnswerCallbackImpl(msg); mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, - mExecutor, callback); + mExecutor, null, callback); try { assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", callback.waitForAnswer()); @@ -238,7 +249,7 @@ public class DnsResolverTest extends AndroidTestCase { final String msg = "Query with RawAnswerCallback " + byteArrayToHexString(blob); for (Network network : getTestableNetworks()) { final RawAnswerCallbackImpl callback = new RawAnswerCallbackImpl(msg); - mDns.query(network, blob, FLAG_NO_CACHE_LOOKUP, mExecutor, callback); + mDns.query(network, blob, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); try { assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", callback.waitForAnswer()); @@ -276,7 +287,7 @@ public class DnsResolverTest extends AndroidTestCase { } }; mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, - mExecutor, callback); + mExecutor, null, callback); try { assertTrue(msg + "but no answer after " + TIMEOUT_MS + "ms.", latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); @@ -313,7 +324,7 @@ public class DnsResolverTest extends AndroidTestCase { } }; mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, - mExecutor, callback); + mExecutor, null, callback); try { assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); @@ -322,4 +333,141 @@ public class DnsResolverTest extends AndroidTestCase { } } } + + /** + * A query callback that ensures that the query is cancelled and that onAnswer is never + * called. If the query succeeds before it is cancelled, needRetry will return true so the + * test can retry. + */ + class VerifyCancelCallback extends DnsResolver.RawAnswerCallback { + private static final int CANCEL_TIMEOUT = 3_000; + + private final CountDownLatch mLatch = new CountDownLatch(1); + private final String mMsg; + private final CancellationSignal mCancelSignal; + + VerifyCancelCallback(@NonNull String msg, @NonNull CancellationSignal cancelSignal) { + this.mMsg = msg; + this.mCancelSignal = cancelSignal; + } + + public boolean needRetry() throws InterruptedException { + return mLatch.await(CANCEL_TIMEOUT, TimeUnit.MILLISECONDS); + } + + @Override + public void onAnswer(@NonNull byte[] answer) { + if (mCancelSignal.isCanceled()) { + fail(mMsg + " should not have returned any answers"); + } + mLatch.countDown(); + } + + @Override + public void onParseException(@NonNull ParseException e) { + fail(mMsg + e.getMessage()); + } + + @Override + public void onQueryException(@NonNull ErrnoException e) { + if (mCancelSignal.isCanceled() && e.errno == EBADF) return; + fail(mMsg + e.getMessage()); + } + } + + public void testQueryCancel() throws ErrnoException { + final String dname = "www.google.com"; + final String msg = "Test cancel query " + dname; + // Start a DNS query and the cancel it immediately. Use VerifyCancelCallback to expect + // that the query is cancelled before it succeeds. If it is not cancelled before it + // succeeds, retry the until it is. + for (Network network : getTestableNetworks()) { + boolean retry = false; + int round = 0; + do { + if (++round > CANCEL_RETRY_TIMES) { + fail(msg + " cancel failed " + CANCEL_RETRY_TIMES + " times"); + } + final CountDownLatch latch = new CountDownLatch(1); + final CancellationSignal cancelSignal = new CancellationSignal(); + final VerifyCancelCallback callback = new VerifyCancelCallback(msg, cancelSignal); + mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_EMPTY, + mExecutor, cancelSignal, callback); + mExecutor.execute(() -> { + cancelSignal.cancel(); + latch.countDown(); + }); + try { + retry = callback.needRetry(); + assertTrue(msg + " query was not cancelled", + latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); + } catch (InterruptedException e) { + fail(msg + "Waiting for DNS lookup was interrupted"); + } + } while (retry); + } + } + + public void testQueryBlobCancel() throws ErrnoException { + final byte[] blob = new byte[]{ + /* Header */ + 0x55, 0x66, /* Transaction ID */ + 0x01, 0x00, /* Flags */ + 0x00, 0x01, /* Questions */ + 0x00, 0x00, /* Answer RRs */ + 0x00, 0x00, /* Authority RRs */ + 0x00, 0x00, /* Additional RRs */ + /* Queries */ + 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65, + 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */ + 0x00, 0x01, /* Type */ + 0x00, 0x01 /* Class */ + }; + final String msg = "Test cancel raw Query " + byteArrayToHexString(blob); + // Start a DNS query and the cancel it immediately. Use VerifyCancelCallback to expect + // that the query is cancelled before it succeeds. If it is not cancelled before it + // succeeds, retry the until it is. + for (Network network : getTestableNetworks()) { + boolean retry = false; + int round = 0; + do { + if (++round > CANCEL_RETRY_TIMES) { + fail(msg + " cancel failed " + CANCEL_RETRY_TIMES + " times"); + } + final CountDownLatch latch = new CountDownLatch(1); + final CancellationSignal cancelSignal = new CancellationSignal(); + final VerifyCancelCallback callback = new VerifyCancelCallback(msg, cancelSignal); + mDns.query(network, blob, FLAG_EMPTY, mExecutor, cancelSignal, callback); + mExecutor.execute(() -> { + cancelSignal.cancel(); + latch.countDown(); + }); + try { + retry = callback.needRetry(); + assertTrue(msg + " cancel is not done", + latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); + } catch (InterruptedException e) { + fail(msg + " Waiting for DNS lookup was interrupted"); + } + } while (retry); + } + } + + public void testCancelBeforeQuery() throws ErrnoException { + final String dname = "www.google.com"; + final String msg = "Test cancelled query " + dname; + for (Network network : getTestableNetworks()) { + final RawAnswerCallbackImpl callback = new RawAnswerCallbackImpl(msg, 3_000); + final CancellationSignal cancelSignal = new CancellationSignal(); + cancelSignal.cancel(); + mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_EMPTY, + mExecutor, cancelSignal, callback); + try { + assertTrue(msg + " should not return any answers", + !callback.waitForAnswer()); + } catch (InterruptedException e) { + fail(msg + " Waiting for DNS lookup was interrupted"); + } + } + } } From d05db41eb7a413339d25f8bd37f44b229980a1a5 Mon Sep 17 00:00:00 2001 From: junyulai Date: Tue, 19 Mar 2019 21:34:38 +0800 Subject: [PATCH 0575/1109] Export API of listening for network change events in app2 Currently, due to foreground app will never get blocked by NetworkPolicyManagerService, so onBlockedStatusChanged cannot be tested under cts net app. Thus, listen for network change events in app2 allows subsequent tests on NetworkCallbacks. Bug: 118862340 Test: m -j cts Change-Id: I26ca370fc6ae4dd3f32ce6cf448bae83f3fbfbcc --- tests/cts/hostside/aidl/Android.mk | 1 + .../android/cts/net/hostside/IMyService.aidl | 3 + .../cts/net/hostside/INetworkCallback.aidl | 25 +++++++ ...ractRestrictBackgroundNetworkTestCase.java | 4 + .../cts/net/hostside/MyServiceClient.java | 6 +- .../cts/net/hostside/app2/MyService.java | 74 ++++++++++++++++++- 6 files changed, 108 insertions(+), 5 deletions(-) create mode 100644 tests/cts/hostside/aidl/com/android/cts/net/hostside/INetworkCallback.aidl diff --git a/tests/cts/hostside/aidl/Android.mk b/tests/cts/hostside/aidl/Android.mk index 85f71c3726..20dabc15b2 100644 --- a/tests/cts/hostside/aidl/Android.mk +++ b/tests/cts/hostside/aidl/Android.mk @@ -19,6 +19,7 @@ LOCAL_MODULE_TAGS := tests LOCAL_SDK_VERSION := current LOCAL_SRC_FILES := \ com/android/cts/net/hostside/IMyService.aidl \ + com/android/cts/net/hostside/INetworkCallback.aidl \ com/android/cts/net/hostside/INetworkStateObserver.aidl \ com/android/cts/net/hostside/IRemoteSocketFactory.aidl LOCAL_MODULE := CtsHostsideNetworkTestsAidl diff --git a/tests/cts/hostside/aidl/com/android/cts/net/hostside/IMyService.aidl b/tests/cts/hostside/aidl/com/android/cts/net/hostside/IMyService.aidl index 72d105990e..a820ae581f 100644 --- a/tests/cts/hostside/aidl/com/android/cts/net/hostside/IMyService.aidl +++ b/tests/cts/hostside/aidl/com/android/cts/net/hostside/IMyService.aidl @@ -16,10 +16,13 @@ package com.android.cts.net.hostside; +import com.android.cts.net.hostside.INetworkCallback; + interface IMyService { void registerBroadcastReceiver(); int getCounters(String receiverName, String action); String checkNetworkStatus(); String getRestrictBackgroundStatus(); void sendNotification(int notificationId, String notificationType); + void registerNetworkCallback(in INetworkCallback cb); } diff --git a/tests/cts/hostside/aidl/com/android/cts/net/hostside/INetworkCallback.aidl b/tests/cts/hostside/aidl/com/android/cts/net/hostside/INetworkCallback.aidl new file mode 100644 index 0000000000..740ec26ee2 --- /dev/null +++ b/tests/cts/hostside/aidl/com/android/cts/net/hostside/INetworkCallback.aidl @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import android.net.Network; + +interface INetworkCallback { + void onBlockedStatusChanged(in Network network, boolean blocked); + void onAvailable(in Network network); + void onLost(in Network network); +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 5232372047..d15913d85c 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -962,6 +962,10 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation fail("app2 receiver is not ready"); } + protected void registerNetworkCallback(INetworkCallback cb) throws Exception { + mServiceClient.registerNetworkCallback(cb); + } + /** * Registers a {@link NotificationListenerService} implementation that will execute the * notification actions right after the notification is sent. diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyServiceClient.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyServiceClient.java index e2976c2150..3ee7b99c35 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyServiceClient.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MyServiceClient.java @@ -26,8 +26,6 @@ import android.os.RemoteException; import com.android.cts.net.hostside.IMyService; -import java.io.FileDescriptor; - public class MyServiceClient { private static final int TIMEOUT_MS = 5000; private static final String PACKAGE = MyServiceClient.class.getPackage().getName(); @@ -98,4 +96,8 @@ public class MyServiceClient { public void sendNotification(int notificationId, String notificationType) throws RemoteException { mService.sendNotification(notificationId, notificationType); } + + public void registerNetworkCallback(INetworkCallback cb) throws RemoteException { + mService.registerNetworkCallback(cb); + } } diff --git a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java index 2496c4ac7d..ec536aff68 100644 --- a/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java +++ b/tests/cts/hostside/app2/src/com/android/cts/net/hostside/app2/MyService.java @@ -16,6 +16,7 @@ package com.android.cts.net.hostside.app2; import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; + import static com.android.cts.net.hostside.app2.Common.ACTION_RECEIVER_READY; import static com.android.cts.net.hostside.app2.Common.DYNAMIC_RECEIVER; import static com.android.cts.net.hostside.app2.Common.TAG; @@ -26,13 +27,16 @@ import android.app.Service; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.SharedPreferences; +import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.NetworkRequest; import android.os.IBinder; -import android.os.Looper; +import android.os.RemoteException; import android.util.Log; -import android.widget.Toast; import com.android.cts.net.hostside.IMyService; +import com.android.cts.net.hostside.INetworkCallback; /** * Service used to dynamically register a broadcast receiver. @@ -40,7 +44,10 @@ import com.android.cts.net.hostside.IMyService; public class MyService extends Service { private static final String NOTIFICATION_CHANNEL_ID = "MyService"; + ConnectivityManager mCm; + private MyBroadcastReceiver mReceiver; + private ConnectivityManager.NetworkCallback mNetworkCallback; // TODO: move MyBroadcast static functions here - they were kept there to make git diff easier. @@ -81,8 +88,67 @@ public class MyService extends Service { MyBroadcastReceiver .sendNotification(getApplicationContext(), NOTIFICATION_CHANNEL_ID, notificationId, notificationType); } + + @Override + public void registerNetworkCallback(INetworkCallback cb) { + if (mNetworkCallback != null) { + Log.d(TAG, "unregister previous network callback: " + mNetworkCallback); + unregisterNetworkCallback(); + } + Log.d(TAG, "registering network callback"); + + mNetworkCallback = new ConnectivityManager.NetworkCallback() { + @Override + public void onBlockedStatusChanged(Network network, boolean blocked) { + try { + cb.onBlockedStatusChanged(network, blocked); + } catch (RemoteException e) { + Log.d(TAG, "Cannot send onBlockedStatusChanged: " + e); + unregisterNetworkCallback(); + } + } + + @Override + public void onAvailable(Network network) { + try { + cb.onAvailable(network); + } catch (RemoteException e) { + Log.d(TAG, "Cannot send onAvailable: " + e); + unregisterNetworkCallback(); + } + } + + @Override + public void onLost(Network network) { + try { + cb.onLost(network); + } catch (RemoteException e) { + Log.d(TAG, "Cannot send onLost: " + e); + unregisterNetworkCallback(); + } + } + }; + mCm.registerNetworkCallback(makeWifiNetworkRequest(), mNetworkCallback); + try { + cb.asBinder().linkToDeath(() -> unregisterNetworkCallback(), 0); + } catch (RemoteException e) { + unregisterNetworkCallback(); + } + } }; + private void unregisterNetworkCallback() { + Log.d(TAG, "unregistering network callback"); + mCm.unregisterNetworkCallback(mNetworkCallback); + mNetworkCallback = null; + } + + private NetworkRequest makeWifiNetworkRequest() { + return new NetworkRequest.Builder() + .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) + .build(); + } + @Override public IBinder onBind(Intent intent) { return mBinder; @@ -94,6 +160,8 @@ public class MyService extends Service { ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE)) .createNotificationChannel(new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT)); + mCm = (ConnectivityManager) getApplicationContext() + .getSystemService(Context.CONNECTIVITY_SERVICE); } @Override From 27e1316c337fe96920061ebe2ac0120b1de50536 Mon Sep 17 00:00:00 2001 From: junyulai Date: Wed, 20 Mar 2019 14:45:10 +0800 Subject: [PATCH 0576/1109] Add cts test cases for NetworkCallback.onBlockedStatusChanged Bug: 118862340 Test: atest HostsideNetworkCallbackTests Change-Id: Ic19b3b648a94adf4449393beb9b30ad7a7dc2283 --- ...ractRestrictBackgroundNetworkTestCase.java | 17 ++ .../cts/net/hostside/DataSaverModeTest.java | 17 -- .../cts/net/hostside/NetworkCallbackTest.java | 241 ++++++++++++++++++ .../cts/net/HostsideNetworkCallbackTests.java | 42 +++ 4 files changed, 300 insertions(+), 17 deletions(-) create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java create mode 100644 tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index d15913d85c..bbc0354e2f 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -369,6 +369,23 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation fail("App2 is not on foreground service state after " + maxTries + " attempts: " + state ); } + /** + * As per CDD requirements, if the device doesn't support data saver mode then + * ConnectivityManager.getRestrictBackgroundStatus() will always return + * RESTRICT_BACKGROUND_STATUS_DISABLED. So, enable the data saver mode and check if + * ConnectivityManager.getRestrictBackgroundStatus() for an app in background returns + * RESTRICT_BACKGROUND_STATUS_DISABLED or not. + */ + protected boolean isDataSaverSupported() throws Exception { + assertMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + try { + setRestrictBackground(true); + return !isMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + } finally { + setRestrictBackground(false); + } + } + /** * Returns whether an app state should be considered "background" for restriction purposes. */ diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index 599a31ce1c..72563d499e 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -73,23 +73,6 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase return mIsDataSaverSupported && super.isSupported(); } - /** - * As per CDD requirements, if the device doesn't support data saver mode then - * ConnectivityManager.getRestrictBackgroundStatus() will always return - * RESTRICT_BACKGROUND_STATUS_DISABLED. So, enable the data saver mode and check if - * ConnectivityManager.getRestrictBackgroundStatus() for an app in background returns - * RESTRICT_BACKGROUND_STATUS_DISABLED or not. - */ - private boolean isDataSaverSupported() throws Exception { - assertMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); - try { - setRestrictBackground(true); - return !isMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); - } finally { - setRestrictBackground(false); - } - } - public void testGetRestrictBackgroundStatus_disabled() throws Exception { if (!isSupported()) return; diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java new file mode 100644 index 0000000000..24dde9d356 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import android.net.Network; + +import java.util.Objects; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCase { + + private boolean mIsDataSaverSupported; + private Network mNetwork; + private final TestNetworkCallback mTestNetworkCallback = new TestNetworkCallback(); + + enum CallbackState { + NONE, + AVAILABLE, + LOST, + BLOCKED_STATUS + } + + private static class CallbackInfo { + public final CallbackState state; + public final Network network; + public final Object arg; + + CallbackInfo(CallbackState s, Network n, Object o) { + state = s; network = n; arg = o; + } + + public String toString() { + return String.format("%s (%s) (%s)", state, network, arg); + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof CallbackInfo)) return false; + // Ignore timeMs, since it's unpredictable. + final CallbackInfo other = (CallbackInfo) o; + return (state == other.state) && Objects.equals(network, other.network) + && Objects.equals(arg, other.arg); + } + + @Override + public int hashCode() { + return Objects.hash(state, network, arg); + } + } + + private class TestNetworkCallback extends INetworkCallback.Stub { + private static final int TEST_CALLBACK_TIMEOUT_MS = 200; + + private final LinkedBlockingQueue mCallbacks = new LinkedBlockingQueue<>(); + + protected void setLastCallback(CallbackState state, Network network, Object o) { + mCallbacks.offer(new CallbackInfo(state, network, o)); + } + + CallbackInfo nextCallback(int timeoutMs) { + CallbackInfo cb = null; + try { + cb = mCallbacks.poll(timeoutMs, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + } + if (cb == null) { + fail("Did not receive callback after " + timeoutMs + "ms"); + } + return cb; + } + + CallbackInfo expectCallback(CallbackState state, Network expectedNetwork, Object o) { + final CallbackInfo expected = new CallbackInfo(state, expectedNetwork, o); + final CallbackInfo actual = nextCallback(TEST_CALLBACK_TIMEOUT_MS); + assertEquals("Unexpected callback:", expected, actual); + return actual; + } + + @Override + public void onAvailable(Network network) { + setLastCallback(CallbackState.AVAILABLE, network, null); + } + + @Override + public void onLost(Network network) { + setLastCallback(CallbackState.LOST, network, null); + } + + @Override + public void onBlockedStatusChanged(Network network, boolean blocked) { + setLastCallback(CallbackState.BLOCKED_STATUS, network, blocked); + } + + public void expectLostCallback(Network expectedNetwork) { + expectCallback(CallbackState.LOST, expectedNetwork, null); + } + + public void expectAvailableCallback(Network expectedNetwork) { + expectCallback(CallbackState.AVAILABLE, expectedNetwork, null); + } + + public void expectBlockedStatusCallback(Network expectedNetwork, boolean expectBlocked) { + expectCallback(CallbackState.BLOCKED_STATUS, expectedNetwork, + expectBlocked); + } + + void assertNoCallback() { + CallbackInfo cb = null; + try { + cb = mCallbacks.poll(TEST_CALLBACK_TIMEOUT_MS, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + // Expected. + } + if (cb != null) { + assertNull("Unexpected callback: " + cb, cb); + } + } + } + + @Override + public void setUp() throws Exception { + super.setUp(); + + mIsDataSaverSupported = isDataSaverSupported(); + + mNetwork = mCm.getActiveNetwork(); + + // Set initial state. + setBatterySaverMode(false); + registerBroadcastReceiver(); + + if (!mIsDataSaverSupported) return; + setRestrictBackground(false); + removeRestrictBackgroundWhitelist(mUid); + removeRestrictBackgroundBlacklist(mUid); + assertRestrictBackgroundChangedReceived(0); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + + if (!mIsDataSaverSupported) return; + + try { + resetMeteredNetwork(); + } finally { + setRestrictBackground(false); + } + } + + public void testOnBlockedStatusChanged_data_saver() throws Exception { + if (!mIsDataSaverSupported) return; + + // Prepare metered wifi + if (!setMeteredNetwork()) return; + + // Register callback + registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); + mTestNetworkCallback.expectAvailableCallback(mNetwork); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Enable restrict background + setRestrictBackground(true); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); + + // Add to whitelist + addRestrictBackgroundWhitelist(mUid); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Remove from whitelist + removeRestrictBackgroundWhitelist(mUid); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); + + // Set to non-metered network + setUnmeteredNetwork(); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Disable restrict background, should not trigger callback + setRestrictBackground(false); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.assertNoCallback(); + } + + + public void testOnBlockedStatusChanged_power_saver() throws Exception { + // Prepare metered wifi + if (!setMeteredNetwork()) return; + + // Register callback + registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); + mTestNetworkCallback.expectAvailableCallback(mNetwork); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Enable Power Saver + setBatterySaverMode(true); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); + + // Disable Power Saver + setBatterySaverMode(false); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Set to non-metered network + setUnmeteredNetwork(); + mTestNetworkCallback.assertNoCallback(); + + // Enable Power Saver + setBatterySaverMode(true); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); + + // Disable Power Saver + setBatterySaverMode(false); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + } + + // TODO: 1. test against VPN lockdown. + // 2. test against multiple networks. +} diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java new file mode 100644 index 0000000000..8d6c4acd7d --- /dev/null +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2019 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.cts.net; +public class HostsideNetworkCallbackTests extends HostsideNetworkTestCase { + + @Override + protected void setUp() throws Exception { + super.setUp(); + uninstallPackage(TEST_APP2_PKG, false); + installPackage(TEST_APP2_APK); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + uninstallPackage(TEST_APP2_PKG, true); + } + + public void testOnBlockedStatusChanged_data_saver() throws Exception { + runDeviceTests(TEST_PKG, + TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_data_saver"); + } + + public void testOnBlockedStatusChanged_power_saver() throws Exception { + runDeviceTests(TEST_PKG, + TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_power_saver"); + } +} + From f011d5f95bf73c8f0a64fe15ddd0ef29ca253863 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Mon, 25 Mar 2019 13:40:16 +0900 Subject: [PATCH 0577/1109] Enable instant and ABI XML tags for native networking tests. These tests include native code so mark them as multi_abi. They also pass in instant mode so mark them instant_app. Fix: 123367032 Fix: 123367595 Test: atest CtsNativeNetDnsTestCases CtsNativeNetTestCases Test: cts-tradefed run commandAndExit cts --enable-parameterized-modules --module-parameter instant_app -m CtsNativeNetDnsTestCases Test: cts-tradefed run commandAndExit cts --enable-parameterized-modules --module-parameter instant_app -m CtsNativeNetTestCases Change-Id: Id66705ecb012a07aa34318f41afb1840dd25b9e3 --- tests/cts/net/native/dns/AndroidTest.xml | 2 ++ tests/cts/net/native/qtaguid/AndroidTest.xml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/cts/net/native/dns/AndroidTest.xml b/tests/cts/net/native/dns/AndroidTest.xml index e63c6789a5..fe88cdaffe 100644 --- a/tests/cts/net/native/dns/AndroidTest.xml +++ b/tests/cts/net/native/dns/AndroidTest.xml @@ -16,6 +16,8 @@ diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java index 7c9ce8f833..a2443b391a 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java @@ -128,7 +128,7 @@ abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiRec protected void runDeviceTests(String packageName, String testClassName, String methodName) throws DeviceNotAvailableException { RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(packageName, - "android.support.test.runner.AndroidJUnitRunner", getDevice().getIDevice()); + "androidx.test.runner.AndroidJUnitRunner", getDevice().getIDevice()); if (testClassName != null) { if (methodName != null) { diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index 1430071997..45941a79e1 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -41,8 +41,8 @@ LOCAL_PACKAGE_NAME := CtsNetTestCases LOCAL_STATIC_JAVA_LIBRARIES := \ core-tests-support \ - compatibility-device-util \ - ctstestrunner \ + compatibility-device-util-axt \ + ctstestrunner-axt \ ctstestserver \ mockwebserver \ junit \ diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index 0bfb650882..b261b39885 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -42,7 +42,7 @@ - Date: Wed, 19 Dec 2018 23:50:35 -0800 Subject: [PATCH 0579/1109] RESTRICT AUTOMERGE: Port "Exempt adb socket for hostside VpnTest" to Cts 8.1 https://android-review.googlesource.com/c/platform/cts/+/833600 Change-Id: Id6f986aacc3cadf713ebbc8305ca535b861390fc Bug: 119382723 --- tests/cts/hostside/app/Android.mk | 3 ++- .../com/android/cts/net/hostside/VpnTest.java | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) mode change 100644 => 100755 tests/cts/hostside/app/Android.mk diff --git a/tests/cts/hostside/app/Android.mk b/tests/cts/hostside/app/Android.mk old mode 100644 new mode 100755 index f094f3f4a1..127ef322e6 --- a/tests/cts/hostside/app/Android.mk +++ b/tests/cts/hostside/app/Android.mk @@ -19,7 +19,8 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests -LOCAL_SDK_VERSION := current +#LOCAL_SDK_VERSION := current +LOCAL_PRIVATE_PLATFORM_APIS := true LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util ctstestrunner ub-uiautomator \ CtsHostsideNetworkTestsAidl diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java index bc982cec78..b3f61c486d 100755 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java @@ -29,6 +29,7 @@ import android.net.NetworkRequest; import android.net.VpnService; import android.os.ParcelFileDescriptor; import android.os.Process; +import android.os.SystemProperties; import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiObject; import android.support.test.uiautomator.UiObjectNotFoundException; @@ -537,6 +538,14 @@ public class VpnTest extends InstrumentationTestCase { public void testDefault() throws Exception { if (!supportedHardware()) return; + // If adb TCP port opened, this test may running by adb over network. + // All of socket would be destroyed in this test. So this test don't + // support adb over network, see b/119382723. + if (SystemProperties.getInt("persist.adb.tcp.port", -1) > -1 + || SystemProperties.getInt("service.adb.tcp.port", -1) > -1) { + Log.i(TAG, "adb is running over the network, so skip this test"); + return; + } FileDescriptor fd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS); @@ -554,6 +563,7 @@ public class VpnTest extends InstrumentationTestCase { FileDescriptor fd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS); + // Shell app must not be put in here or it would kill the ADB-over-network use case String allowedApps = mRemoteSocketFactoryClient.getPackageName() + "," + mPackageName; startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"}, new String[] {"192.0.2.0/24", "2001:db8::/32"}, @@ -571,6 +581,12 @@ public class VpnTest extends InstrumentationTestCase { FileDescriptor remoteFd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS); String disallowedApps = mRemoteSocketFactoryClient.getPackageName() + "," + mPackageName; + // If adb TCP port opened, this test may running by adb over TCP. + // Add com.android.shell appllication into blacklist to exclude adb socket for VPN test, + // see b/119382723. + // Note: The test don't support running adb over network for root device + disallowedApps = disallowedApps + ",com.android.shell"; + Log.i(TAG, "Append shell app to disallowedApps: " + disallowedApps); startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"}, new String[] {"192.0.2.0/24", "2001:db8::/32"}, "", disallowedApps); From acadb939b5e74d5035099545763cffe1cd20dd79 Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Tue, 26 Mar 2019 17:43:42 +0800 Subject: [PATCH 0580/1109] Improve test and fix doulbe-close fd problem for async DNS API cts 1. Change test cases for enlarging buffer size of FrameworkListener. 2. Remove test procedure which caused doulbe-close fd. Bug: 129317069 Bug: 126307309 Test: atest CtsNativeNetDnsTestCases MultinetworkApiTest Change-Id: I8d871cebca6fa7e298a874ba430ec0aaa05c0eed --- tests/cts/net/jni/NativeMultinetworkJni.cpp | 31 +++++++++---------- .../cts/net/native/dns/NativeDnsAsyncTest.cpp | 21 ++++++------- 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/tests/cts/net/jni/NativeMultinetworkJni.cpp b/tests/cts/net/jni/NativeMultinetworkJni.cpp index d1a92a47a1..a6b5e90b1d 100644 --- a/tests/cts/net/jni/NativeMultinetworkJni.cpp +++ b/tests/cts/net/jni/NativeMultinetworkJni.cpp @@ -245,13 +245,12 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runResNcancelCheck( net_handle_t handle = (net_handle_t) nethandle; int fd = android_res_nquery(handle, kGoogleName, ns_c_in, ns_t_a, 0); - int rcode = -1; - uint8_t buf[MAXPACKET] = {}; + errno = 0; android_res_cancel(fd); - EXPECT_EQ(env, -EBADF, android_res_nresult(fd, &rcode, buf, MAXPACKET), "res_cancel"); - - android_res_cancel(fd); - EXPECT_EQ(env, -EBADF, android_res_nresult(fd, &rcode, buf, MAXPACKET), "res_cancel"); + int err = errno; + EXPECT_EQ(env, 0, err, "res_cancel"); + // DO NOT call cancel or result with the same fd more than once, + // otherwise it will hit fdsan double-close fd. return 0; } @@ -288,10 +287,10 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runResNapiMalformedCheck fd = android_res_nsend(handle, largeBuf, sizeof(largeBuf), 0); EXPECT_EQ(env, -EMSGSIZE, fd, "res_nsend buffer larger than 8KB"); - // 1000 bytes filled with 0. This returns EMSGSIZE because FrameworkListener limits the size of - // commands to 1024 bytes. TODO: b/126307309 - fd = android_res_nsend(handle, largeBuf, 1000, 0); - EXPECT_EQ(env, -EMSGSIZE, fd, "res_nsend 1000 bytes filled with 0"); + // 5000 bytes filled with 0. This returns EMSGSIZE because FrameworkListener limits the size of + // commands to 4096 bytes. + fd = android_res_nsend(handle, largeBuf, 5000, 0); + EXPECT_EQ(env, -EMSGSIZE, fd, "res_nsend 5000 bytes filled with 0"); // 500 bytes filled with 0 fd = android_res_nsend(handle, largeBuf, 500, 0); @@ -299,16 +298,16 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runResNapiMalformedCheck EXPECT_EQ(env, 0, expectAnswersNotValid(env, fd, -EINVAL), "res_nsend 500 bytes filled with 0 check answers"); - // 1000 bytes filled with 0xFF - uint8_t ffBuf[1001] = {}; + // 5000 bytes filled with 0xFF + uint8_t ffBuf[5001] = {}; memset(ffBuf, 0xFF, sizeof(ffBuf)); - ffBuf[1000] = '\0'; + ffBuf[5000] = '\0'; fd = android_res_nsend(handle, ffBuf, sizeof(ffBuf), 0); - EXPECT_EQ(env, -EMSGSIZE, fd, "res_nsend 1000 bytes filled with 0xFF"); + EXPECT_EQ(env, -EMSGSIZE, fd, "res_nsend 5000 bytes filled with 0xFF"); // 500 bytes filled with 0xFF - ffBuf[501] = '\0'; - fd = android_res_nsend(handle, ffBuf, 500, 0); + ffBuf[500] = '\0'; + fd = android_res_nsend(handle, ffBuf, 501, 0); EXPECT_GE(env, fd, 0, "res_nsend 500 bytes filled with 0xFF"); EXPECT_EQ(env, 0, expectAnswersNotValid(env, fd, -EINVAL), "res_nsend 500 bytes filled with 0xFF check answers"); diff --git a/tests/cts/net/native/dns/NativeDnsAsyncTest.cpp b/tests/cts/net/native/dns/NativeDnsAsyncTest.cpp index 2fc9ff8fd8..e501475996 100644 --- a/tests/cts/net/native/dns/NativeDnsAsyncTest.cpp +++ b/tests/cts/net/native/dns/NativeDnsAsyncTest.cpp @@ -194,13 +194,12 @@ TEST (NativeDnsAsyncTest, Async_NXDOMAIN) { TEST (NativeDnsAsyncTest, Async_Cancel) { int fd = android_res_nquery( NETWORK_UNSPECIFIED, "www.google.com", ns_c_in, ns_t_a, 0); - int rcode = -1; - uint8_t buf[MAXPACKET] = {}; + errno = 0; android_res_cancel(fd); - android_res_cancel(fd); - - int res = android_res_nresult(fd, &rcode, buf, MAXPACKET); - EXPECT_EQ(-EBADF, res); + int err = errno; + EXPECT_EQ(err, 0); + // DO NOT call cancel or result with the same fd more than once, + // otherwise it will hit fdsan double-close fd. } TEST (NativeDnsAsyncTest, Async_Query_MALFORMED) { @@ -235,9 +234,9 @@ TEST (NativeDnsAsyncTest, Async_Send_MALFORMED) { NETWORK_UNSPECIFIED, largeBuf.data(), largeBuf.size(), 0); EXPECT_EQ(-EMSGSIZE, fd); - // 1000 bytes filled with 0. This returns EMSGSIZE because FrameworkListener limits the size of - // commands to 1024 bytes. TODO: fix this. - fd = android_res_nsend(NETWORK_UNSPECIFIED, largeBuf.data(), 1000, 0); + // 5000 bytes filled with 0. This returns EMSGSIZE because FrameworkListener limits the size of + // commands to 4096 bytes. + fd = android_res_nsend(NETWORK_UNSPECIFIED, largeBuf.data(), 5000, 0); EXPECT_EQ(-EMSGSIZE, fd); // 500 bytes filled with 0 @@ -245,8 +244,8 @@ TEST (NativeDnsAsyncTest, Async_Send_MALFORMED) { EXPECT_GE(fd, 0); expectAnswersNotValid(fd, -EINVAL); - // 1000 bytes filled with 0xFF - std::vector ffBuf(1000, 0xFF); + // 5000 bytes filled with 0xFF + std::vector ffBuf(5000, 0xFF); fd = android_res_nsend( NETWORK_UNSPECIFIED, ffBuf.data(), ffBuf.size(), 0); EXPECT_EQ(-EMSGSIZE, fd); From 3852fd92f583e4f05db4d086b168df9f070eae4c Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Thu, 28 Mar 2019 17:38:32 +0900 Subject: [PATCH 0581/1109] Fix expected reverse lookup of Google DNS IP addresses DnsTest.testDnsWorks expects that reverse lookup for the Google public DNS servers will return something with google.com in the name. This no longer works because the reverse DNS entries have changed to dns.google. Bug: 129452237 Test: atest android.net.cts.DnsTest.testDnsWorks Change-Id: Iee8bfe418bf6003e5c78df77d75f6f9745249267 --- tests/cts/net/jni/NativeDnsJni.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/cts/net/jni/NativeDnsJni.c b/tests/cts/net/jni/NativeDnsJni.c index 352c0c52cc..6d3d1c3250 100644 --- a/tests/cts/net/jni/NativeDnsJni.c +++ b/tests/cts/net/jni/NativeDnsJni.c @@ -120,8 +120,8 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas gai_strerror(res)); return JNI_FALSE; } - if (strstr(buf, "google.com") == NULL) { - ALOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com: %s", + if (strstr(buf, "google.com") == NULL && strstr(buf, "dns.google") == NULL) { + ALOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com or dns.google: %s", GoogleDNSIpV4Address, buf); return JNI_FALSE; } @@ -133,8 +133,9 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas res, gai_strerror(res)); return JNI_FALSE; } - if (strstr(buf, "google.com") == NULL) { - ALOGD("getnameinfo(%s) didn't return google.com: %s", GoogleDNSIpV6Address2, buf); + if (strstr(buf, "google.com") == NULL && strstr(buf, "dns.google") == NULL) { + ALOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com or dns.google: %s", + GoogleDNSIpV6Address2, buf); return JNI_FALSE; } From 92f1edd2f0b2d19568c2ee70e86208eb34506d10 Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Tue, 26 Mar 2019 19:41:38 +0800 Subject: [PATCH 0582/1109] Improve cancellation test for async DNS API After having a lock between callback and cancellationsignal, errno with EBADF should not happen. Bug: 129317069 Test: atest DnsResolverTest Change-Id: I08e800b078d40345eb3f46da1323db251c8dcd47 --- tests/cts/net/src/android/net/cts/DnsResolverTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/DnsResolverTest.java b/tests/cts/net/src/android/net/cts/DnsResolverTest.java index f6cc76852b..57a5dc7788 100644 --- a/tests/cts/net/src/android/net/cts/DnsResolverTest.java +++ b/tests/cts/net/src/android/net/cts/DnsResolverTest.java @@ -370,7 +370,6 @@ public class DnsResolverTest extends AndroidTestCase { @Override public void onQueryException(@NonNull ErrnoException e) { - if (mCancelSignal.isCanceled() && e.errno == EBADF) return; fail(mMsg + e.getMessage()); } } From 8fd050640166eb04cc96c1933cb6a2093155d7dc Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Thu, 28 Mar 2019 21:04:11 +0800 Subject: [PATCH 0583/1109] Add more test for async DNS api Bug: 129395490 Test: atest DnsResolverTest Change-Id: I4d2cdc2be577846c08dfe994da60965f983acb97 --- .../src/android/net/cts/DnsResolverTest.java | 108 +++++++++++++++++- 1 file changed, 106 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/DnsResolverTest.java b/tests/cts/net/src/android/net/cts/DnsResolverTest.java index 57a5dc7788..0ff6cd8bac 100644 --- a/tests/cts/net/src/android/net/cts/DnsResolverTest.java +++ b/tests/cts/net/src/android/net/cts/DnsResolverTest.java @@ -379,7 +379,7 @@ public class DnsResolverTest extends AndroidTestCase { final String msg = "Test cancel query " + dname; // Start a DNS query and the cancel it immediately. Use VerifyCancelCallback to expect // that the query is cancelled before it succeeds. If it is not cancelled before it - // succeeds, retry the until it is. + // succeeds, retry the test until it is. for (Network network : getTestableNetworks()) { boolean retry = false; int round = 0; @@ -425,7 +425,7 @@ public class DnsResolverTest extends AndroidTestCase { final String msg = "Test cancel raw Query " + byteArrayToHexString(blob); // Start a DNS query and the cancel it immediately. Use VerifyCancelCallback to expect // that the query is cancelled before it succeeds. If it is not cancelled before it - // succeeds, retry the until it is. + // succeeds, retry the test until it is. for (Network network : getTestableNetworks()) { boolean retry = false; int round = 0; @@ -469,4 +469,108 @@ public class DnsResolverTest extends AndroidTestCase { } } } + + /** + * A query callback for InetAddress that ensures that the query is + * cancelled and that onAnswer is never called. If the query succeeds + * before it is cancelled, needRetry will return true so the + * test can retry. + */ + class VerifyCancelInetAddressCallback extends DnsResolver.InetAddressAnswerCallback { + private static final int CANCEL_TIMEOUT = 3_000; + + private final CountDownLatch mLatch = new CountDownLatch(1); + private final String mMsg; + private final List mAnswers; + private final CancellationSignal mCancelSignal; + + VerifyCancelInetAddressCallback(@NonNull String msg, @Nullable CancellationSignal cancel) { + this.mMsg = msg; + this.mCancelSignal = cancel; + mAnswers = new ArrayList<>(); + } + + public boolean waitForAnswer() throws InterruptedException { + return mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS); + } + + public boolean needRetry() throws InterruptedException { + return mLatch.await(CANCEL_TIMEOUT, TimeUnit.MILLISECONDS); + } + + public boolean isAnswerEmpty() { + return mAnswers.isEmpty(); + } + + @Override + public void onAnswer(@NonNull List answerList) { + if (mCancelSignal != null && mCancelSignal.isCanceled()) { + fail(mMsg + " should not have returned any answers"); + } + mAnswers.clear(); + mAnswers.addAll(answerList); + mLatch.countDown(); + } + + @Override + public void onParseException(@NonNull ParseException e) { + fail(mMsg + e.getMessage()); + } + + @Override + public void onQueryException(@NonNull ErrnoException e) { + fail(mMsg + e.getMessage()); + } + } + + public void testQueryForInetAddress() { + final String dname = "www.google.com"; + final String msg = "Test query for InetAddress " + dname; + for (Network network : getTestableNetworks()) { + final VerifyCancelInetAddressCallback callback = + new VerifyCancelInetAddressCallback(msg, null); + mDns.query(network, dname, FLAG_NO_CACHE_LOOKUP, + mExecutor, null, callback); + try { + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + callback.waitForAnswer()); + assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty()); + } catch (InterruptedException e) { + fail(msg + " Waiting for DNS lookup was interrupted"); + } + } + } + + public void testQueryCancelForInetAddress() throws ErrnoException { + final String dname = "www.google.com"; + final String msg = "Test cancel query for InetAddress " + dname; + // Start a DNS query and the cancel it immediately. Use VerifyCancelCallback to expect + // that the query is cancelled before it succeeds. If it is not cancelled before it + // succeeds, retry the test until it is. + for (Network network : getTestableNetworks()) { + boolean retry = false; + int round = 0; + do { + if (++round > CANCEL_RETRY_TIMES) { + fail(msg + " cancel failed " + CANCEL_RETRY_TIMES + " times"); + } + final CountDownLatch latch = new CountDownLatch(1); + final CancellationSignal cancelSignal = new CancellationSignal(); + final VerifyCancelInetAddressCallback callback = + new VerifyCancelInetAddressCallback(msg, cancelSignal); + mDns.query(network, dname, FLAG_EMPTY, mExecutor, cancelSignal, callback); + mExecutor.execute(() -> { + cancelSignal.cancel(); + latch.countDown(); + }); + try { + retry = callback.needRetry(); + assertTrue(msg + " query was not cancelled", + latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); + } catch (InterruptedException e) { + fail(msg + "Waiting for DNS lookup was interrupted"); + } + } while (retry); + } + } } From 950e10572b4d999787bd46c6f3758a0e9f89f213 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Fri, 29 Mar 2019 22:05:29 +0900 Subject: [PATCH 0584/1109] Add test coverage for ICMP echo constants. Bug: 129251251 Test: atest android.net.ipv6.cts.PingTest com.android.cts.net.HostsideVpnTests Change-Id: Icca18e0870588ca250225ce79cf30dbd8c361e84 --- .../cts/net/hostside/PacketReflector.java | 19 +++++++++++++++---- .../src/android/net/ipv6/cts/PingTest.java | 4 ++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/PacketReflector.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/PacketReflector.java index a4a2956d3a..124c2c3862 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/PacketReflector.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/PacketReflector.java @@ -16,6 +16,11 @@ package com.android.cts.net.hostside; +import static android.system.OsConstants.ICMP6_ECHO_REPLY; +import static android.system.OsConstants.ICMP6_ECHO_REQUEST; +import static android.system.OsConstants.ICMP_ECHO; +import static android.system.OsConstants.ICMP_ECHOREPLY; + import android.system.ErrnoException; import android.system.Os; import android.util.Log; @@ -47,8 +52,6 @@ public class PacketReflector extends Thread { private static final byte ICMP_ECHO = 8; private static final byte ICMP_ECHOREPLY = 0; - private static final byte ICMPV6_ECHO_REQUEST = (byte) 128; - private static final byte ICMPV6_ECHO_REPLY = (byte) 129; private static String TAG = "PacketReflector"; @@ -125,7 +128,7 @@ public class PacketReflector extends Thread { byte type = buf[hdrLen]; if (!(version == 4 && type == ICMP_ECHO) && - !(version == 6 && type == ICMPV6_ECHO_REQUEST)) { + !(version == 6 && type == (byte) ICMP6_ECHO_REQUEST)) { return; } @@ -145,10 +148,18 @@ public class PacketReflector extends Thread { return; } + byte replyType = buf[hdrLen]; + if ((type == ICMP_ECHO && replyType != ICMP_ECHOREPLY) + || (type == (byte) ICMP6_ECHO_REQUEST && replyType != (byte) ICMP6_ECHO_REPLY)) { + Log.i(TAG, "Received unexpected ICMP reply: original " + type + + ", reply " + replyType); + return; + } + // Compare the response we got with the original packet. // The only thing that should have changed are addresses, type and checksum. // Overwrite them with the received bytes and see if the packet is otherwise identical. - request[hdrLen] = buf[hdrLen]; // Type. + request[hdrLen] = buf[hdrLen]; // Type request[hdrLen + 2] = buf[hdrLen + 2]; // Checksum byte 1. request[hdrLen + 3] = buf[hdrLen + 3]; // Checksum byte 2. diff --git a/tests/cts/net/src/android/net/ipv6/cts/PingTest.java b/tests/cts/net/src/android/net/ipv6/cts/PingTest.java index c23ad30f05..146fd83978 100644 --- a/tests/cts/net/src/android/net/ipv6/cts/PingTest.java +++ b/tests/cts/net/src/android/net/ipv6/cts/PingTest.java @@ -61,7 +61,7 @@ public class PingTest extends AndroidTestCase { /** The beginning of an ICMPv6 echo request: type, code, and uninitialized checksum. */ private static final byte[] PING_HEADER = new byte[] { - (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00 + (byte) ICMP6_ECHO_REQUEST, (byte) 0x00, (byte) 0x00, (byte) 0x00 }; /** @@ -135,7 +135,7 @@ public class PingTest extends AndroidTestCase { byte[] response = new byte[bytesRead]; responseBuffer.flip(); responseBuffer.get(response, 0, bytesRead); - assertEquals((byte) 0x81, response[0]); + assertEquals((byte) ICMP6_ECHO_REPLY, response[0]); // Find out what ICMP ID was used in the packet that was sent. int id = ((InetSocketAddress) Os.getsockname(s)).getPort(); From 478f45e36db572d9c8d74255f80231911ee9940b Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Fri, 29 Mar 2019 10:34:39 -0700 Subject: [PATCH 0585/1109] WifiManagerTest: Test for new privileged permission Add a new test to ensure that the NETWORK_CARRIER_PROVISIONING is only granted to one app. Bug: 129401919 Test: atest WifiManagerTest Change-Id: Id2e722d63b02d9cee718dd3af49e9ef113bd5ffb --- .../android/net/wifi/cts/WifiManagerTest.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 93795b2bf0..1d666827fa 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -881,6 +881,30 @@ public class WifiManagerTest extends AndroidTestCase { } } + /** + * Verify that the {@link android.Manifest.permission#NETWORK_CARRIER_PROVISIONING} permission + * is held by at most one application. + */ + public void testNetworkCarrierProvisioningPermission() { + final PackageManager pm = getContext().getPackageManager(); + + final List holding = pm.getPackagesHoldingPermissions(new String[] { + android.Manifest.permission.NETWORK_CARRIER_PROVISIONING + }, PackageManager.MATCH_UNINSTALLED_PACKAGES); + + List uniquePackageNames = holding + .stream() + .map(pi -> pi.packageName) + .distinct() + .collect(Collectors.toList()); + + if (uniquePackageNames.size() > 1) { + fail("The NETWORK_CARRIER_PROVISIONING permission must not be held by more than one " + + "application, but is held by " + uniquePackageNames.size() + " applications: " + + String.join(", ", uniquePackageNames)); + } + } + /** * Verify that the {@link android.Manifest.permission#WIFI_UPDATE_USABILITY_STATS_SCORE} * permission is held by at most one application. From c1419d913d247c63f1c1e7ba20338d2b9217f8dd Mon Sep 17 00:00:00 2001 From: junyulai Date: Wed, 27 Mar 2019 14:57:21 +0800 Subject: [PATCH 0586/1109] Fix tests in TrafficStatsTest that are affected by adb over network If the adb TCP port is opened, this test may be run by adb over network. Huge amount of data traffic might go through the network and accounted into total packets stats. The upper bound check would be meaningless. Bug: 126320702 Test: atest android.net.cts.TrafficStatsTest 10 trials for both cases Change-Id: Iaee455826dc01741c6a3a9f5f8096361c69a1e7c --- .../src/android/net/cts/TrafficStatsTest.java | 42 +++++++++++++------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java index af096da089..503ba51727 100755 --- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java +++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java @@ -16,15 +16,14 @@ package android.net.cts; +import android.content.pm.PackageManager; import android.net.NetworkStats; import android.net.TrafficStats; import android.os.Process; +import android.os.SystemProperties; import android.test.AndroidTestCase; import android.util.Log; -import java.io.BufferedReader; -import java.io.FileNotFoundException; -import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -237,19 +236,37 @@ public class TrafficStatsTest extends AndroidTestCase { uidRxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets + deltaRxOtherPackets, 0)); // Localhost traffic *does* count against total stats. - // Fudge by 132 packets of 1500 bytes not related to the test. + // Check the total stats increased after test data transfer over localhost has been made. assertTrue("ttxp: " + totalTxPacketsBefore + " -> " + totalTxPacketsAfter, - totalTxPacketsAfter >= totalTxPacketsBefore + uidTxDeltaPackets && - totalTxPacketsAfter <= totalTxPacketsBefore + uidTxDeltaPackets + 132); + totalTxPacketsAfter >= totalTxPacketsBefore + uidTxDeltaPackets); assertTrue("trxp: " + totalRxPacketsBefore + " -> " + totalRxPacketsAfter, - totalRxPacketsAfter >= totalRxPacketsBefore + uidRxDeltaPackets && - totalRxPacketsAfter <= totalRxPacketsBefore + uidRxDeltaPackets + 132); + totalRxPacketsAfter >= totalRxPacketsBefore + uidRxDeltaPackets); assertTrue("ttxb: " + totalTxBytesBefore + " -> " + totalTxBytesAfter, - totalTxBytesAfter >= totalTxBytesBefore + uidTxDeltaBytes && - totalTxBytesAfter <= totalTxBytesBefore + uidTxDeltaBytes + 132 * 1500); + totalTxBytesAfter >= totalTxBytesBefore + uidTxDeltaBytes); assertTrue("trxb: " + totalRxBytesBefore + " -> " + totalRxBytesAfter, - totalRxBytesAfter >= totalRxBytesBefore + uidRxDeltaBytes && - totalRxBytesAfter <= totalRxBytesBefore + uidRxDeltaBytes + 132 * 1500); + totalRxBytesAfter >= totalRxBytesBefore + uidRxDeltaBytes); + + // If the adb TCP port is opened, this test may be run by adb over network. + // Huge amount of data traffic might go through the network and accounted into total packets + // stats. The upper bound check would be meaningless. + // TODO: Consider precisely calculate the traffic accounted due to adb over network and + // subtract it when checking upper bound instead of skip checking. + final PackageManager pm = mContext.getPackageManager(); + if (SystemProperties.getInt("persist.adb.tcp.port", -1) > -1 + || SystemProperties.getInt("service.adb.tcp.port", -1) > -1 + || !pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY)) { + Log.i(LOG_TAG, "adb is running over the network, skip the upper bound check"); + } else { + // Fudge by 132 packets of 1500 bytes not related to the test. + assertTrue("ttxp: " + totalTxPacketsBefore + " -> " + totalTxPacketsAfter, + totalTxPacketsAfter <= totalTxPacketsBefore + uidTxDeltaPackets + 132); + assertTrue("trxp: " + totalRxPacketsBefore + " -> " + totalRxPacketsAfter, + totalRxPacketsAfter <= totalRxPacketsBefore + uidRxDeltaPackets + 132); + assertTrue("ttxb: " + totalTxBytesBefore + " -> " + totalTxBytesAfter, + totalTxBytesAfter <= totalTxBytesBefore + uidTxDeltaBytes + 132 * 1500); + assertTrue("trxb: " + totalRxBytesBefore + " -> " + totalRxBytesAfter, + totalRxBytesAfter <= totalRxBytesBefore + uidRxDeltaBytes + 132 * 1500); + } // Localhost traffic should *not* count against mobile stats, // There might be some other traffic, but nowhere near 1MB. @@ -265,6 +282,5 @@ public class TrafficStatsTest extends AndroidTestCase { assertTrue("mrxb: " + mobileRxBytesBefore + " -> " + mobileRxBytesAfter, mobileRxBytesAfter >= mobileRxBytesBefore && mobileRxBytesAfter <= mobileRxBytesBefore + 200000); - } } From 5dc16818233197e691ef7f64d767e6a5ac0fdbd0 Mon Sep 17 00:00:00 2001 From: markchien Date: Wed, 23 Jan 2019 16:18:10 +0800 Subject: [PATCH 0587/1109] [KA09] add cts test for tcp keepalive offload Add a test case to make sure tcp keepalive offload starts correctly. Bug: 114151147 Test: atest ConnectivityManagerTest#testCreateTcpKeepalive Change-Id: Iaf1c2fab755f3df8e866b4988f64c25906e1737a --- .../net/cts/ConnectivityManagerTest.java | 242 +++++++++++++++++- 1 file changed, 241 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 1b7d29001b..4180ea4396 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -23,12 +23,17 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; +import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT; import static android.provider.Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE; +import static android.system.OsConstants.AF_INET; +import static android.system.OsConstants.AF_INET6; +import static android.system.OsConstants.AF_UNSPEC; import static com.android.compatibility.common.util.SystemUtil.runShellCommand; import android.app.Instrumentation; import android.app.PendingIntent; +import android.app.UiAutomation; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; @@ -46,8 +51,10 @@ import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; import android.net.NetworkRequest; +import android.net.SocketKeepalive; import android.net.wifi.WifiManager; import android.os.Looper; +import android.os.MessageQueue; import android.os.SystemClock; import android.os.SystemProperties; import android.provider.Settings; @@ -64,11 +71,13 @@ import com.android.internal.telephony.PhoneConstants; import libcore.io.Streams; +import java.io.FileDescriptor; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; +import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.InetSocketAddress; @@ -79,6 +88,7 @@ import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.HashMap; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executor; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; @@ -96,7 +106,11 @@ public class ConnectivityManagerTest extends AndroidTestCase { private static final int HOST_ADDRESS = 0x7f000001;// represent ip 127.0.0.1 private static final String TEST_HOST = "connectivitycheck.gstatic.com"; private static final int SOCKET_TIMEOUT_MS = 2000; + private static final int CONNECT_TIMEOUT_MS = 2000; + private static final int KEEPALIVE_CALLBACK_TIMEOUT_MS = 2000; + private static final int KEEPALIVE_SOCKET_TIMEOUT_MS = 5000; private static final int SEND_BROADCAST_TIMEOUT = 30000; + private static final int MIN_KEEPALIVE_INTERVAL = 10; private static final int NETWORK_CHANGE_METEREDNESS_TIMEOUT = 5000; private static final int NUM_TRIES_MULTIPATH_PREF_CHECK = 20; private static final long INTERVAL_MULTIPATH_PREF_CHECK_MS = 500; @@ -126,7 +140,8 @@ public class ConnectivityManagerTest extends AndroidTestCase { new HashMap(); boolean mWifiConnectAttempted; private TestNetworkCallback mCellNetworkCallback; - + private UiAutomation mUiAutomation; + private boolean mShellPermissionIdentityAdopted; @Override protected void setUp() throws Exception { @@ -153,6 +168,8 @@ public class ConnectivityManagerTest extends AndroidTestCase { mNetworks.put(n.type, n); } catch (Exception e) {} } + mUiAutomation = mInstrumentation.getUiAutomation(); + mShellPermissionIdentityAdopted = false; } @Override @@ -164,6 +181,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { if (cellConnectAttempted()) { disconnectFromCell(); } + dropShellPermissionIdentity(); super.tearDown(); } @@ -1037,4 +1055,226 @@ public class ConnectivityManagerTest extends AndroidTestCase { setWifiMeteredStatus(ssid, oldMeteredSetting); } } + + // TODO: move the following socket keep alive test to dedicated test class. + /** + * Callback used in tcp keepalive offload that allows caller to wait callback fires. + */ + private static class TestSocketKeepaliveCallback extends SocketKeepalive.Callback { + public enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR }; + + public static class CallbackValue { + public final CallbackType callbackType; + public final int error; + + private CallbackValue(final CallbackType type, final int error) { + this.callbackType = type; + this.error = error; + } + + public static class OnStartedCallback extends CallbackValue { + OnStartedCallback() { super(CallbackType.ON_STARTED, 0); } + } + + public static class OnStoppedCallback extends CallbackValue { + OnStoppedCallback() { super(CallbackType.ON_STOPPED, 0); } + } + + public static class OnErrorCallback extends CallbackValue { + OnErrorCallback(final int error) { super(CallbackType.ON_ERROR, error); } + } + + @Override + public boolean equals(Object o) { + return o.getClass() == this.getClass() + && this.callbackType == ((CallbackValue) o).callbackType + && this.error == ((CallbackValue) o).error; + } + + @Override + public String toString() { + return String.format("%s(%s, %d)", getClass().getSimpleName(), callbackType, error); + } + } + + private final LinkedBlockingQueue mCallbacks = new LinkedBlockingQueue<>(); + + @Override + public void onStarted() { + mCallbacks.add(new CallbackValue.OnStartedCallback()); + } + + @Override + public void onStopped() { + mCallbacks.add(new CallbackValue.OnStoppedCallback()); + } + + @Override + public void onError(final int error) { + mCallbacks.add(new CallbackValue.OnErrorCallback(error)); + } + + public CallbackValue pollCallback() { + try { + return mCallbacks.poll(KEEPALIVE_CALLBACK_TIMEOUT_MS, + TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + fail("Callback not seen after " + KEEPALIVE_CALLBACK_TIMEOUT_MS + " ms"); + } + return null; + } + private void expectCallback(CallbackValue expectedCallback) { + final CallbackValue actualCallback = pollCallback(); + assertEquals(expectedCallback, actualCallback); + } + + public void expectStarted() { + expectCallback(new CallbackValue.OnStartedCallback()); + } + + public void expectStopped() { + expectCallback(new CallbackValue.OnStoppedCallback()); + } + + public void expectError(int error) { + expectCallback(new CallbackValue.OnErrorCallback(error)); + } + } + + private InetAddress getAddrByName(final String hostname, final int family) throws Exception { + final InetAddress[] allAddrs = InetAddress.getAllByName(hostname); + for (InetAddress addr : allAddrs) { + if (family == AF_INET && addr instanceof Inet4Address) return addr; + + if (family == AF_INET6 && addr instanceof Inet6Address) return addr; + + if (family == AF_UNSPEC) return addr; + } + return null; + } + + private Socket getConnectedSocket(final Network network, final String host, final int port, + final int socketTimeOut, final int family) throws Exception { + final Socket s = network.getSocketFactory().createSocket(); + try { + final InetAddress addr = getAddrByName(host, family); + if (addr == null) fail("Fail to get destination address for " + family); + + final InetSocketAddress sockAddr = new InetSocketAddress(addr, port); + s.setSoTimeout(socketTimeOut); + s.connect(sockAddr, CONNECT_TIMEOUT_MS); + } catch (Exception e) { + s.close(); + throw e; + } + return s; + } + + private boolean isKeepaliveSupported() throws Exception { + final Network network = ensureWifiConnected(); + final Executor executor = mContext.getMainExecutor(); + final TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(); + try (Socket s = getConnectedSocket(network, TEST_HOST, + HTTP_PORT, KEEPALIVE_SOCKET_TIMEOUT_MS, AF_INET); + SocketKeepalive sk = mCm.createSocketKeepalive(network, s, executor, callback)) { + sk.start(MIN_KEEPALIVE_INTERVAL); + final TestSocketKeepaliveCallback.CallbackValue result = callback.pollCallback(); + switch (result.callbackType) { + case ON_STARTED: + sk.stop(); + callback.expectStopped(); + return true; + case ON_ERROR: + if (result.error == SocketKeepalive.ERROR_UNSUPPORTED) return false; + // else fallthrough. + default: + fail("Got unexpected callback: " + result); + return false; + } + } + } + + private void adoptShellPermissionIdentity() { + mUiAutomation.adoptShellPermissionIdentity(); + mShellPermissionIdentityAdopted = true; + } + + private void dropShellPermissionIdentity() { + if (mShellPermissionIdentityAdopted) { + mUiAutomation.dropShellPermissionIdentity(); + mShellPermissionIdentityAdopted = false; + } + } + + public void testCreateTcpKeepalive() throws Exception { + adoptShellPermissionIdentity(); + + if (!isKeepaliveSupported()) return; + + final Network network = ensureWifiConnected(); + final byte[] requestBytes = HTTP_REQUEST.getBytes("UTF-8"); + // So far only ipv4 tcp keepalive offload is supported. + // TODO: add test case for ipv6 tcp keepalive offload when it is supported. + try (Socket s = getConnectedSocket(network, TEST_HOST, HTTP_PORT, + KEEPALIVE_SOCKET_TIMEOUT_MS, AF_INET)) { + + // Should able to start keep alive offload when socket is idle. + final Executor executor = mContext.getMainExecutor(); + final TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(); + try (SocketKeepalive sk = mCm.createSocketKeepalive(network, s, executor, callback)) { + sk.start(MIN_KEEPALIVE_INTERVAL); + callback.expectStarted(); + + // App should not able to write during keepalive offload. + final OutputStream out = s.getOutputStream(); + try { + out.write(requestBytes); + fail("Should not able to write"); + } catch (IOException e) { } + // App should not able to read during keepalive offload. + final InputStream in = s.getInputStream(); + byte[] responseBytes = new byte[4096]; + try { + in.read(responseBytes); + fail("Should not able to read"); + } catch (IOException e) { } + + // Stop. + sk.stop(); + callback.expectStopped(); + } + + // Ensure socket is still connected. + assertTrue(s.isConnected()); + assertFalse(s.isClosed()); + + // Let socket be not idle. + try { + final OutputStream out = s.getOutputStream(); + out.write(requestBytes); + } catch (IOException e) { + fail("Failed to write data " + e); + } + // Make sure response data arrives. + final MessageQueue fdHandlerQueue = Looper.getMainLooper().getQueue(); + final FileDescriptor fd = s.getFileDescriptor$(); + final CountDownLatch mOnReceiveLatch = new CountDownLatch(1); + fdHandlerQueue.addOnFileDescriptorEventListener(fd, EVENT_INPUT, (readyFd, events) -> { + mOnReceiveLatch.countDown(); + return 0; // Unregister listener. + }); + if (!mOnReceiveLatch.await(2, TimeUnit.SECONDS)) { + fdHandlerQueue.removeOnFileDescriptorEventListener(fd); + fail("Timeout: no response data"); + } + + // Should get ERROR_SOCKET_NOT_IDLE because there is still data in the receive queue + // that has not been read. + try (SocketKeepalive sk = mCm.createSocketKeepalive(network, s, executor, callback)) { + sk.start(MIN_KEEPALIVE_INTERVAL); + callback.expectError(SocketKeepalive.ERROR_SOCKET_NOT_IDLE); + } + + } + } } From 16fc55e30de5922b26c2437d1b5d4831fcd00374 Mon Sep 17 00:00:00 2001 From: Remi NGUYEN VAN Date: Wed, 3 Apr 2019 18:06:33 +0900 Subject: [PATCH 0588/1109] Add FrameworksNetCommonTests to CTS The common tests include tests that must be both in CTS and unit tests. Bug: 129199908 Test: atest CtsNetTestCases, IpPrefixCommonTest is run and passes. Change-Id: Id16f40247cca9a6c5bba573006b84547727f1bab --- tests/cts/net/Android.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index 2084dbc357..04974702a6 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -39,6 +39,7 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := CtsNetTestCases LOCAL_STATIC_JAVA_LIBRARIES := \ + FrameworksNetCommonTests \ core-tests-support \ compatibility-device-util-axt \ ctstestrunner-axt \ From ef4ac8c021b8cfe108a5b80d8c2cb1806b6cc51f Mon Sep 17 00:00:00 2001 From: Remi NGUYEN VAN Date: Thu, 4 Apr 2019 09:39:20 -0700 Subject: [PATCH 0589/1109] Add FrameworksNetCommonTests to CTS The common tests include tests that must be both in CTS and unit tests. Bug: 129199908 Test: atest CtsNetTestCases, IpPrefixCommonTest is run and passes. Change-Id: I872fb80e8a0b21144f0b66b33645a320dcd5dcf2 (cherry picked from commit 855e7889d62839fe6449f97086656e860c4db177) --- tests/cts/net/Android.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk index 2084dbc357..04974702a6 100644 --- a/tests/cts/net/Android.mk +++ b/tests/cts/net/Android.mk @@ -39,6 +39,7 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := CtsNetTestCases LOCAL_STATIC_JAVA_LIBRARIES := \ + FrameworksNetCommonTests \ core-tests-support \ compatibility-device-util-axt \ ctstestrunner-axt \ From d11be5bbeb31330a5a304522ea8f96276e895371 Mon Sep 17 00:00:00 2001 From: saurav subedi Date: Fri, 7 Sep 2018 10:57:01 -0700 Subject: [PATCH 0590/1109] DO NOT MERGE:CDD Annotation for 7.4.7/C-2-1 Devices that don't provide data saver mode must return RESTRICT_BACKGROUND_STATUS_DISABLED for the ConnectivityManager#getRestrictBackgroundStatus() Bug:130032710 Test: make cts Change-Id: I81b52c9d26afcf51a7e416d20589c9c7cfb878f6 --- .../src/com/android/cts/net/hostside/DataSaverModeTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index 599a31ce1c..c3962fbbc3 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -22,6 +22,9 @@ import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELI import android.util.Log; +import com.android.compatibility.common.util.CddTest; + +@CddTest(requirement="7.4.7/C-1-1,H-1-1,C-2-1") public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase { private static final String[] REQUIRED_WHITELISTED_PACKAGES = { From 3a984ca812e0955ce69352ed1dff02eb24e370b1 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Thu, 28 Mar 2019 17:38:32 +0900 Subject: [PATCH 0591/1109] Fix expected reverse lookup of Google DNS IP addresses DnsTest.testDnsWorks expects that reverse lookup for the Google public DNS servers will return something with google.com in the name. This no longer works because the reverse DNS entries have changed to dns.google. Bug: 129452237 Test: atest android.net.cts.DnsTest.testDnsWorks Change-Id: Iee8bfe418bf6003e5c78df77d75f6f9745249267 Merged-In: Iee8bfe418bf6003e5c78df77d75f6f9745249267 (cherry picked from commit 3852fd92f583e4f05db4d086b168df9f070eae4c) --- tests/cts/net/jni/NativeDnsJni.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/cts/net/jni/NativeDnsJni.c b/tests/cts/net/jni/NativeDnsJni.c index 4eb3c7aebc..1df9169cdc 100644 --- a/tests/cts/net/jni/NativeDnsJni.c +++ b/tests/cts/net/jni/NativeDnsJni.c @@ -120,8 +120,8 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas gai_strerror(res)); return JNI_FALSE; } - if (strstr(buf, "google.com") == NULL) { - ALOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com: %s", + if (strstr(buf, "google.com") == NULL && strstr(buf, "dns.google") == NULL) { + ALOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com or dns.google: %s", GoogleDNSIpV4Address, buf); return JNI_FALSE; } @@ -133,8 +133,9 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas res, gai_strerror(res)); return JNI_FALSE; } - if (strstr(buf, "google.com") == NULL) { - ALOGD("getnameinfo(%s) didn't return google.com: %s", GoogleDNSIpV6Address2, buf); + if (strstr(buf, "google.com") == NULL && strstr(buf, "dns.google") == NULL) { + ALOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com or dns.google: %s", + GoogleDNSIpV6Address2, buf); return JNI_FALSE; } From 5227dbe606d73326111c4e2c391bf3097647f3ee Mon Sep 17 00:00:00 2001 From: Adam Vartanian Date: Tue, 9 Apr 2019 15:46:20 +0100 Subject: [PATCH 0592/1109] Add test for SslError.getCertificate() Bug: 129200144 Test: cts -m CtsNetTestCases -t android.net.http.cts Change-Id: I1b23746865a4bffc90847b30384defd2c7d49879 --- tests/cts/net/src/android/net/http/cts/SslErrorTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/cts/net/src/android/net/http/cts/SslErrorTest.java b/tests/cts/net/src/android/net/http/cts/SslErrorTest.java index 850a8b61e6..0058c90ac4 100644 --- a/tests/cts/net/src/android/net/http/cts/SslErrorTest.java +++ b/tests/cts/net/src/android/net/http/cts/SslErrorTest.java @@ -77,4 +77,9 @@ public class SslErrorTest extends TestCase { SslError error = new SslError(SslError.SSL_EXPIRED, mCertificate); assertEquals(error.getUrl(), ""); } + + public void testGetCertificate() { + SslError error = new SslError(SslError.SSL_EXPIRED, mCertificate); + assertEquals(mCertificate, error.getCertificate()); + } } From 4b1fab0dd0ea0e4f1bc42b8dc7426ef7b2ab148a Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Mon, 8 Apr 2019 19:54:05 +0800 Subject: [PATCH 0593/1109] DnsResolver cts changes to match API council requests Bug: 129261432 Test: atest DnsResolverTest Change-Id: I803f10218a01614ba7fb26597971853e602273c6 --- .../src/android/net/cts/DnsResolverTest.java | 384 +++++++++--------- 1 file changed, 181 insertions(+), 203 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/DnsResolverTest.java b/tests/cts/net/src/android/net/cts/DnsResolverTest.java index 0ff6cd8bac..40d64cf49b 100644 --- a/tests/cts/net/src/android/net/cts/DnsResolverTest.java +++ b/tests/cts/net/src/android/net/cts/DnsResolverTest.java @@ -39,13 +39,14 @@ import android.system.ErrnoException; import android.test.AndroidTestCase; import android.util.Log; +import java.net.Inet4Address; +import java.net.Inet6Address; import java.net.InetAddress; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; public class DnsResolverTest extends AndroidTestCase { private static final String TAG = "DnsResolverTest"; @@ -53,7 +54,9 @@ public class DnsResolverTest extends AndroidTestCase { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; static final int TIMEOUT_MS = 12_000; + static final int CANCEL_TIMEOUT_MS = 3_000; static final int CANCEL_RETRY_TIMES = 5; + static final int NXDOMAIN = 3; private ConnectivityManager mCM; private Executor mExecutor; @@ -94,73 +97,26 @@ public class DnsResolverTest extends AndroidTestCase { return testableNetworks.toArray(new Network[0]); } - public void testQueryWithInetAddressCallback() { - final String dname = "www.google.com"; - final String msg = "Query with InetAddressAnswerCallback " + dname; - for (Network network : getTestableNetworks()) { - final CountDownLatch latch = new CountDownLatch(1); - final AtomicReference> answers = new AtomicReference<>(); - final DnsResolver.InetAddressAnswerCallback callback = - new DnsResolver.InetAddressAnswerCallback() { - @Override - public void onAnswer(@NonNull List answerList) { - answers.set(answerList); - for (InetAddress addr : answerList) { - Log.d(TAG, "Reported addr: " + addr.toString()); - } - latch.countDown(); - } - - @Override - public void onParseException(@NonNull ParseException e) { - fail(msg + e.getMessage()); - } - - @Override - public void onQueryException(@NonNull ErrnoException e) { - fail(msg + e.getMessage()); - } - }; - mDns.query(network, dname, CLASS_IN, TYPE_A, FLAG_NO_CACHE_LOOKUP, - mExecutor, null, callback); - try { - assertTrue(msg + " but no valid answer after " + TIMEOUT_MS + "ms.", - latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - assertGreaterThan(msg + " returned 0 result", answers.get().size(), 0); - } catch (InterruptedException e) { - fail(msg + " Waiting for DNS lookup was interrupted"); - } - } - } - static private void assertGreaterThan(String msg, int first, int second) { assertTrue(msg + " Excepted " + first + " to be greater than " + second, first > second); } - static private void assertValidAnswer(String msg, @NonNull DnsAnswer ans) { - // Check rcode field.(0, No error condition). - assertTrue(msg + " Response error, rcode: " + ans.getRcode(), ans.getRcode() == 0); - // Check answer counts. - assertGreaterThan(msg + " No answer found", ans.getANCount(), 0); - // Check question counts. - assertGreaterThan(msg + " No question found", ans.getQDCount(), 0); - } + private static class DnsParseException extends Exception { + public DnsParseException(String msg) { + super(msg); + } - static private void assertValidEmptyAnswer(String msg, @NonNull DnsAnswer ans) { - // Check rcode field.(0, No error condition). - assertTrue(msg + " Response error, rcode: " + ans.getRcode(), ans.getRcode() == 0); - // Check answer counts. Expect 0 answer. - assertTrue(msg + " Not an empty answer", ans.getANCount() == 0); - // Check question counts. - assertGreaterThan(msg + " No question found", ans.getQDCount(), 0); + public DnsParseException(String msg, Throwable cause) { + super(msg, cause); + } } private static class DnsAnswer extends DnsPacket { - DnsAnswer(@NonNull byte[] data) throws ParseException { + DnsAnswer(@NonNull byte[] data) throws DnsParseException { super(data); // Check QR field.(query (0), or a response (1)). if ((mHeader.flags & (1 << 15)) == 0) { - throw new ParseException("Not an answer packet"); + throw new DnsParseException("Not an answer packet"); } } @@ -175,63 +131,116 @@ public class DnsResolverTest extends AndroidTestCase { } } - class RawAnswerCallbackImpl extends DnsResolver.RawAnswerCallback { + /** + * A query callback that ensures that the query is cancelled and that onAnswer is never + * called. If the query succeeds before it is cancelled, needRetry will return true so the + * test can retry. + */ + class VerifyCancelCallback implements DnsResolver.Callback { private final CountDownLatch mLatch = new CountDownLatch(1); private final String mMsg; - private final int mTimeout; + private final CancellationSignal mCancelSignal; + private int mRcode; + private DnsAnswer mDnsAnswer; - RawAnswerCallbackImpl(@NonNull String msg, int timeout) { + VerifyCancelCallback(@NonNull String msg, @Nullable CancellationSignal cancel) { this.mMsg = msg; - this.mTimeout = timeout; + this.mCancelSignal = cancel; + this.mDnsAnswer = null; } - RawAnswerCallbackImpl(@NonNull String msg) { - this(msg, TIMEOUT_MS); + VerifyCancelCallback(@NonNull String msg) { + this(msg, null); + } + + public boolean waitForAnswer(int timeout) throws InterruptedException { + return mLatch.await(timeout, TimeUnit.MILLISECONDS); } public boolean waitForAnswer() throws InterruptedException { - return mLatch.await(mTimeout, TimeUnit.MILLISECONDS); + return waitForAnswer(TIMEOUT_MS); + } + + public boolean needRetry() throws InterruptedException { + return mLatch.await(CANCEL_TIMEOUT_MS, TimeUnit.MILLISECONDS); } @Override - public void onAnswer(@NonNull byte[] answer) { + public void onAnswer(@NonNull byte[] answer, int rcode) { + if (mCancelSignal != null && mCancelSignal.isCanceled()) { + fail(mMsg + " should not have returned any answers"); + } + + mRcode = rcode; try { - assertValidAnswer(mMsg, new DnsAnswer(answer)); - Log.d(TAG, "Reported blob: " + byteArrayToHexString(answer)); - mLatch.countDown(); - } catch (ParseException e) { + mDnsAnswer = new DnsAnswer(answer); + } catch (DnsParseException e) { fail(mMsg + e.getMessage()); } + Log.d(TAG, "Reported blob: " + byteArrayToHexString(answer)); + mLatch.countDown(); } @Override - public void onParseException(@NonNull ParseException e) { - fail(mMsg + e.getMessage()); + public void onError(@NonNull DnsResolver.DnsException error) { + fail(mMsg + error.getMessage()); } - @Override - public void onQueryException(@NonNull ErrnoException e) { - fail(mMsg + e.getMessage()); + private void assertValidAnswer() { + assertTrue(mMsg + "No valid answer", mDnsAnswer != null); + assertTrue(mMsg + " Unexpected error: reported rcode" + mRcode + + " blob's rcode " + mDnsAnswer.getRcode(), mRcode == mDnsAnswer.getRcode()); + } + + public void assertHasAnswer() { + assertValidAnswer(); + // Check rcode field.(0, No error condition). + assertTrue(mMsg + " Response error, rcode: " + mRcode, mRcode == 0); + // Check answer counts. + assertGreaterThan(mMsg + " No answer found", mDnsAnswer.getANCount(), 0); + // Check question counts. + assertGreaterThan(mMsg + " No question found", mDnsAnswer.getQDCount(), 0); + } + + public void assertNXDomain() { + assertValidAnswer(); + // Check rcode field.(3, NXDomain). + assertTrue(mMsg + " Unexpected rcode: " + mRcode, mRcode == NXDOMAIN); + // Check answer counts. Expect 0 answer. + assertTrue(mMsg + " Not an empty answer", mDnsAnswer.getANCount() == 0); + // Check question counts. + assertGreaterThan(mMsg + " No question found", mDnsAnswer.getQDCount(), 0); + } + + public void assertEmptyAnswer() { + assertValidAnswer(); + // Check rcode field.(0, No error condition). + assertTrue(mMsg + " Response error, rcode: " + mRcode, mRcode == 0); + // Check answer counts. Expect 0 answer. + assertTrue(mMsg + " Not an empty answer", mDnsAnswer.getANCount() == 0); + // Check question counts. + assertGreaterThan(mMsg + " No question found", mDnsAnswer.getQDCount(), 0); } } - public void testQueryWithRawAnswerCallback() { + public void testRawQuery() { final String dname = "www.google.com"; - final String msg = "Query with RawAnswerCallback " + dname; + final String msg = "RawQuery " + dname; for (Network network : getTestableNetworks()) { - final RawAnswerCallbackImpl callback = new RawAnswerCallbackImpl(msg); - mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, + final VerifyCancelCallback callback = new VerifyCancelCallback(msg); + mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); try { assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", callback.waitForAnswer()); + callback.assertHasAnswer(); } catch (InterruptedException e) { fail(msg + " Waiting for DNS lookup was interrupted"); } } } - public void testQueryBlobWithRawAnswerCallback() { + public void testRawQueryBlob() { final byte[] blob = new byte[]{ /* Header */ 0x55, 0x66, /* Transaction ID */ @@ -246,137 +255,58 @@ public class DnsResolverTest extends AndroidTestCase { 0x00, 0x01, /* Type */ 0x00, 0x01 /* Class */ }; - final String msg = "Query with RawAnswerCallback " + byteArrayToHexString(blob); + final String msg = "RawQuery blob " + byteArrayToHexString(blob); for (Network network : getTestableNetworks()) { - final RawAnswerCallbackImpl callback = new RawAnswerCallbackImpl(msg); - mDns.query(network, blob, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); + final VerifyCancelCallback callback = new VerifyCancelCallback(msg); + mDns.rawQuery(network, blob, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); try { assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", callback.waitForAnswer()); + callback.assertHasAnswer(); } catch (InterruptedException e) { fail(msg + " Waiting for DNS lookup was interrupted"); } } } - public void testQueryRoot() { + public void testRawQueryRoot() { final String dname = ""; - final String msg = "Query with RawAnswerCallback empty dname(ROOT) "; + final String msg = "RawQuery empty dname(ROOT) "; for (Network network : getTestableNetworks()) { - final CountDownLatch latch = new CountDownLatch(1); - final DnsResolver.RawAnswerCallback callback = new DnsResolver.RawAnswerCallback() { - @Override - public void onAnswer(@NonNull byte[] answer) { - try { - // Except no answer record because of querying with empty dname(ROOT) - assertValidEmptyAnswer(msg, new DnsAnswer(answer)); - latch.countDown(); - } catch (ParseException e) { - fail(msg + e.getMessage()); - } - } - - @Override - public void onParseException(@NonNull ParseException e) { - fail(msg + e.getMessage()); - } - - @Override - public void onQueryException(@NonNull ErrnoException e) { - fail(msg + e.getMessage()); - } - }; - mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, + final VerifyCancelCallback callback = new VerifyCancelCallback(msg); + mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); try { - assertTrue(msg + "but no answer after " + TIMEOUT_MS + "ms.", - latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + callback.waitForAnswer()); + // Except no answer record because of querying with empty dname(ROOT) + callback.assertEmptyAnswer(); } catch (InterruptedException e) { fail(msg + "Waiting for DNS lookup was interrupted"); } } } - public void testQueryNXDomain() { + public void testRawQueryNXDomain() { final String dname = "test1-nx.metric.gstatic.com"; - final String msg = "Query with InetAddressAnswerCallback " + dname; + final String msg = "RawQuery " + dname; for (Network network : getTestableNetworks()) { - final CountDownLatch latch = new CountDownLatch(1); - final DnsResolver.InetAddressAnswerCallback callback = - new DnsResolver.InetAddressAnswerCallback() { - @Override - public void onAnswer(@NonNull List answerList) { - if (answerList.size() == 0) { - latch.countDown(); - return; - } - fail(msg + " but get valid answers"); - } - - @Override - public void onParseException(@NonNull ParseException e) { - fail(msg + e.getMessage()); - } - - @Override - public void onQueryException(@NonNull ErrnoException e) { - fail(msg + e.getMessage()); - } - }; - mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, + final VerifyCancelCallback callback = new VerifyCancelCallback(msg); + mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); try { assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", - latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); + callback.waitForAnswer()); + callback.assertNXDomain(); } catch (InterruptedException e) { fail(msg + " Waiting for DNS lookup was interrupted"); } } } - /** - * A query callback that ensures that the query is cancelled and that onAnswer is never - * called. If the query succeeds before it is cancelled, needRetry will return true so the - * test can retry. - */ - class VerifyCancelCallback extends DnsResolver.RawAnswerCallback { - private static final int CANCEL_TIMEOUT = 3_000; - - private final CountDownLatch mLatch = new CountDownLatch(1); - private final String mMsg; - private final CancellationSignal mCancelSignal; - - VerifyCancelCallback(@NonNull String msg, @NonNull CancellationSignal cancelSignal) { - this.mMsg = msg; - this.mCancelSignal = cancelSignal; - } - - public boolean needRetry() throws InterruptedException { - return mLatch.await(CANCEL_TIMEOUT, TimeUnit.MILLISECONDS); - } - - @Override - public void onAnswer(@NonNull byte[] answer) { - if (mCancelSignal.isCanceled()) { - fail(mMsg + " should not have returned any answers"); - } - mLatch.countDown(); - } - - @Override - public void onParseException(@NonNull ParseException e) { - fail(mMsg + e.getMessage()); - } - - @Override - public void onQueryException(@NonNull ErrnoException e) { - fail(mMsg + e.getMessage()); - } - } - - public void testQueryCancel() throws ErrnoException { + public void testRawQueryCancel() throws ErrnoException { final String dname = "www.google.com"; - final String msg = "Test cancel query " + dname; + final String msg = "Test cancel RawQuery " + dname; // Start a DNS query and the cancel it immediately. Use VerifyCancelCallback to expect // that the query is cancelled before it succeeds. If it is not cancelled before it // succeeds, retry the test until it is. @@ -390,7 +320,7 @@ public class DnsResolverTest extends AndroidTestCase { final CountDownLatch latch = new CountDownLatch(1); final CancellationSignal cancelSignal = new CancellationSignal(); final VerifyCancelCallback callback = new VerifyCancelCallback(msg, cancelSignal); - mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_EMPTY, + mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_EMPTY, mExecutor, cancelSignal, callback); mExecutor.execute(() -> { cancelSignal.cancel(); @@ -399,7 +329,7 @@ public class DnsResolverTest extends AndroidTestCase { try { retry = callback.needRetry(); assertTrue(msg + " query was not cancelled", - latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); + latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); } catch (InterruptedException e) { fail(msg + "Waiting for DNS lookup was interrupted"); } @@ -407,7 +337,7 @@ public class DnsResolverTest extends AndroidTestCase { } } - public void testQueryBlobCancel() throws ErrnoException { + public void testRawQueryBlobCancel() throws ErrnoException { final byte[] blob = new byte[]{ /* Header */ 0x55, 0x66, /* Transaction ID */ @@ -422,7 +352,7 @@ public class DnsResolverTest extends AndroidTestCase { 0x00, 0x01, /* Type */ 0x00, 0x01 /* Class */ }; - final String msg = "Test cancel raw Query " + byteArrayToHexString(blob); + final String msg = "Test cancel RawQuery blob " + byteArrayToHexString(blob); // Start a DNS query and the cancel it immediately. Use VerifyCancelCallback to expect // that the query is cancelled before it succeeds. If it is not cancelled before it // succeeds, retry the test until it is. @@ -436,7 +366,7 @@ public class DnsResolverTest extends AndroidTestCase { final CountDownLatch latch = new CountDownLatch(1); final CancellationSignal cancelSignal = new CancellationSignal(); final VerifyCancelCallback callback = new VerifyCancelCallback(msg, cancelSignal); - mDns.query(network, blob, FLAG_EMPTY, mExecutor, cancelSignal, callback); + mDns.rawQuery(network, blob, FLAG_EMPTY, mExecutor, cancelSignal, callback); mExecutor.execute(() -> { cancelSignal.cancel(); latch.countDown(); @@ -444,7 +374,7 @@ public class DnsResolverTest extends AndroidTestCase { try { retry = callback.needRetry(); assertTrue(msg + " cancel is not done", - latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); + latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); } catch (InterruptedException e) { fail(msg + " Waiting for DNS lookup was interrupted"); } @@ -454,16 +384,16 @@ public class DnsResolverTest extends AndroidTestCase { public void testCancelBeforeQuery() throws ErrnoException { final String dname = "www.google.com"; - final String msg = "Test cancelled query " + dname; + final String msg = "Test cancelled RawQuery " + dname; for (Network network : getTestableNetworks()) { - final RawAnswerCallbackImpl callback = new RawAnswerCallbackImpl(msg, 3_000); + final VerifyCancelCallback callback = new VerifyCancelCallback(msg); final CancellationSignal cancelSignal = new CancellationSignal(); cancelSignal.cancel(); - mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_EMPTY, + mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_EMPTY, mExecutor, cancelSignal, callback); try { assertTrue(msg + " should not return any answers", - !callback.waitForAnswer()); + !callback.waitForAnswer(CANCEL_TIMEOUT_MS)); } catch (InterruptedException e) { fail(msg + " Waiting for DNS lookup was interrupted"); } @@ -476,9 +406,7 @@ public class DnsResolverTest extends AndroidTestCase { * before it is cancelled, needRetry will return true so the * test can retry. */ - class VerifyCancelInetAddressCallback extends DnsResolver.InetAddressAnswerCallback { - private static final int CANCEL_TIMEOUT = 3_000; - + class VerifyCancelInetAddressCallback implements DnsResolver.Callback> { private final CountDownLatch mLatch = new CountDownLatch(1); private final String mMsg; private final List mAnswers; @@ -495,31 +423,43 @@ public class DnsResolverTest extends AndroidTestCase { } public boolean needRetry() throws InterruptedException { - return mLatch.await(CANCEL_TIMEOUT, TimeUnit.MILLISECONDS); + return mLatch.await(CANCEL_TIMEOUT_MS, TimeUnit.MILLISECONDS); } public boolean isAnswerEmpty() { return mAnswers.isEmpty(); } + public boolean hasIpv6Answer() { + for (InetAddress answer : mAnswers) { + if (answer instanceof Inet6Address) return true; + } + return false; + } + + public boolean hasIpv4Answer() { + for (InetAddress answer : mAnswers) { + if (answer instanceof Inet4Address) return true; + } + return false; + } + @Override - public void onAnswer(@NonNull List answerList) { + public void onAnswer(@NonNull List answerList, int rcode) { if (mCancelSignal != null && mCancelSignal.isCanceled()) { fail(mMsg + " should not have returned any answers"); } + for (InetAddress addr : answerList) { + Log.d(TAG, "Reported addr: " + addr.toString()); + } mAnswers.clear(); mAnswers.addAll(answerList); mLatch.countDown(); } @Override - public void onParseException(@NonNull ParseException e) { - fail(mMsg + e.getMessage()); - } - - @Override - public void onQueryException(@NonNull ErrnoException e) { - fail(mMsg + e.getMessage()); + public void onError(@NonNull DnsResolver.DnsException error) { + fail(mMsg + error.getMessage()); } } @@ -544,8 +484,8 @@ public class DnsResolverTest extends AndroidTestCase { public void testQueryCancelForInetAddress() throws ErrnoException { final String dname = "www.google.com"; final String msg = "Test cancel query for InetAddress " + dname; - // Start a DNS query and the cancel it immediately. Use VerifyCancelCallback to expect - // that the query is cancelled before it succeeds. If it is not cancelled before it + // Start a DNS query and the cancel it immediately. Use VerifyCancelInetAddressCallback to + // expect that the query is cancelled before it succeeds. If it is not cancelled before it // succeeds, retry the test until it is. for (Network network : getTestableNetworks()) { boolean retry = false; @@ -566,11 +506,49 @@ public class DnsResolverTest extends AndroidTestCase { try { retry = callback.needRetry(); assertTrue(msg + " query was not cancelled", - latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); + latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); } catch (InterruptedException e) { fail(msg + "Waiting for DNS lookup was interrupted"); } } while (retry); } } + + public void testQueryForInetAddressIpv4() { + final String dname = "www.google.com"; + final String msg = "Test query for IPv4 InetAddress " + dname; + for (Network network : getTestableNetworks()) { + final VerifyCancelInetAddressCallback callback = + new VerifyCancelInetAddressCallback(msg, null); + mDns.query(network, dname, TYPE_A, FLAG_NO_CACHE_LOOKUP, + mExecutor, null, callback); + try { + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + callback.waitForAnswer()); + assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty()); + assertTrue(msg + " returned Ipv6 results", !callback.hasIpv6Answer()); + } catch (InterruptedException e) { + fail(msg + " Waiting for DNS lookup was interrupted"); + } + } + } + + public void testQueryForInetAddressIpv6() { + final String dname = "www.google.com"; + final String msg = "Test query for IPv6 InetAddress " + dname; + for (Network network : getTestableNetworks()) { + final VerifyCancelInetAddressCallback callback = + new VerifyCancelInetAddressCallback(msg, null); + mDns.query(network, dname, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, + mExecutor, null, callback); + try { + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + callback.waitForAnswer()); + assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty()); + assertTrue(msg + " returned Ipv4 results", !callback.hasIpv4Answer()); + } catch (InterruptedException e) { + fail(msg + " Waiting for DNS lookup was interrupted"); + } + } + } } From ad17ee9e9273a53e3bb141f750c09eb27e76372e Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Mon, 25 Mar 2019 21:12:51 +0900 Subject: [PATCH 0594/1109] Add instant and ABI XML tags for hostside networking tests. These are not multi-ABI because the behaviour does not depend on the ABI of the app. Some of the APIs are ultimately backed by JNI code in the system server, but that only depends on the system server's ABI, not the app's. Enable instant mode because these applications are subject to the same network restrictions as other apps. Fix: 123364589 Test: atest CtsHostsideNetworkTests Test: cts-tradefed run commandAndExit cts --enable-parameterized-modules --module-parameter instant_app -m CtsHostsideNetworkTests Change-Id: Ib3c4cd365ffe95889d51a236f035ea84516f0abd --- tests/cts/hostside/AndroidTest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/cts/hostside/AndroidTest.xml b/tests/cts/hostside/AndroidTest.xml index 0656cae3ca..c7cab7b0ba 100644 --- a/tests/cts/hostside/AndroidTest.xml +++ b/tests/cts/hostside/AndroidTest.xml @@ -16,6 +16,9 @@

    Only checks for known plaintext bytes to prevent triggering on ICMP/RA packets or the like + * + * @param plaintext the plaintext bytes to check for + * @param startIndex the index in the list to check for + */ + public boolean hasPlaintextPacket(byte[] plaintext, int startIndex) { + Predicate verifier = + (pkt) -> { + return Collections.indexOfSubList(Arrays.asList(pkt), Arrays.asList(plaintext)) + != -1; + }; + return getFirstMatchingPacket(verifier, startIndex) != null; + } + + public byte[] getEspPacket(int spi, boolean encap, int startIndex) { + return getFirstMatchingPacket( + (pkt) -> { + return isEsp(pkt, spi, encap); + }, + startIndex); + } + + public byte[] awaitEspPacketNoPlaintext( + int spi, byte[] plaintext, boolean useEncap, int expectedPacketSize) throws Exception { + long endTime = System.currentTimeMillis() + TIMEOUT; + int startIndex = 0; + + synchronized (mPackets) { + while (System.currentTimeMillis() < endTime) { + byte[] espPkt = getEspPacket(spi, useEncap, startIndex); + if (espPkt != null) { + // Validate packet size + assertEquals(expectedPacketSize, espPkt.length); + + // Always check plaintext from start + assertFalse(hasPlaintextPacket(plaintext, 0)); + return espPkt; // We've found the packet we're looking for. + } + + startIndex = mPackets.size(); + + // Try to prevent waiting too long. If waitTimeout <= 0, we've already hit timeout + long waitTimeout = endTime - System.currentTimeMillis(); + if (waitTimeout > 0) { + mPackets.wait(waitTimeout); + } + } + + fail("No such ESP packet found with SPI " + spi); + } + return null; + } + + private static boolean isSpiEqual(byte[] pkt, int espOffset, int spi) { + // Check SPI byte by byte. + return pkt[espOffset] == (byte) ((spi >>> 24) & 0xff) + && pkt[espOffset + 1] == (byte) ((spi >>> 16) & 0xff) + && pkt[espOffset + 2] == (byte) ((spi >>> 8) & 0xff) + && pkt[espOffset + 3] == (byte) (spi & 0xff); + } + + private static boolean isEsp(byte[] pkt, int spi, boolean encap) { + if (isIpv6(pkt)) { + // IPv6 UDP encap not supported by kernels; assume non-encap. + return pkt[IP6_PROTO_OFFSET] == IPPROTO_ESP + && isSpiEqual(pkt, IpSecBaseTest.IP6_HDRLEN, spi); + } else { + // Use default IPv4 header length (assuming no options) + if (encap) { + return pkt[IP4_PROTO_OFFSET] == IPPROTO_UDP + && isSpiEqual( + pkt, IpSecBaseTest.IP4_HDRLEN + IpSecBaseTest.UDP_HDRLEN, spi); + } else { + return pkt[IP4_PROTO_OFFSET] == IPPROTO_ESP + && isSpiEqual(pkt, IpSecBaseTest.IP4_HDRLEN, spi); + } + } + } + + private static boolean isIpv6(byte[] pkt) { + // First nibble shows IP version. 0x60 for IPv6 + return (pkt[0] & (byte) 0xF0) == (byte) 0x60; + } + + private static byte[] getReflectedPacket(byte[] pkt) { + byte[] reflected = Arrays.copyOf(pkt, pkt.length); + + if (isIpv6(pkt)) { + // Set reflected packet's dst to that of the original's src + System.arraycopy( + pkt, // src + IP6_ADDR_OFFSET + IP6_ADDR_LEN, // src offset + reflected, // dst + IP6_ADDR_OFFSET, // dst offset + IP6_ADDR_LEN); // len + // Set reflected packet's src IP to that of the original's dst IP + System.arraycopy( + pkt, // src + IP6_ADDR_OFFSET, // src offset + reflected, // dst + IP6_ADDR_OFFSET + IP6_ADDR_LEN, // dst offset + IP6_ADDR_LEN); // len + } else { + // Set reflected packet's dst to that of the original's src + System.arraycopy( + pkt, // src + IP4_ADDR_OFFSET + IP4_ADDR_LEN, // src offset + reflected, // dst + IP4_ADDR_OFFSET, // dst offset + IP4_ADDR_LEN); // len + // Set reflected packet's src IP to that of the original's dst IP + System.arraycopy( + pkt, // src + IP4_ADDR_OFFSET, // src offset + reflected, // dst + IP4_ADDR_OFFSET + IP4_ADDR_LEN, // dst offset + IP4_ADDR_LEN); // len + } + return reflected; + } + + /** Takes all captured packets, flips the src/dst, and re-injects them. */ + public void reflectPackets() throws IOException { + synchronized (mPackets) { + for (byte[] pkt : mPackets) { + injectPacket(getReflectedPacket(pkt)); + } + } + } + + public void injectPacket(byte[] pkt) throws IOException { + FileOutputStream out = new FileOutputStream(mTunFd.getFileDescriptor()); + out.write(pkt); + out.flush(); + } +} From af4330f7770cdcc853b5a61a52f49a734635ffc4 Mon Sep 17 00:00:00 2001 From: Benedict Wong Date: Tue, 7 May 2019 19:11:26 -0700 Subject: [PATCH 0612/1109] Check for IPSEC_TUNNELS feature before running CTS tests If tunnel feature does is not present, skip tests. Bug: 117183273 Test: This Change-Id: I62fcc2cbca8bf3d2b70da5646303a7059a0df663 Merged-In: I62fcc2cbca8bf3d2b70da5646303a7059a0df663 (cherry picked from commit 698c99fcf03a4e1afb028ac66852140762a7f2b1) --- .../src/android/net/cts/IpSecManagerTunnelTest.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java index 5dc9b63b87..c8c99f4a37 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java @@ -21,6 +21,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import android.content.pm.PackageManager; import android.net.IpSecAlgorithm; import android.net.IpSecManager; import android.net.IpSecTransform; @@ -56,6 +57,12 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { setAppop(false); } + private boolean hasTunnelsFeature() { + return getContext() + .getPackageManager() + .hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS); + } + private void setAppop(boolean allow) { // Under normal circumstances, the MANAGE_IPSEC_TUNNELS appop would be auto-granted by the // telephony framework, and the only permission that is sufficient is NETWORK_STACK. So we @@ -69,6 +76,8 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { } public void testSecurityExceptionsCreateTunnelInterface() throws Exception { + if (!hasTunnelsFeature()) return; + // Ensure we don't have the appop. Permission is not requested in the Manifest setAppop(false); @@ -81,6 +90,8 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { } public void testSecurityExceptionsBuildTunnelTransform() throws Exception { + if (!hasTunnelsFeature()) return; + // Ensure we don't have the appop. Permission is not requested in the Manifest setAppop(false); @@ -97,6 +108,8 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { private void checkTunnel(InetAddress inner, InetAddress outer, boolean useEncap) throws Exception { + if (!hasTunnelsFeature()) return; + setAppop(true); int innerPrefixLen = inner instanceof Inet6Address ? IP6_PREFIX_LEN : IP4_PREFIX_LEN; From 75fb3d002e91d3cff5db5ac625acb592108afcb1 Mon Sep 17 00:00:00 2001 From: Benedict Wong Date: Thu, 4 Apr 2019 17:20:38 -0700 Subject: [PATCH 0613/1109] Add utilities to generate packets This change adds utility methods to generate packets incrementally. It supports UDP, ESP, IPv4, IPv6 packet generation. For ESP, it exclusively does AES-CBC, HMAC-SHA256. Bug: 72950854 Test: This Change-Id: Icffeed2ebb2005d79faf04f48fd5126d1d6fb175 --- .../src/android/net/cts/IpSecBaseTest.java | 11 - .../src/android/net/cts/IpSecManagerTest.java | 37 +- .../net/src/android/net/cts/PacketUtils.java | 460 ++++++++++++++++++ .../cts/net/src/android/net/cts/TunUtils.java | 16 +- 4 files changed, 483 insertions(+), 41 deletions(-) create mode 100644 tests/cts/net/src/android/net/cts/PacketUtils.java diff --git a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java index cbb9c195d0..35d0f485e0 100644 --- a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java @@ -52,17 +52,6 @@ public class IpSecBaseTest extends AndroidTestCase { protected static final int[] DIRECTIONS = new int[] {IpSecManager.DIRECTION_IN, IpSecManager.DIRECTION_OUT}; - protected static final int TCP_HDRLEN_WITH_OPTIONS = 32; - protected static final int UDP_HDRLEN = 8; - protected static final int IP4_HDRLEN = 20; - protected static final int IP6_HDRLEN = 40; - - // Encryption parameters - protected static final int AES_GCM_IV_LEN = 8; - protected static final int AES_CBC_IV_LEN = 16; - protected static final int AES_GCM_BLK_SIZE = 4; - protected static final int AES_CBC_BLK_SIZE = 16; - protected static final byte[] TEST_DATA = "Best test data ever!".getBytes(); protected static final int DATA_BUFFER_LEN = 4096; protected static final int SOCK_TIMEOUT = 500; diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java index e788d9602f..60d1c03ee2 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java @@ -16,6 +16,14 @@ package android.net.cts; +import static android.net.cts.PacketUtils.AES_CBC_BLK_SIZE; +import static android.net.cts.PacketUtils.AES_CBC_IV_LEN; +import static android.net.cts.PacketUtils.AES_GCM_BLK_SIZE; +import static android.net.cts.PacketUtils.AES_GCM_IV_LEN; +import static android.net.cts.PacketUtils.IP4_HDRLEN; +import static android.net.cts.PacketUtils.IP6_HDRLEN; +import static android.net.cts.PacketUtils.TCP_HDRLEN_WITH_TIMESTAMP_OPT; +import static android.net.cts.PacketUtils.UDP_HDRLEN; import static android.system.OsConstants.IPPROTO_TCP; import static android.system.OsConstants.IPPROTO_UDP; import static org.junit.Assert.assertArrayEquals; @@ -421,19 +429,6 @@ public class IpSecManagerTest extends IpSecBaseTest { } } - /** Helper function to calculate expected ESP packet size. */ - private int calculateEspPacketSize( - int payloadLen, int cryptIvLength, int cryptBlockSize, int authTruncLen) { - final int ESP_HDRLEN = 4 + 4; // SPI + Seq# - final int ICV_LEN = authTruncLen / 8; // Auth trailer; based on truncation length - payloadLen += cryptIvLength; // Initialization Vector - payloadLen += 2; // ESP trailer - - // Align to block size of encryption algorithm - payloadLen += (cryptBlockSize - (payloadLen % cryptBlockSize)) % cryptBlockSize; - return payloadLen + ESP_HDRLEN + ICV_LEN; - } - public void checkTransform( int protocol, String localAddress, @@ -474,7 +469,7 @@ public class IpSecManagerTest extends IpSecBaseTest { try (IpSecTransform transform = transformBuilder.buildTransportModeTransform(local, spi)) { if (protocol == IPPROTO_TCP) { - transportHdrLen = TCP_HDRLEN_WITH_OPTIONS; + transportHdrLen = TCP_HDRLEN_WITH_TIMESTAMP_OPT; checkTcp(transform, local, sendCount, useJavaSockets); } else if (protocol == IPPROTO_UDP) { transportHdrLen = UDP_HDRLEN; @@ -511,7 +506,7 @@ public class IpSecManagerTest extends IpSecBaseTest { int innerPacketSize = TEST_DATA.length + transportHdrLen + ipHdrLen; int outerPacketSize = - calculateEspPacketSize( + PacketUtils.calculateEspPacketSize( TEST_DATA.length + transportHdrLen, ivLen, blkSize, truncLenBits) + udpEncapLen + ipHdrLen; @@ -529,13 +524,13 @@ public class IpSecManagerTest extends IpSecBaseTest { // Add TCP ACKs for data packets if (protocol == IPPROTO_TCP) { int encryptedTcpPktSize = - calculateEspPacketSize(TCP_HDRLEN_WITH_OPTIONS, ivLen, blkSize, truncLenBits); + PacketUtils.calculateEspPacketSize( + TCP_HDRLEN_WITH_TIMESTAMP_OPT, ivLen, blkSize, truncLenBits); - - // Add data packet ACKs - expectedOuterBytes += (encryptedTcpPktSize + udpEncapLen + ipHdrLen) * (sendCount); - expectedInnerBytes += (TCP_HDRLEN_WITH_OPTIONS + ipHdrLen) * (sendCount); - expectedPackets += sendCount; + // Add data packet ACKs + expectedOuterBytes += (encryptedTcpPktSize + udpEncapLen + ipHdrLen) * (sendCount); + expectedInnerBytes += (TCP_HDRLEN_WITH_TIMESTAMP_OPT + ipHdrLen) * (sendCount); + expectedPackets += sendCount; } StatsChecker.waitForNumPackets(expectedPackets); diff --git a/tests/cts/net/src/android/net/cts/PacketUtils.java b/tests/cts/net/src/android/net/cts/PacketUtils.java new file mode 100644 index 0000000000..6177827ba6 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/PacketUtils.java @@ -0,0 +1,460 @@ +/* + * 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 static android.system.OsConstants.IPPROTO_IPV6; +import static android.system.OsConstants.IPPROTO_UDP; + +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.nio.ByteBuffer; +import java.nio.ShortBuffer; +import java.security.GeneralSecurityException; +import java.security.SecureRandom; +import java.util.Arrays; +import javax.crypto.Cipher; +import javax.crypto.Mac; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +public class PacketUtils { + private static final String TAG = PacketUtils.class.getSimpleName(); + + private static final int DATA_BUFFER_LEN = 4096; + + static final int IP4_HDRLEN = 20; + static final int IP6_HDRLEN = 40; + static final int UDP_HDRLEN = 8; + static final int TCP_HDRLEN = 20; + static final int TCP_HDRLEN_WITH_TIMESTAMP_OPT = TCP_HDRLEN + 12; + + // Not defined in OsConstants + static final int IPPROTO_IPV4 = 4; + static final int IPPROTO_ESP = 50; + + // Encryption parameters + static final int AES_GCM_IV_LEN = 8; + static final int AES_CBC_IV_LEN = 16; + static final int AES_GCM_BLK_SIZE = 4; + static final int AES_CBC_BLK_SIZE = 16; + + // Encryption algorithms + static final String AES = "AES"; + static final String AES_CBC = "AES/CBC/NoPadding"; + static final String HMAC_SHA_256 = "HmacSHA256"; + + public interface Payload { + byte[] getPacketBytes(IpHeader header) throws Exception; + + void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) throws Exception; + + short length(); + + int getProtocolId(); + } + + public abstract static class IpHeader { + + public final byte proto; + public final InetAddress srcAddr; + public final InetAddress dstAddr; + public final Payload payload; + + public IpHeader(int proto, InetAddress src, InetAddress dst, Payload payload) { + this.proto = (byte) proto; + this.srcAddr = src; + this.dstAddr = dst; + this.payload = payload; + } + + public abstract byte[] getPacketBytes() throws Exception; + + public abstract int getProtocolId(); + } + + public static class Ip4Header extends IpHeader { + private short checksum; + + public Ip4Header(int proto, Inet4Address src, Inet4Address dst, Payload payload) { + super(proto, src, dst, payload); + } + + public byte[] getPacketBytes() throws Exception { + ByteBuffer resultBuffer = buildHeader(); + payload.addPacketBytes(this, resultBuffer); + + return getByteArrayFromBuffer(resultBuffer); + } + + public ByteBuffer buildHeader() { + ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN); + + // Version, IHL + bb.put((byte) (0x45)); + + // DCSP, ECN + bb.put((byte) 0); + + // Total Length + bb.putShort((short) (IP4_HDRLEN + payload.length())); + + // Empty for Identification, Flags and Fragment Offset + bb.putShort((short) 0); + bb.put((byte) 0x40); + bb.put((byte) 0x00); + + // TTL + bb.put((byte) 64); + + // Protocol + bb.put(proto); + + // Header Checksum + final int ipChecksumOffset = bb.position(); + bb.putShort((short) 0); + + // Src/Dst addresses + bb.put(srcAddr.getAddress()); + bb.put(dstAddr.getAddress()); + + bb.putShort(ipChecksumOffset, calculateChecksum(bb)); + + return bb; + } + + private short calculateChecksum(ByteBuffer bb) { + int checksum = 0; + + // Calculate sum of 16-bit values, excluding checksum. IPv4 headers are always 32-bit + // aligned, so no special cases needed for unaligned values. + ShortBuffer shortBuffer = ByteBuffer.wrap(getByteArrayFromBuffer(bb)).asShortBuffer(); + while (shortBuffer.hasRemaining()) { + short val = shortBuffer.get(); + + // Wrap as needed + checksum = addAndWrapForChecksum(checksum, val); + } + + return onesComplement(checksum); + } + + public int getProtocolId() { + return IPPROTO_IPV4; + } + } + + public static class Ip6Header extends IpHeader { + public Ip6Header(int nextHeader, Inet6Address src, Inet6Address dst, Payload payload) { + super(nextHeader, src, dst, payload); + } + + public byte[] getPacketBytes() throws Exception { + ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN); + + // Version | Traffic Class (First 4 bits) + bb.put((byte) 0x60); + + // Traffic class (Last 4 bits), Flow Label + bb.put((byte) 0); + bb.put((byte) 0); + bb.put((byte) 0); + + // Payload Length + bb.putShort((short) payload.length()); + + // Next Header + bb.put(proto); + + // Hop Limit + bb.put((byte) 64); + + // Src/Dst addresses + bb.put(srcAddr.getAddress()); + bb.put(dstAddr.getAddress()); + + // Payload + payload.addPacketBytes(this, bb); + + return getByteArrayFromBuffer(bb); + } + + public int getProtocolId() { + return IPPROTO_IPV6; + } + } + + public static class BytePayload implements Payload { + public final byte[] payload; + + public BytePayload(byte[] payload) { + this.payload = payload; + } + + public int getProtocolId() { + return -1; + } + + public byte[] getPacketBytes(IpHeader header) { + ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN); + + addPacketBytes(header, bb); + return getByteArrayFromBuffer(bb); + } + + public void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) { + resultBuffer.put(payload); + } + + public short length() { + return (short) payload.length; + } + } + + public static class UdpHeader implements Payload { + + public final short srcPort; + public final short dstPort; + public final Payload payload; + + public UdpHeader(int srcPort, int dstPort, Payload payload) { + this.srcPort = (short) srcPort; + this.dstPort = (short) dstPort; + this.payload = payload; + } + + public int getProtocolId() { + return IPPROTO_UDP; + } + + public short length() { + return (short) (payload.length() + 8); + } + + public byte[] getPacketBytes(IpHeader header) throws Exception { + ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN); + + addPacketBytes(header, bb); + return getByteArrayFromBuffer(bb); + } + + public void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) throws Exception { + // Source, Destination port + resultBuffer.putShort(srcPort); + resultBuffer.putShort(dstPort); + + // Payload Length + resultBuffer.putShort(length()); + + // Get payload bytes for checksum + payload + ByteBuffer payloadBuffer = ByteBuffer.allocate(DATA_BUFFER_LEN); + payload.addPacketBytes(header, payloadBuffer); + byte[] payloadBytes = getByteArrayFromBuffer(payloadBuffer); + + // Checksum + resultBuffer.putShort(calculateChecksum(header, payloadBytes)); + + // Payload + resultBuffer.put(payloadBytes); + } + + private short calculateChecksum(IpHeader header, byte[] payloadBytes) throws Exception { + int newChecksum = 0; + ShortBuffer srcBuffer = ByteBuffer.wrap(header.srcAddr.getAddress()).asShortBuffer(); + ShortBuffer dstBuffer = ByteBuffer.wrap(header.dstAddr.getAddress()).asShortBuffer(); + + while (srcBuffer.hasRemaining() || dstBuffer.hasRemaining()) { + short val = srcBuffer.hasRemaining() ? srcBuffer.get() : dstBuffer.get(); + + // Wrap as needed + newChecksum = addAndWrapForChecksum(newChecksum, val); + } + + // Add pseudo-header values. Proto is 0-padded, so just use the byte. + newChecksum = addAndWrapForChecksum(newChecksum, header.proto); + newChecksum = addAndWrapForChecksum(newChecksum, length()); + newChecksum = addAndWrapForChecksum(newChecksum, srcPort); + newChecksum = addAndWrapForChecksum(newChecksum, dstPort); + newChecksum = addAndWrapForChecksum(newChecksum, length()); + + ShortBuffer payloadShortBuffer = ByteBuffer.wrap(payloadBytes).asShortBuffer(); + while (payloadShortBuffer.hasRemaining()) { + newChecksum = addAndWrapForChecksum(newChecksum, payloadShortBuffer.get()); + } + if (payload.length() % 2 != 0) { + newChecksum = + addAndWrapForChecksum( + newChecksum, (payloadBytes[payloadBytes.length - 1] << 8)); + } + + return onesComplement(newChecksum); + } + } + + public static class EspHeader implements Payload { + public final int nextHeader; + public final int spi; + public final int seqNum; + public final byte[] key; + public final byte[] payload; + + /** + * Generic constructor for ESP headers. + * + *

    For Tunnel mode, payload will be a full IP header + attached payloads + * + *

    For Transport mode, payload will be only the attached payloads, but with the checksum + * calculated using the pre-encryption IP header + */ + public EspHeader(int nextHeader, int spi, int seqNum, byte[] key, byte[] payload) { + this.nextHeader = nextHeader; + this.spi = spi; + this.seqNum = seqNum; + this.key = key; + this.payload = payload; + } + + public int getProtocolId() { + return IPPROTO_ESP; + } + + public short length() { + // ALWAYS uses AES-CBC, HMAC-SHA256 (128b trunc len) + return (short) + calculateEspPacketSize(payload.length, AES_CBC_IV_LEN, AES_CBC_BLK_SIZE, 128); + } + + public byte[] getPacketBytes(IpHeader header) throws Exception { + ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN); + + addPacketBytes(header, bb); + return getByteArrayFromBuffer(bb); + } + + public void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) throws Exception { + ByteBuffer espPayloadBuffer = ByteBuffer.allocate(DATA_BUFFER_LEN); + espPayloadBuffer.putInt(spi); + espPayloadBuffer.putInt(seqNum); + espPayloadBuffer.put(getCiphertext(key)); + + espPayloadBuffer.put(getIcv(getByteArrayFromBuffer(espPayloadBuffer)), 0, 16); + resultBuffer.put(getByteArrayFromBuffer(espPayloadBuffer)); + } + + private byte[] getIcv(byte[] authenticatedSection) throws GeneralSecurityException { + Mac sha256HMAC = Mac.getInstance(HMAC_SHA_256); + SecretKeySpec authKey = new SecretKeySpec(key, HMAC_SHA_256); + sha256HMAC.init(authKey); + + return sha256HMAC.doFinal(authenticatedSection); + } + + /** + * Encrypts and builds ciphertext block. Includes the IV, Padding and Next-Header blocks + * + *

    The ciphertext does NOT include the SPI/Sequence numbers, or the ICV. + */ + private byte[] getCiphertext(byte[] key) throws GeneralSecurityException { + int paddedLen = calculateEspEncryptedLength(payload.length, AES_CBC_BLK_SIZE); + ByteBuffer paddedPayload = ByteBuffer.allocate(paddedLen); + paddedPayload.put(payload); + + // Add padding - consecutive integers from 0x01 + int pad = 1; + while (paddedPayload.position() < paddedPayload.limit()) { + paddedPayload.put((byte) pad++); + } + + paddedPayload.position(paddedPayload.limit() - 2); + paddedPayload.put((byte) (paddedLen - 2 - payload.length)); // Pad length + paddedPayload.put((byte) nextHeader); + + // Generate Initialization Vector + byte[] iv = new byte[AES_CBC_IV_LEN]; + new SecureRandom().nextBytes(iv); + IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); + SecretKeySpec secretKeySpec = new SecretKeySpec(key, AES); + + // Encrypt payload + Cipher cipher = Cipher.getInstance(AES_CBC); + cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); + byte[] encrypted = cipher.doFinal(getByteArrayFromBuffer(paddedPayload)); + + // Build ciphertext + ByteBuffer cipherText = ByteBuffer.allocate(AES_CBC_IV_LEN + encrypted.length); + cipherText.put(iv); + cipherText.put(encrypted); + + return getByteArrayFromBuffer(cipherText); + } + } + + private static int addAndWrapForChecksum(int currentChecksum, int value) { + currentChecksum += value & 0x0000ffff; + + // Wrap anything beyond the first 16 bits, and add to lower order bits + return (currentChecksum >>> 16) + (currentChecksum & 0x0000ffff); + } + + private static short onesComplement(int val) { + val = (val >>> 16) + (val & 0xffff); + + if (val == 0) return 0; + return (short) ((~val) & 0xffff); + } + + public static int calculateEspPacketSize( + int payloadLen, int cryptIvLength, int cryptBlockSize, int authTruncLen) { + final int ESP_HDRLEN = 4 + 4; // SPI + Seq# + final int ICV_LEN = authTruncLen / 8; // Auth trailer; based on truncation length + payloadLen += cryptIvLength; // Initialization Vector + + // Align to block size of encryption algorithm + payloadLen = calculateEspEncryptedLength(payloadLen, cryptBlockSize); + return payloadLen + ESP_HDRLEN + ICV_LEN; + } + + private static int calculateEspEncryptedLength(int payloadLen, int cryptBlockSize) { + payloadLen += 2; // ESP trailer + + // Align to block size of encryption algorithm + return payloadLen + calculateEspPadLen(payloadLen, cryptBlockSize); + } + + private static int calculateEspPadLen(int payloadLen, int cryptBlockSize) { + return (cryptBlockSize - (payloadLen % cryptBlockSize)) % cryptBlockSize; + } + + private static byte[] getByteArrayFromBuffer(ByteBuffer buffer) { + return Arrays.copyOfRange(buffer.array(), 0, buffer.position()); + } + + /* + * Debug printing + */ + private static final char[] hexArray = "0123456789ABCDEF".toCharArray(); + + public static String bytesToHex(byte[] bytes) { + StringBuilder sb = new StringBuilder(); + for (byte b : bytes) { + sb.append(hexArray[b >>> 4]); + sb.append(hexArray[b & 0x0F]); + sb.append(' '); + } + return sb.toString(); + } +} diff --git a/tests/cts/net/src/android/net/cts/TunUtils.java b/tests/cts/net/src/android/net/cts/TunUtils.java index ca233ce1e8..4d5533fc62 100644 --- a/tests/cts/net/src/android/net/cts/TunUtils.java +++ b/tests/cts/net/src/android/net/cts/TunUtils.java @@ -16,6 +16,10 @@ package android.net.cts; +import static android.net.cts.PacketUtils.IP4_HDRLEN; +import static android.net.cts.PacketUtils.IP6_HDRLEN; +import static android.net.cts.PacketUtils.IPPROTO_ESP; +import static android.net.cts.PacketUtils.UDP_HDRLEN; import static android.system.OsConstants.IPPROTO_UDP; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -46,9 +50,6 @@ public class TunUtils { private static final int IP6_ADDR_OFFSET = 8; private static final int IP6_ADDR_LEN = 16; - // Not defined in OsConstants - private static final int IPPROTO_ESP = 50; - private final ParcelFileDescriptor mTunFd; private final List mPackets = new ArrayList<>(); private final Thread mReaderThread; @@ -178,17 +179,14 @@ public class TunUtils { private static boolean isEsp(byte[] pkt, int spi, boolean encap) { if (isIpv6(pkt)) { // IPv6 UDP encap not supported by kernels; assume non-encap. - return pkt[IP6_PROTO_OFFSET] == IPPROTO_ESP - && isSpiEqual(pkt, IpSecBaseTest.IP6_HDRLEN, spi); + return pkt[IP6_PROTO_OFFSET] == IPPROTO_ESP && isSpiEqual(pkt, IP6_HDRLEN, spi); } else { // Use default IPv4 header length (assuming no options) if (encap) { return pkt[IP4_PROTO_OFFSET] == IPPROTO_UDP - && isSpiEqual( - pkt, IpSecBaseTest.IP4_HDRLEN + IpSecBaseTest.UDP_HDRLEN, spi); + && isSpiEqual(pkt, IP4_HDRLEN + UDP_HDRLEN, spi); } else { - return pkt[IP4_PROTO_OFFSET] == IPPROTO_ESP - && isSpiEqual(pkt, IpSecBaseTest.IP4_HDRLEN, spi); + return pkt[IP4_PROTO_OFFSET] == IPPROTO_ESP && isSpiEqual(pkt, IP4_HDRLEN, spi); } } } From 64e64ff454338ced2e418fa13b65b75a5884ebd5 Mon Sep 17 00:00:00 2001 From: Benedict Wong Date: Mon, 8 Apr 2019 10:15:26 -0700 Subject: [PATCH 0614/1109] Add IPsec Tunnel mode data tests This change adds single-direction tests for the IPsec Tunnel Mode API. In the outbound direction, TUNs are used to capture outgoing packets, and values are inspected. In the inbound direction, packets are built manually, using the PacketUtils framework. Additional testing for end-to-end integration tests will follow in aosp/941021 using packet reflection via the TUN. Bug: 72950854 Test: This; passing Change-Id: Ic4181fc857fa880db5553314efa914f870dbe87c --- .../src/android/net/cts/IpSecBaseTest.java | 43 +- .../net/cts/IpSecManagerTunnelTest.java | 694 ++++++++++++++++-- .../cts/net/src/android/net/cts/TunUtils.java | 7 + 3 files changed, 661 insertions(+), 83 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java index 35d0f485e0..087dbdaec3 100644 --- a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java @@ -28,11 +28,12 @@ import android.system.OsConstants; import android.test.AndroidTestCase; import android.util.Log; +import androidx.test.InstrumentationRegistry; + import java.io.FileDescriptor; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; -import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.InetSocketAddress; @@ -72,8 +73,14 @@ public class IpSecBaseTest extends AndroidTestCase { protected void setUp() throws Exception { super.setUp(); - mISM = (IpSecManager) getContext().getSystemService(Context.IPSEC_SERVICE); - mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); + mISM = + (IpSecManager) + InstrumentationRegistry.getContext() + .getSystemService(Context.IPSEC_SERVICE); + mCM = + (ConnectivityManager) + InstrumentationRegistry.getContext() + .getSystemService(Context.CONNECTIVITY_SERVICE); } protected static byte[] getKey(int bitLength) { @@ -195,6 +202,17 @@ public class IpSecBaseTest extends AndroidTestCase { public static class JavaUdpSocket implements GenericUdpSocket { public final DatagramSocket mSocket; + public JavaUdpSocket(InetAddress localAddr, int port) { + try { + mSocket = new DatagramSocket(port, localAddr); + mSocket.setSoTimeout(SOCK_TIMEOUT); + } catch (SocketException e) { + // Fail loudly if we can't set up sockets properly. And without the timeout, we + // could easily end up in an endless wait. + throw new RuntimeException(e); + } + } + public JavaUdpSocket(InetAddress localAddr) { try { mSocket = new DatagramSocket(0, localAddr); @@ -425,26 +443,25 @@ public class IpSecBaseTest extends AndroidTestCase { } protected static IpSecTransform buildIpSecTransform( - Context mContext, + Context context, IpSecManager.SecurityParameterIndex spi, IpSecManager.UdpEncapsulationSocket encapSocket, InetAddress remoteAddr) throws Exception { - String localAddr = (remoteAddr instanceof Inet4Address) ? IPV4_LOOPBACK : IPV6_LOOPBACK; IpSecTransform.Builder builder = - new IpSecTransform.Builder(mContext) - .setEncryption(new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY)) - .setAuthentication( - new IpSecAlgorithm( - IpSecAlgorithm.AUTH_HMAC_SHA256, - AUTH_KEY, - AUTH_KEY.length * 4)); + new IpSecTransform.Builder(context) + .setEncryption(new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY)) + .setAuthentication( + new IpSecAlgorithm( + IpSecAlgorithm.AUTH_HMAC_SHA256, + AUTH_KEY, + AUTH_KEY.length * 4)); if (encapSocket != null) { builder.setIpv4Encapsulation(encapSocket, encapSocket.getPort()); } - return builder.buildTransportModeTransform(InetAddress.getByName(localAddr), spi); + return builder.buildTransportModeTransform(remoteAddr, spi); } private IpSecTransform buildDefaultTransform(InetAddress localAddr) throws Exception { diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java index c8c99f4a37..e8c0a7a4b2 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java @@ -16,174 +16,728 @@ package android.net.cts; +import static android.app.AppOpsManager.OP_MANAGE_IPSEC_TUNNELS; +import static android.net.IpSecManager.UdpEncapsulationSocket; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; +import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED; +import static android.net.NetworkCapabilities.TRANSPORT_TEST; +import static android.net.cts.PacketUtils.AES_CBC_BLK_SIZE; +import static android.net.cts.PacketUtils.AES_CBC_IV_LEN; +import static android.net.cts.PacketUtils.BytePayload; +import static android.net.cts.PacketUtils.EspHeader; +import static android.net.cts.PacketUtils.IP4_HDRLEN; +import static android.net.cts.PacketUtils.IP6_HDRLEN; +import static android.net.cts.PacketUtils.Ip4Header; +import static android.net.cts.PacketUtils.Ip6Header; +import static android.net.cts.PacketUtils.IpHeader; +import static android.net.cts.PacketUtils.UDP_HDRLEN; +import static android.net.cts.PacketUtils.UdpHeader; +import static android.system.OsConstants.AF_INET; +import static android.system.OsConstants.AF_INET6; + +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import android.app.AppOpsManager; +import android.content.Context; import android.content.pm.PackageManager; +import android.net.ConnectivityManager; import android.net.IpSecAlgorithm; import android.net.IpSecManager; import android.net.IpSecTransform; +import android.net.LinkAddress; import android.net.Network; +import android.net.NetworkRequest; +import android.net.TestNetworkInterface; +import android.net.TestNetworkManager; +import android.net.cts.PacketUtils.Payload; +import android.os.Binder; +import android.os.IBinder; +import android.os.ParcelFileDescriptor; + +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; import com.android.compatibility.common.util.SystemUtil; +import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.InterfaceAddress; import java.net.NetworkInterface; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) public class IpSecManagerTunnelTest extends IpSecBaseTest { - private static final String TAG = IpSecManagerTunnelTest.class.getSimpleName(); - private static final int IP4_PREFIX_LEN = 24; - private static final int IP6_PREFIX_LEN = 48; - private static final InetAddress OUTER_ADDR4 = InetAddress.parseNumericAddress("192.0.2.0"); - private static final InetAddress OUTER_ADDR6 = - InetAddress.parseNumericAddress("2001:db8:f00d::1"); - private static final InetAddress INNER_ADDR4 = InetAddress.parseNumericAddress("10.0.0.1"); - private static final InetAddress INNER_ADDR6 = - InetAddress.parseNumericAddress("2001:db8:d00d::1"); - private Network mUnderlyingNetwork; - private Network mIpSecNetwork; + private static final InetAddress LOCAL_OUTER_4 = InetAddress.parseNumericAddress("192.0.2.1"); + private static final InetAddress REMOTE_OUTER_4 = InetAddress.parseNumericAddress("192.0.2.2"); + private static final InetAddress LOCAL_OUTER_6 = + InetAddress.parseNumericAddress("2001:db8:1::1"); + private static final InetAddress REMOTE_OUTER_6 = + InetAddress.parseNumericAddress("2001:db8:1::2"); - protected void setUp() throws Exception { + private static final InetAddress LOCAL_INNER_4 = + InetAddress.parseNumericAddress("198.51.100.1"); + private static final InetAddress REMOTE_INNER_4 = + InetAddress.parseNumericAddress("198.51.100.2"); + private static final InetAddress LOCAL_INNER_6 = + InetAddress.parseNumericAddress("2001:db8:2::1"); + private static final InetAddress REMOTE_INNER_6 = + InetAddress.parseNumericAddress("2001:db8:2::2"); + + private static final int IP4_PREFIX_LEN = 32; + private static final int IP6_PREFIX_LEN = 128; + + private static final int TIMEOUT_MS = 500; + + // Static state to reduce setup/teardown + private static ConnectivityManager sCM; + private static TestNetworkManager sTNM; + private static ParcelFileDescriptor sTunFd; + private static TestNetworkCallback sTunNetworkCallback; + private static Network sTunNetwork; + private static TunUtils sTunUtils; + + private static Context sContext = InstrumentationRegistry.getContext(); + private static IBinder sBinder = new Binder(); + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .adoptShellPermissionIdentity(); + sCM = (ConnectivityManager) sContext.getSystemService(Context.CONNECTIVITY_SERVICE); + sTNM = (TestNetworkManager) sContext.getSystemService(Context.TEST_NETWORK_SERVICE); + + // 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 + // right appop permissions. + setAppop(OP_MANAGE_IPSEC_TUNNELS, true); + + TestNetworkInterface testIntf = + sTNM.createTunInterface( + new LinkAddress[] { + new LinkAddress(LOCAL_OUTER_4, IP4_PREFIX_LEN), + new LinkAddress(LOCAL_OUTER_6, IP6_PREFIX_LEN) + }); + + sTunFd = testIntf.getFileDescriptor(); + sTunNetworkCallback = setupAndGetTestNetwork(testIntf.getInterfaceName()); + sTunNetwork = sTunNetworkCallback.getNetworkBlocking(); + + sTunUtils = new TunUtils(sTunFd); + } + + @Before + public void setUp() throws Exception { super.setUp(); + + // Set to true before every run; some tests flip this. + setAppop(OP_MANAGE_IPSEC_TUNNELS, true); + + // Clear sTunUtils state + sTunUtils.reset(); } - protected void tearDown() { - setAppop(false); + @AfterClass + public static void tearDownAfterClass() throws Exception { + setAppop(OP_MANAGE_IPSEC_TUNNELS, false); + + sCM.unregisterNetworkCallback(sTunNetworkCallback); + + sTNM.teardownTestNetwork(sTunNetwork); + sTunFd.close(); + + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .dropShellPermissionIdentity(); } - private boolean hasTunnelsFeature() { - return getContext() - .getPackageManager() - .hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS); + private static boolean hasTunnelsFeature() { + return sContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS); } - private void setAppop(boolean allow) { - // Under normal circumstances, the MANAGE_IPSEC_TUNNELS appop would be auto-granted by the - // telephony framework, and the only permission that is sufficient is NETWORK_STACK. So we - // shell out the appop manager, to give us the right appop permissions. - String cmd = - "appops set " - + mContext.getPackageName() - + " MANAGE_IPSEC_TUNNELS " - + (allow ? "allow" : "deny"); - SystemUtil.runShellCommand(cmd); + private static void setAppop(int appop, boolean allow) { + String opName = AppOpsManager.opToName(appop); + for (String pkg : new String[] {"com.android.shell", sContext.getPackageName()}) { + String cmd = + String.format( + "appops set %s %s %s", + pkg, // Package name + opName, // Appop + (allow ? "allow" : "deny")); // Action + SystemUtil.runShellCommand(cmd); + } } - public void testSecurityExceptionsCreateTunnelInterface() throws Exception { + private static TestNetworkCallback setupAndGetTestNetwork(String ifname) throws Exception { + // Build a network request + NetworkRequest nr = + new NetworkRequest.Builder() + .addTransportType(TRANSPORT_TEST) + .removeCapability(NET_CAPABILITY_TRUSTED) + .removeCapability(NET_CAPABILITY_NOT_VPN) + .setNetworkSpecifier(ifname) + .build(); + + TestNetworkCallback cb = new TestNetworkCallback(); + sCM.requestNetwork(nr, cb); + + // Setup the test network after network request is filed to prevent Network from being + // reaped due to no requests matching it. + sTNM.setupTestNetwork(ifname, sBinder); + + return cb; + } + + @Test + public void testSecurityExceptionCreateTunnelInterfaceWithoutAppop() throws Exception { if (!hasTunnelsFeature()) return; // Ensure we don't have the appop. Permission is not requested in the Manifest - setAppop(false); + setAppop(OP_MANAGE_IPSEC_TUNNELS, false); // Security exceptions are thrown regardless of IPv4/IPv6. Just test one try { - mISM.createIpSecTunnelInterface(OUTER_ADDR6, OUTER_ADDR6, mUnderlyingNetwork); + mISM.createIpSecTunnelInterface(LOCAL_INNER_6, REMOTE_INNER_6, sTunNetwork); fail("Did not throw SecurityException for Tunnel creation without appop"); } catch (SecurityException expected) { } } - public void testSecurityExceptionsBuildTunnelTransform() throws Exception { + @Test + public void testSecurityExceptionBuildTunnelTransformWithoutAppop() throws Exception { if (!hasTunnelsFeature()) return; // Ensure we don't have the appop. Permission is not requested in the Manifest - setAppop(false); + setAppop(OP_MANAGE_IPSEC_TUNNELS, false); // Security exceptions are thrown regardless of IPv4/IPv6. Just test one try (IpSecManager.SecurityParameterIndex spi = - mISM.allocateSecurityParameterIndex(OUTER_ADDR4); + mISM.allocateSecurityParameterIndex(LOCAL_INNER_4); IpSecTransform transform = - new IpSecTransform.Builder(mContext) - .buildTunnelModeTransform(OUTER_ADDR4, spi)) { + new IpSecTransform.Builder(sContext) + .buildTunnelModeTransform(REMOTE_INNER_4, spi)) { fail("Did not throw SecurityException for Transform creation without appop"); } catch (SecurityException expected) { } } - private void checkTunnel(InetAddress inner, InetAddress outer, boolean useEncap) + /* Test runnables for callbacks after IPsec tunnels are set up. */ + private interface TestRunnable { + void run(Network ipsecNetwork) throws Exception; + } + + private static class TestNetworkCallback extends ConnectivityManager.NetworkCallback { + private final CompletableFuture futureNetwork = new CompletableFuture<>(); + + @Override + public void onAvailable(Network network) { + futureNetwork.complete(network); + } + + public Network getNetworkBlocking() throws Exception { + return futureNetwork.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); + } + } + + private int getPacketSize( + int innerFamily, int outerFamily, boolean useEncap, boolean transportInTunnelMode) { + int expectedPacketSize = TEST_DATA.length + UDP_HDRLEN; + + // Inner Transport mode packet size + if (transportInTunnelMode) { + expectedPacketSize = + PacketUtils.calculateEspPacketSize( + expectedPacketSize, + AES_CBC_IV_LEN, + AES_CBC_BLK_SIZE, + AUTH_KEY.length * 4); + } + + // Inner IP Header + expectedPacketSize += innerFamily == AF_INET ? IP4_HDRLEN : IP6_HDRLEN; + + // Tunnel mode transform size + expectedPacketSize = + PacketUtils.calculateEspPacketSize( + expectedPacketSize, AES_CBC_IV_LEN, AES_CBC_BLK_SIZE, AUTH_KEY.length * 4); + + // UDP encap size + expectedPacketSize += useEncap ? UDP_HDRLEN : 0; + + // Outer IP Header + expectedPacketSize += outerFamily == AF_INET ? IP4_HDRLEN : IP6_HDRLEN; + + return expectedPacketSize; + } + + private interface TestRunnableFactory { + TestRunnable getTestRunnable( + boolean transportInTunnelMode, + int spi, + InetAddress localInner, + InetAddress remoteInner, + InetAddress localOuter, + InetAddress remoteOuter, + IpSecTransform inTransportTransform, + IpSecTransform outTransportTransform, + int encapPort, + int expectedPacketSize) + throws Exception; + } + + private class OutputTestRunnableFactory implements TestRunnableFactory { + public TestRunnable getTestRunnable( + boolean transportInTunnelMode, + int spi, + InetAddress localInner, + InetAddress remoteInner, + InetAddress localOuter, + InetAddress remoteOuter, + IpSecTransform inTransportTransform, + IpSecTransform outTransportTransform, + int encapPort, + int expectedPacketSize) { + return new TestRunnable() { + @Override + public void run(Network ipsecNetwork) throws Exception { + // Build a socket and send traffic + JavaUdpSocket socket = new JavaUdpSocket(localInner); + ipsecNetwork.bindSocket(socket.mSocket); + + // For Transport-In-Tunnel mode, apply transform to socket + if (transportInTunnelMode) { + mISM.applyTransportModeTransform( + socket.mSocket, IpSecManager.DIRECTION_IN, inTransportTransform); + mISM.applyTransportModeTransform( + socket.mSocket, IpSecManager.DIRECTION_OUT, outTransportTransform); + } + + socket.sendTo(TEST_DATA, remoteInner, socket.getPort()); + + // Verify that an encrypted packet is sent. As of right now, checking encrypted + // body is not possible, due to our not knowing some of the fields of the + // inner IP header (flow label, flags, etc) + sTunUtils.awaitEspPacketNoPlaintext( + spi, TEST_DATA, encapPort != 0, expectedPacketSize); + + socket.close(); + } + }; + } + } + + private class InputPacketGeneratorTestRunnableFactory implements TestRunnableFactory { + public TestRunnable getTestRunnable( + boolean transportInTunnelMode, + int spi, + InetAddress localInner, + InetAddress remoteInner, + InetAddress localOuter, + InetAddress remoteOuter, + IpSecTransform inTransportTransform, + IpSecTransform outTransportTransform, + int encapPort, + int expectedPacketSize) + throws Exception { + return new TestRunnable() { + @Override + public void run(Network ipsecNetwork) throws Exception { + // Build a socket and receive traffic + JavaUdpSocket socket = new JavaUdpSocket(localInner); + // JavaUdpSocket socket = new JavaUdpSocket(localInner, socketPort.get()); + ipsecNetwork.bindSocket(socket.mSocket); + + // For Transport-In-Tunnel mode, apply transform to socket + if (transportInTunnelMode) { + mISM.applyTransportModeTransform( + socket.mSocket, IpSecManager.DIRECTION_IN, outTransportTransform); + mISM.applyTransportModeTransform( + socket.mSocket, IpSecManager.DIRECTION_OUT, inTransportTransform); + } + + byte[] pkt; + if (transportInTunnelMode) { + pkt = + getTransportInTunnelModePacket( + spi, + spi, + remoteInner, + localInner, + remoteOuter, + localOuter, + socket.getPort(), + encapPort); + } else { + pkt = + getTunnelModePacket( + spi, + remoteInner, + localInner, + remoteOuter, + localOuter, + socket.getPort(), + encapPort); + } + sTunUtils.injectPacket(pkt); + + // Receive packet from socket, and validate + receiveAndValidatePacket(socket); + + socket.close(); + } + }; + } + } + + private void checkTunnelOutput( + int innerFamily, int outerFamily, boolean useEncap, boolean transportInTunnelMode) + throws Exception { + checkTunnel( + innerFamily, + outerFamily, + useEncap, + transportInTunnelMode, + new OutputTestRunnableFactory()); + } + + private void checkTunnelInput( + int innerFamily, int outerFamily, boolean useEncap, boolean transportInTunnelMode) + throws Exception { + checkTunnel( + innerFamily, + outerFamily, + useEncap, + transportInTunnelMode, + new InputPacketGeneratorTestRunnableFactory()); + } + + public void checkTunnel( + int innerFamily, + int outerFamily, + boolean useEncap, + boolean transportInTunnelMode, + TestRunnableFactory factory) throws Exception { if (!hasTunnelsFeature()) return; - setAppop(true); - int innerPrefixLen = inner instanceof Inet6Address ? IP6_PREFIX_LEN : IP4_PREFIX_LEN; + InetAddress localInner = innerFamily == AF_INET ? LOCAL_INNER_4 : LOCAL_INNER_6; + InetAddress remoteInner = innerFamily == AF_INET ? REMOTE_INNER_4 : REMOTE_INNER_6; - try (IpSecManager.SecurityParameterIndex spi = mISM.allocateSecurityParameterIndex(outer); + InetAddress localOuter = outerFamily == AF_INET ? LOCAL_OUTER_4 : LOCAL_OUTER_6; + InetAddress remoteOuter = outerFamily == AF_INET ? REMOTE_OUTER_4 : REMOTE_OUTER_6; + + // Preselect both SPI and encap port, to be used for both inbound and outbound tunnels. + // Re-uses the same SPI to ensure that even in cases of symmetric SPIs shared across tunnel + // and transport mode, packets are encrypted/decrypted properly based on the src/dst. + int spi = getRandomSpi(localOuter, remoteOuter); + int expectedPacketSize = + getPacketSize(innerFamily, outerFamily, useEncap, transportInTunnelMode); + + try (IpSecManager.SecurityParameterIndex inTransportSpi = + mISM.allocateSecurityParameterIndex(localInner, spi); + IpSecManager.SecurityParameterIndex outTransportSpi = + mISM.allocateSecurityParameterIndex(remoteInner, spi); + IpSecTransform inTransportTransform = + buildIpSecTransform(sContext, inTransportSpi, null, remoteInner); + IpSecTransform outTransportTransform = + buildIpSecTransform(sContext, outTransportSpi, null, localInner); + UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) { + + buildTunnelAndNetwork( + localInner, + remoteInner, + localOuter, + remoteOuter, + spi, + useEncap ? encapSocket : null, + factory.getTestRunnable( + transportInTunnelMode, + spi, + localInner, + remoteInner, + localOuter, + remoteOuter, + inTransportTransform, + outTransportTransform, + useEncap ? encapSocket.getPort() : 0, + expectedPacketSize)); + } + } + + private void buildTunnelAndNetwork( + InetAddress localInner, + InetAddress remoteInner, + InetAddress localOuter, + InetAddress remoteOuter, + int spi, + UdpEncapsulationSocket encapSocket, + TestRunnable test) + throws Exception { + int innerPrefixLen = localInner instanceof Inet6Address ? IP6_PREFIX_LEN : IP4_PREFIX_LEN; + TestNetworkCallback testNetworkCb = null; + + try (IpSecManager.SecurityParameterIndex inSpi = + mISM.allocateSecurityParameterIndex(localOuter, spi); + IpSecManager.SecurityParameterIndex outSpi = + mISM.allocateSecurityParameterIndex(remoteOuter, spi); IpSecManager.IpSecTunnelInterface tunnelIntf = - mISM.createIpSecTunnelInterface(outer, outer, mCM.getActiveNetwork()); - IpSecManager.UdpEncapsulationSocket encapSocket = - mISM.openUdpEncapsulationSocket()) { + mISM.createIpSecTunnelInterface(localOuter, remoteOuter, sTunNetwork)) { + // Build the test network + tunnelIntf.addAddress(localInner, innerPrefixLen); + testNetworkCb = setupAndGetTestNetwork(tunnelIntf.getInterfaceName()); + Network testNetwork = testNetworkCb.getNetworkBlocking(); - IpSecTransform.Builder transformBuilder = new IpSecTransform.Builder(mContext); + // Check interface was created + NetworkInterface netIntf = NetworkInterface.getByName(tunnelIntf.getInterfaceName()); + assertNotNull(netIntf); + + // Check addresses + List intfAddrs = netIntf.getInterfaceAddresses(); + assertEquals(1, intfAddrs.size()); + assertEquals(localInner, intfAddrs.get(0).getAddress()); + assertEquals(innerPrefixLen, intfAddrs.get(0).getNetworkPrefixLength()); + + // Configure Transform parameters + IpSecTransform.Builder transformBuilder = new IpSecTransform.Builder(sContext); transformBuilder.setEncryption( new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY)); transformBuilder.setAuthentication( new IpSecAlgorithm( IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4)); - if (useEncap) { + if (encapSocket != null) { transformBuilder.setIpv4Encapsulation(encapSocket, encapSocket.getPort()); } - // Check transform application - try (IpSecTransform transform = transformBuilder.buildTunnelModeTransform(outer, spi)) { - mISM.applyTunnelModeTransform(tunnelIntf, IpSecManager.DIRECTION_IN, transform); - mISM.applyTunnelModeTransform(tunnelIntf, IpSecManager.DIRECTION_OUT, transform); + // Apply transform and check that traffic is properly encrypted + try (IpSecTransform inTransform = + transformBuilder.buildTunnelModeTransform(remoteOuter, inSpi); + IpSecTransform outTransform = + transformBuilder.buildTunnelModeTransform(localOuter, outSpi)) { + mISM.applyTunnelModeTransform(tunnelIntf, IpSecManager.DIRECTION_IN, inTransform); + mISM.applyTunnelModeTransform(tunnelIntf, IpSecManager.DIRECTION_OUT, outTransform); - // TODO: Test to ensure that send/receive works with these transforms. + test.run(testNetwork); } - // Check interface was created - NetworkInterface netIntf = NetworkInterface.getByName(tunnelIntf.getInterfaceName()); - assertNotNull(netIntf); - - // Add addresses and check - tunnelIntf.addAddress(inner, innerPrefixLen); - for (InterfaceAddress intfAddr : netIntf.getInterfaceAddresses()) { - assertEquals(intfAddr.getAddress(), inner); - assertEquals(intfAddr.getNetworkPrefixLength(), innerPrefixLen); - } + // Teardown the test network + sTNM.teardownTestNetwork(testNetwork); // Remove addresses and check - tunnelIntf.removeAddress(inner, innerPrefixLen); + tunnelIntf.removeAddress(localInner, innerPrefixLen); + netIntf = NetworkInterface.getByName(tunnelIntf.getInterfaceName()); assertTrue(netIntf.getInterfaceAddresses().isEmpty()); // Check interface was cleaned up tunnelIntf.close(); netIntf = NetworkInterface.getByName(tunnelIntf.getInterfaceName()); assertNull(netIntf); + } finally { + if (testNetworkCb != null) { + sCM.unregisterNetworkCallback(testNetworkCb); + } } } - /* - * Create, add and remove addresses, then teardown tunnel - */ + private static void receiveAndValidatePacket(JavaUdpSocket socket) throws Exception { + byte[] socketResponseBytes = socket.receive(); + assertArrayEquals(TEST_DATA, socketResponseBytes); + } + + private int getRandomSpi(InetAddress localOuter, InetAddress remoteOuter) throws Exception { + // Try to allocate both in and out SPIs using the same requested SPI value. + try (IpSecManager.SecurityParameterIndex inSpi = + mISM.allocateSecurityParameterIndex(localOuter); + IpSecManager.SecurityParameterIndex outSpi = + mISM.allocateSecurityParameterIndex(remoteOuter, inSpi.getSpi()); ) { + return inSpi.getSpi(); + } + } + + private IpHeader getIpHeader(int protocol, InetAddress src, InetAddress dst, Payload payload) { + if ((src instanceof Inet6Address) != (dst instanceof Inet6Address)) { + throw new IllegalArgumentException("Invalid src/dst address combination"); + } + + if (src instanceof Inet6Address) { + return new Ip6Header(protocol, (Inet6Address) src, (Inet6Address) dst, payload); + } else { + return new Ip4Header(protocol, (Inet4Address) src, (Inet4Address) dst, payload); + } + } + + private EspHeader buildTransportModeEspPacket( + int spi, InetAddress src, InetAddress dst, int port, Payload payload) throws Exception { + IpHeader preEspIpHeader = getIpHeader(payload.getProtocolId(), src, dst, payload); + + return new EspHeader( + payload.getProtocolId(), + spi, + 1, // sequence number + CRYPT_KEY, // Same key for auth and crypt + payload.getPacketBytes(preEspIpHeader)); + } + + private EspHeader buildTunnelModeEspPacket( + int spi, + InetAddress srcInner, + InetAddress dstInner, + InetAddress srcOuter, + InetAddress dstOuter, + int port, + int encapPort, + Payload payload) + throws Exception { + IpHeader innerIp = getIpHeader(payload.getProtocolId(), srcInner, dstInner, payload); + return new EspHeader( + innerIp.getProtocolId(), + spi, + 1, // sequence number + CRYPT_KEY, // Same key for auth and crypt + innerIp.getPacketBytes()); + } + + private IpHeader maybeEncapPacket( + InetAddress src, InetAddress dst, int encapPort, EspHeader espPayload) + throws Exception { + + Payload payload = espPayload; + if (encapPort != 0) { + payload = new UdpHeader(encapPort, encapPort, espPayload); + } + + return getIpHeader(payload.getProtocolId(), src, dst, payload); + } + + private byte[] getTunnelModePacket( + int spi, + InetAddress srcInner, + InetAddress dstInner, + InetAddress srcOuter, + InetAddress dstOuter, + int port, + int encapPort) + throws Exception { + UdpHeader udp = new UdpHeader(port, port, new BytePayload(TEST_DATA)); + + EspHeader espPayload = + buildTunnelModeEspPacket( + spi, srcInner, dstInner, srcOuter, dstOuter, port, encapPort, udp); + return maybeEncapPacket(srcOuter, dstOuter, encapPort, espPayload).getPacketBytes(); + } + + private byte[] getTransportInTunnelModePacket( + int spiInner, + int spiOuter, + InetAddress srcInner, + InetAddress dstInner, + InetAddress srcOuter, + InetAddress dstOuter, + int port, + int encapPort) + throws Exception { + UdpHeader udp = new UdpHeader(port, port, new BytePayload(TEST_DATA)); + + EspHeader espPayload = buildTransportModeEspPacket(spiInner, srcInner, dstInner, port, udp); + espPayload = + buildTunnelModeEspPacket( + spiOuter, + srcInner, + dstInner, + srcOuter, + dstOuter, + port, + encapPort, + espPayload); + return maybeEncapPacket(srcOuter, dstOuter, encapPort, espPayload).getPacketBytes(); + } + + // Transport-in-Tunnel mode tests + @Test + public void testTransportInTunnelModeV4InV4() throws Exception { + checkTunnelOutput(AF_INET, AF_INET, false, true); + checkTunnelInput(AF_INET, AF_INET, false, true); + } + + @Test + public void testTransportInTunnelModeV4InV4UdpEncap() throws Exception { + checkTunnelOutput(AF_INET, AF_INET, true, true); + checkTunnelInput(AF_INET, AF_INET, true, true); + } + + @Test + public void testTransportInTunnelModeV4InV6() throws Exception { + checkTunnelOutput(AF_INET, AF_INET6, false, true); + checkTunnelInput(AF_INET, AF_INET6, false, true); + } + + @Test + public void testTransportInTunnelModeV6InV4() throws Exception { + checkTunnelOutput(AF_INET6, AF_INET, false, true); + checkTunnelInput(AF_INET6, AF_INET, false, true); + } + + @Test + public void testTransportInTunnelModeV6InV4UdpEncap() throws Exception { + checkTunnelOutput(AF_INET6, AF_INET, true, true); + checkTunnelInput(AF_INET6, AF_INET, true, true); + } + + @Test + public void testTransportInTunnelModeV6InV6() throws Exception { + checkTunnelOutput(AF_INET, AF_INET6, false, true); + checkTunnelInput(AF_INET, AF_INET6, false, true); + } + + // Tunnel mode tests + @Test public void testTunnelV4InV4() throws Exception { - checkTunnel(INNER_ADDR4, OUTER_ADDR4, false); + checkTunnelOutput(AF_INET, AF_INET, false, false); + checkTunnelInput(AF_INET, AF_INET, false, false); } + @Test public void testTunnelV4InV4UdpEncap() throws Exception { - checkTunnel(INNER_ADDR4, OUTER_ADDR4, true); + checkTunnelOutput(AF_INET, AF_INET, true, false); + checkTunnelInput(AF_INET, AF_INET, true, false); } + @Test public void testTunnelV4InV6() throws Exception { - checkTunnel(INNER_ADDR4, OUTER_ADDR6, false); + checkTunnelOutput(AF_INET, AF_INET6, false, false); + checkTunnelInput(AF_INET, AF_INET6, false, false); } + @Test public void testTunnelV6InV4() throws Exception { - checkTunnel(INNER_ADDR6, OUTER_ADDR4, false); + checkTunnelOutput(AF_INET6, AF_INET, false, false); + checkTunnelInput(AF_INET6, AF_INET, false, false); } + @Test public void testTunnelV6InV4UdpEncap() throws Exception { - checkTunnel(INNER_ADDR6, OUTER_ADDR4, true); + checkTunnelOutput(AF_INET6, AF_INET, true, false); + checkTunnelInput(AF_INET6, AF_INET, true, false); } + @Test public void testTunnelV6InV6() throws Exception { - checkTunnel(INNER_ADDR6, OUTER_ADDR6, false); + checkTunnelOutput(AF_INET6, AF_INET6, false, false); + checkTunnelInput(AF_INET6, AF_INET6, false, false); } } diff --git a/tests/cts/net/src/android/net/cts/TunUtils.java b/tests/cts/net/src/android/net/cts/TunUtils.java index 4d5533fc62..a0307137a5 100644 --- a/tests/cts/net/src/android/net/cts/TunUtils.java +++ b/tests/cts/net/src/android/net/cts/TunUtils.java @@ -247,4 +247,11 @@ public class TunUtils { out.write(pkt); out.flush(); } + + /** Resets the intercepted packets. */ + public void reset() throws IOException { + synchronized (mPackets) { + mPackets.clear(); + } + } } From 2742923a63e47262044994c70388324a46c891e8 Mon Sep 17 00:00:00 2001 From: Benedict Wong Date: Wed, 26 Dec 2018 14:31:42 -0800 Subject: [PATCH 0615/1109] Add TunUtils as utility to reflect packets This patch adds a TunUtils class, allowing for packet capture over a TUN interface, inspection of some basic header fields, and reflection of packets with flipped src/dst headers. Bug: 72950854 Test: Ran, passing Change-Id: I9fdba4a905886c7a4820d86ef52c0cc1843215b2 Merged-In: I9fdba4a905886c7a4820d86ef52c0cc1843215b2 (cherry picked from commit 2f07cd8551d755a4076e94b9e620bc446a66bf54) --- .../src/android/net/cts/IpSecBaseTest.java | 11 + .../src/android/net/cts/IpSecManagerTest.java | 11 - .../cts/net/src/android/net/cts/TunUtils.java | 252 ++++++++++++++++++ 3 files changed, 263 insertions(+), 11 deletions(-) create mode 100644 tests/cts/net/src/android/net/cts/TunUtils.java diff --git a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java index 35d0f485e0..cbb9c195d0 100644 --- a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java @@ -52,6 +52,17 @@ public class IpSecBaseTest extends AndroidTestCase { protected static final int[] DIRECTIONS = new int[] {IpSecManager.DIRECTION_IN, IpSecManager.DIRECTION_OUT}; + protected static final int TCP_HDRLEN_WITH_OPTIONS = 32; + protected static final int UDP_HDRLEN = 8; + protected static final int IP4_HDRLEN = 20; + protected static final int IP6_HDRLEN = 40; + + // Encryption parameters + protected static final int AES_GCM_IV_LEN = 8; + protected static final int AES_CBC_IV_LEN = 16; + protected static final int AES_GCM_BLK_SIZE = 4; + protected static final int AES_CBC_BLK_SIZE = 16; + protected static final byte[] TEST_DATA = "Best test data ever!".getBytes(); protected static final int DATA_BUFFER_LEN = 4096; protected static final int SOCK_TIMEOUT = 500; diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java index 3387064d41..e788d9602f 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java @@ -53,17 +53,6 @@ public class IpSecManagerTest extends IpSecBaseTest { private static final byte[] AEAD_KEY = getKey(288); - private static final int TCP_HDRLEN_WITH_OPTIONS = 32; - private static final int UDP_HDRLEN = 8; - private static final int IP4_HDRLEN = 20; - private static final int IP6_HDRLEN = 40; - - // Encryption parameters - private static final int AES_GCM_IV_LEN = 8; - private static final int AES_CBC_IV_LEN = 16; - private static final int AES_GCM_BLK_SIZE = 4; - private static final int AES_CBC_BLK_SIZE = 16; - protected void setUp() throws Exception { super.setUp(); } diff --git a/tests/cts/net/src/android/net/cts/TunUtils.java b/tests/cts/net/src/android/net/cts/TunUtils.java new file mode 100644 index 0000000000..ca233ce1e8 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/TunUtils.java @@ -0,0 +1,252 @@ +/* + * 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 static android.system.OsConstants.IPPROTO_UDP; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.fail; + +import android.os.ParcelFileDescriptor; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.function.Predicate; + +public class TunUtils { + private static final String TAG = TunUtils.class.getSimpleName(); + + private static final int DATA_BUFFER_LEN = 4096; + private static final int TIMEOUT = 100; + + private static final int IP4_PROTO_OFFSET = 9; + private static final int IP6_PROTO_OFFSET = 6; + + private static final int IP4_ADDR_OFFSET = 12; + private static final int IP4_ADDR_LEN = 4; + private static final int IP6_ADDR_OFFSET = 8; + private static final int IP6_ADDR_LEN = 16; + + // Not defined in OsConstants + private static final int IPPROTO_ESP = 50; + + private final ParcelFileDescriptor mTunFd; + private final List mPackets = new ArrayList<>(); + private final Thread mReaderThread; + + public TunUtils(ParcelFileDescriptor tunFd) { + mTunFd = tunFd; + + // Start background reader thread + mReaderThread = + new Thread( + () -> { + try { + // Loop will exit and thread will quit when tunFd is closed. + // Receiving either EOF or an exception will exit this reader loop. + // FileInputStream in uninterruptable, so there's no good way to + // ensure that this thread shuts down except upon FD closure. + while (true) { + byte[] intercepted = receiveFromTun(); + if (intercepted == null) { + // Exit once we've hit EOF + return; + } else if (intercepted.length > 0) { + // Only save packet if we've received any bytes. + synchronized (mPackets) { + mPackets.add(intercepted); + mPackets.notifyAll(); + } + } + } + } catch (IOException ignored) { + // Simply exit this reader thread + return; + } + }); + mReaderThread.start(); + } + + private byte[] receiveFromTun() throws IOException { + FileInputStream in = new FileInputStream(mTunFd.getFileDescriptor()); + byte[] inBytes = new byte[DATA_BUFFER_LEN]; + int bytesRead = in.read(inBytes); + + if (bytesRead < 0) { + return null; // return null for EOF + } else if (bytesRead >= DATA_BUFFER_LEN) { + throw new IllegalStateException("Too big packet. Fragmentation unsupported"); + } + return Arrays.copyOf(inBytes, bytesRead); + } + + private byte[] getFirstMatchingPacket(Predicate verifier, int startIndex) { + synchronized (mPackets) { + for (int i = startIndex; i < mPackets.size(); i++) { + byte[] pkt = mPackets.get(i); + if (verifier.test(pkt)) { + return pkt; + } + } + } + return null; + } + + /** + * Checks if the specified bytes were ever sent in plaintext. + * + *

    Only checks for known plaintext bytes to prevent triggering on ICMP/RA packets or the like + * + * @param plaintext the plaintext bytes to check for + * @param startIndex the index in the list to check for + */ + public boolean hasPlaintextPacket(byte[] plaintext, int startIndex) { + Predicate verifier = + (pkt) -> { + return Collections.indexOfSubList(Arrays.asList(pkt), Arrays.asList(plaintext)) + != -1; + }; + return getFirstMatchingPacket(verifier, startIndex) != null; + } + + public byte[] getEspPacket(int spi, boolean encap, int startIndex) { + return getFirstMatchingPacket( + (pkt) -> { + return isEsp(pkt, spi, encap); + }, + startIndex); + } + + public byte[] awaitEspPacketNoPlaintext( + int spi, byte[] plaintext, boolean useEncap, int expectedPacketSize) throws Exception { + long endTime = System.currentTimeMillis() + TIMEOUT; + int startIndex = 0; + + synchronized (mPackets) { + while (System.currentTimeMillis() < endTime) { + byte[] espPkt = getEspPacket(spi, useEncap, startIndex); + if (espPkt != null) { + // Validate packet size + assertEquals(expectedPacketSize, espPkt.length); + + // Always check plaintext from start + assertFalse(hasPlaintextPacket(plaintext, 0)); + return espPkt; // We've found the packet we're looking for. + } + + startIndex = mPackets.size(); + + // Try to prevent waiting too long. If waitTimeout <= 0, we've already hit timeout + long waitTimeout = endTime - System.currentTimeMillis(); + if (waitTimeout > 0) { + mPackets.wait(waitTimeout); + } + } + + fail("No such ESP packet found with SPI " + spi); + } + return null; + } + + private static boolean isSpiEqual(byte[] pkt, int espOffset, int spi) { + // Check SPI byte by byte. + return pkt[espOffset] == (byte) ((spi >>> 24) & 0xff) + && pkt[espOffset + 1] == (byte) ((spi >>> 16) & 0xff) + && pkt[espOffset + 2] == (byte) ((spi >>> 8) & 0xff) + && pkt[espOffset + 3] == (byte) (spi & 0xff); + } + + private static boolean isEsp(byte[] pkt, int spi, boolean encap) { + if (isIpv6(pkt)) { + // IPv6 UDP encap not supported by kernels; assume non-encap. + return pkt[IP6_PROTO_OFFSET] == IPPROTO_ESP + && isSpiEqual(pkt, IpSecBaseTest.IP6_HDRLEN, spi); + } else { + // Use default IPv4 header length (assuming no options) + if (encap) { + return pkt[IP4_PROTO_OFFSET] == IPPROTO_UDP + && isSpiEqual( + pkt, IpSecBaseTest.IP4_HDRLEN + IpSecBaseTest.UDP_HDRLEN, spi); + } else { + return pkt[IP4_PROTO_OFFSET] == IPPROTO_ESP + && isSpiEqual(pkt, IpSecBaseTest.IP4_HDRLEN, spi); + } + } + } + + private static boolean isIpv6(byte[] pkt) { + // First nibble shows IP version. 0x60 for IPv6 + return (pkt[0] & (byte) 0xF0) == (byte) 0x60; + } + + private static byte[] getReflectedPacket(byte[] pkt) { + byte[] reflected = Arrays.copyOf(pkt, pkt.length); + + if (isIpv6(pkt)) { + // Set reflected packet's dst to that of the original's src + System.arraycopy( + pkt, // src + IP6_ADDR_OFFSET + IP6_ADDR_LEN, // src offset + reflected, // dst + IP6_ADDR_OFFSET, // dst offset + IP6_ADDR_LEN); // len + // Set reflected packet's src IP to that of the original's dst IP + System.arraycopy( + pkt, // src + IP6_ADDR_OFFSET, // src offset + reflected, // dst + IP6_ADDR_OFFSET + IP6_ADDR_LEN, // dst offset + IP6_ADDR_LEN); // len + } else { + // Set reflected packet's dst to that of the original's src + System.arraycopy( + pkt, // src + IP4_ADDR_OFFSET + IP4_ADDR_LEN, // src offset + reflected, // dst + IP4_ADDR_OFFSET, // dst offset + IP4_ADDR_LEN); // len + // Set reflected packet's src IP to that of the original's dst IP + System.arraycopy( + pkt, // src + IP4_ADDR_OFFSET, // src offset + reflected, // dst + IP4_ADDR_OFFSET + IP4_ADDR_LEN, // dst offset + IP4_ADDR_LEN); // len + } + return reflected; + } + + /** Takes all captured packets, flips the src/dst, and re-injects them. */ + public void reflectPackets() throws IOException { + synchronized (mPackets) { + for (byte[] pkt : mPackets) { + injectPacket(getReflectedPacket(pkt)); + } + } + } + + public void injectPacket(byte[] pkt) throws IOException { + FileOutputStream out = new FileOutputStream(mTunFd.getFileDescriptor()); + out.write(pkt); + out.flush(); + } +} From 2d2a1ab8f7341ba056e622afd98cbcd00501256d Mon Sep 17 00:00:00 2001 From: Benedict Wong Date: Thu, 4 Apr 2019 17:20:38 -0700 Subject: [PATCH 0616/1109] Add utilities to generate packets This change adds utility methods to generate packets incrementally. It supports UDP, ESP, IPv4, IPv6 packet generation. For ESP, it exclusively does AES-CBC, HMAC-SHA256. Bug: 72950854 Test: This Change-Id: Icffeed2ebb2005d79faf04f48fd5126d1d6fb175 Merged-In: Icffeed2ebb2005d79faf04f48fd5126d1d6fb175 (cherry picked from commit 0e4743d56553d698ac45ae548f31019ea6e91541) --- .../src/android/net/cts/IpSecBaseTest.java | 11 - .../src/android/net/cts/IpSecManagerTest.java | 37 +- .../net/src/android/net/cts/PacketUtils.java | 460 ++++++++++++++++++ .../cts/net/src/android/net/cts/TunUtils.java | 16 +- 4 files changed, 483 insertions(+), 41 deletions(-) create mode 100644 tests/cts/net/src/android/net/cts/PacketUtils.java diff --git a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java index cbb9c195d0..35d0f485e0 100644 --- a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java @@ -52,17 +52,6 @@ public class IpSecBaseTest extends AndroidTestCase { protected static final int[] DIRECTIONS = new int[] {IpSecManager.DIRECTION_IN, IpSecManager.DIRECTION_OUT}; - protected static final int TCP_HDRLEN_WITH_OPTIONS = 32; - protected static final int UDP_HDRLEN = 8; - protected static final int IP4_HDRLEN = 20; - protected static final int IP6_HDRLEN = 40; - - // Encryption parameters - protected static final int AES_GCM_IV_LEN = 8; - protected static final int AES_CBC_IV_LEN = 16; - protected static final int AES_GCM_BLK_SIZE = 4; - protected static final int AES_CBC_BLK_SIZE = 16; - protected static final byte[] TEST_DATA = "Best test data ever!".getBytes(); protected static final int DATA_BUFFER_LEN = 4096; protected static final int SOCK_TIMEOUT = 500; diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java index e788d9602f..60d1c03ee2 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java @@ -16,6 +16,14 @@ package android.net.cts; +import static android.net.cts.PacketUtils.AES_CBC_BLK_SIZE; +import static android.net.cts.PacketUtils.AES_CBC_IV_LEN; +import static android.net.cts.PacketUtils.AES_GCM_BLK_SIZE; +import static android.net.cts.PacketUtils.AES_GCM_IV_LEN; +import static android.net.cts.PacketUtils.IP4_HDRLEN; +import static android.net.cts.PacketUtils.IP6_HDRLEN; +import static android.net.cts.PacketUtils.TCP_HDRLEN_WITH_TIMESTAMP_OPT; +import static android.net.cts.PacketUtils.UDP_HDRLEN; import static android.system.OsConstants.IPPROTO_TCP; import static android.system.OsConstants.IPPROTO_UDP; import static org.junit.Assert.assertArrayEquals; @@ -421,19 +429,6 @@ public class IpSecManagerTest extends IpSecBaseTest { } } - /** Helper function to calculate expected ESP packet size. */ - private int calculateEspPacketSize( - int payloadLen, int cryptIvLength, int cryptBlockSize, int authTruncLen) { - final int ESP_HDRLEN = 4 + 4; // SPI + Seq# - final int ICV_LEN = authTruncLen / 8; // Auth trailer; based on truncation length - payloadLen += cryptIvLength; // Initialization Vector - payloadLen += 2; // ESP trailer - - // Align to block size of encryption algorithm - payloadLen += (cryptBlockSize - (payloadLen % cryptBlockSize)) % cryptBlockSize; - return payloadLen + ESP_HDRLEN + ICV_LEN; - } - public void checkTransform( int protocol, String localAddress, @@ -474,7 +469,7 @@ public class IpSecManagerTest extends IpSecBaseTest { try (IpSecTransform transform = transformBuilder.buildTransportModeTransform(local, spi)) { if (protocol == IPPROTO_TCP) { - transportHdrLen = TCP_HDRLEN_WITH_OPTIONS; + transportHdrLen = TCP_HDRLEN_WITH_TIMESTAMP_OPT; checkTcp(transform, local, sendCount, useJavaSockets); } else if (protocol == IPPROTO_UDP) { transportHdrLen = UDP_HDRLEN; @@ -511,7 +506,7 @@ public class IpSecManagerTest extends IpSecBaseTest { int innerPacketSize = TEST_DATA.length + transportHdrLen + ipHdrLen; int outerPacketSize = - calculateEspPacketSize( + PacketUtils.calculateEspPacketSize( TEST_DATA.length + transportHdrLen, ivLen, blkSize, truncLenBits) + udpEncapLen + ipHdrLen; @@ -529,13 +524,13 @@ public class IpSecManagerTest extends IpSecBaseTest { // Add TCP ACKs for data packets if (protocol == IPPROTO_TCP) { int encryptedTcpPktSize = - calculateEspPacketSize(TCP_HDRLEN_WITH_OPTIONS, ivLen, blkSize, truncLenBits); + PacketUtils.calculateEspPacketSize( + TCP_HDRLEN_WITH_TIMESTAMP_OPT, ivLen, blkSize, truncLenBits); - - // Add data packet ACKs - expectedOuterBytes += (encryptedTcpPktSize + udpEncapLen + ipHdrLen) * (sendCount); - expectedInnerBytes += (TCP_HDRLEN_WITH_OPTIONS + ipHdrLen) * (sendCount); - expectedPackets += sendCount; + // Add data packet ACKs + expectedOuterBytes += (encryptedTcpPktSize + udpEncapLen + ipHdrLen) * (sendCount); + expectedInnerBytes += (TCP_HDRLEN_WITH_TIMESTAMP_OPT + ipHdrLen) * (sendCount); + expectedPackets += sendCount; } StatsChecker.waitForNumPackets(expectedPackets); diff --git a/tests/cts/net/src/android/net/cts/PacketUtils.java b/tests/cts/net/src/android/net/cts/PacketUtils.java new file mode 100644 index 0000000000..6177827ba6 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/PacketUtils.java @@ -0,0 +1,460 @@ +/* + * 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 static android.system.OsConstants.IPPROTO_IPV6; +import static android.system.OsConstants.IPPROTO_UDP; + +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.nio.ByteBuffer; +import java.nio.ShortBuffer; +import java.security.GeneralSecurityException; +import java.security.SecureRandom; +import java.util.Arrays; +import javax.crypto.Cipher; +import javax.crypto.Mac; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +public class PacketUtils { + private static final String TAG = PacketUtils.class.getSimpleName(); + + private static final int DATA_BUFFER_LEN = 4096; + + static final int IP4_HDRLEN = 20; + static final int IP6_HDRLEN = 40; + static final int UDP_HDRLEN = 8; + static final int TCP_HDRLEN = 20; + static final int TCP_HDRLEN_WITH_TIMESTAMP_OPT = TCP_HDRLEN + 12; + + // Not defined in OsConstants + static final int IPPROTO_IPV4 = 4; + static final int IPPROTO_ESP = 50; + + // Encryption parameters + static final int AES_GCM_IV_LEN = 8; + static final int AES_CBC_IV_LEN = 16; + static final int AES_GCM_BLK_SIZE = 4; + static final int AES_CBC_BLK_SIZE = 16; + + // Encryption algorithms + static final String AES = "AES"; + static final String AES_CBC = "AES/CBC/NoPadding"; + static final String HMAC_SHA_256 = "HmacSHA256"; + + public interface Payload { + byte[] getPacketBytes(IpHeader header) throws Exception; + + void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) throws Exception; + + short length(); + + int getProtocolId(); + } + + public abstract static class IpHeader { + + public final byte proto; + public final InetAddress srcAddr; + public final InetAddress dstAddr; + public final Payload payload; + + public IpHeader(int proto, InetAddress src, InetAddress dst, Payload payload) { + this.proto = (byte) proto; + this.srcAddr = src; + this.dstAddr = dst; + this.payload = payload; + } + + public abstract byte[] getPacketBytes() throws Exception; + + public abstract int getProtocolId(); + } + + public static class Ip4Header extends IpHeader { + private short checksum; + + public Ip4Header(int proto, Inet4Address src, Inet4Address dst, Payload payload) { + super(proto, src, dst, payload); + } + + public byte[] getPacketBytes() throws Exception { + ByteBuffer resultBuffer = buildHeader(); + payload.addPacketBytes(this, resultBuffer); + + return getByteArrayFromBuffer(resultBuffer); + } + + public ByteBuffer buildHeader() { + ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN); + + // Version, IHL + bb.put((byte) (0x45)); + + // DCSP, ECN + bb.put((byte) 0); + + // Total Length + bb.putShort((short) (IP4_HDRLEN + payload.length())); + + // Empty for Identification, Flags and Fragment Offset + bb.putShort((short) 0); + bb.put((byte) 0x40); + bb.put((byte) 0x00); + + // TTL + bb.put((byte) 64); + + // Protocol + bb.put(proto); + + // Header Checksum + final int ipChecksumOffset = bb.position(); + bb.putShort((short) 0); + + // Src/Dst addresses + bb.put(srcAddr.getAddress()); + bb.put(dstAddr.getAddress()); + + bb.putShort(ipChecksumOffset, calculateChecksum(bb)); + + return bb; + } + + private short calculateChecksum(ByteBuffer bb) { + int checksum = 0; + + // Calculate sum of 16-bit values, excluding checksum. IPv4 headers are always 32-bit + // aligned, so no special cases needed for unaligned values. + ShortBuffer shortBuffer = ByteBuffer.wrap(getByteArrayFromBuffer(bb)).asShortBuffer(); + while (shortBuffer.hasRemaining()) { + short val = shortBuffer.get(); + + // Wrap as needed + checksum = addAndWrapForChecksum(checksum, val); + } + + return onesComplement(checksum); + } + + public int getProtocolId() { + return IPPROTO_IPV4; + } + } + + public static class Ip6Header extends IpHeader { + public Ip6Header(int nextHeader, Inet6Address src, Inet6Address dst, Payload payload) { + super(nextHeader, src, dst, payload); + } + + public byte[] getPacketBytes() throws Exception { + ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN); + + // Version | Traffic Class (First 4 bits) + bb.put((byte) 0x60); + + // Traffic class (Last 4 bits), Flow Label + bb.put((byte) 0); + bb.put((byte) 0); + bb.put((byte) 0); + + // Payload Length + bb.putShort((short) payload.length()); + + // Next Header + bb.put(proto); + + // Hop Limit + bb.put((byte) 64); + + // Src/Dst addresses + bb.put(srcAddr.getAddress()); + bb.put(dstAddr.getAddress()); + + // Payload + payload.addPacketBytes(this, bb); + + return getByteArrayFromBuffer(bb); + } + + public int getProtocolId() { + return IPPROTO_IPV6; + } + } + + public static class BytePayload implements Payload { + public final byte[] payload; + + public BytePayload(byte[] payload) { + this.payload = payload; + } + + public int getProtocolId() { + return -1; + } + + public byte[] getPacketBytes(IpHeader header) { + ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN); + + addPacketBytes(header, bb); + return getByteArrayFromBuffer(bb); + } + + public void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) { + resultBuffer.put(payload); + } + + public short length() { + return (short) payload.length; + } + } + + public static class UdpHeader implements Payload { + + public final short srcPort; + public final short dstPort; + public final Payload payload; + + public UdpHeader(int srcPort, int dstPort, Payload payload) { + this.srcPort = (short) srcPort; + this.dstPort = (short) dstPort; + this.payload = payload; + } + + public int getProtocolId() { + return IPPROTO_UDP; + } + + public short length() { + return (short) (payload.length() + 8); + } + + public byte[] getPacketBytes(IpHeader header) throws Exception { + ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN); + + addPacketBytes(header, bb); + return getByteArrayFromBuffer(bb); + } + + public void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) throws Exception { + // Source, Destination port + resultBuffer.putShort(srcPort); + resultBuffer.putShort(dstPort); + + // Payload Length + resultBuffer.putShort(length()); + + // Get payload bytes for checksum + payload + ByteBuffer payloadBuffer = ByteBuffer.allocate(DATA_BUFFER_LEN); + payload.addPacketBytes(header, payloadBuffer); + byte[] payloadBytes = getByteArrayFromBuffer(payloadBuffer); + + // Checksum + resultBuffer.putShort(calculateChecksum(header, payloadBytes)); + + // Payload + resultBuffer.put(payloadBytes); + } + + private short calculateChecksum(IpHeader header, byte[] payloadBytes) throws Exception { + int newChecksum = 0; + ShortBuffer srcBuffer = ByteBuffer.wrap(header.srcAddr.getAddress()).asShortBuffer(); + ShortBuffer dstBuffer = ByteBuffer.wrap(header.dstAddr.getAddress()).asShortBuffer(); + + while (srcBuffer.hasRemaining() || dstBuffer.hasRemaining()) { + short val = srcBuffer.hasRemaining() ? srcBuffer.get() : dstBuffer.get(); + + // Wrap as needed + newChecksum = addAndWrapForChecksum(newChecksum, val); + } + + // Add pseudo-header values. Proto is 0-padded, so just use the byte. + newChecksum = addAndWrapForChecksum(newChecksum, header.proto); + newChecksum = addAndWrapForChecksum(newChecksum, length()); + newChecksum = addAndWrapForChecksum(newChecksum, srcPort); + newChecksum = addAndWrapForChecksum(newChecksum, dstPort); + newChecksum = addAndWrapForChecksum(newChecksum, length()); + + ShortBuffer payloadShortBuffer = ByteBuffer.wrap(payloadBytes).asShortBuffer(); + while (payloadShortBuffer.hasRemaining()) { + newChecksum = addAndWrapForChecksum(newChecksum, payloadShortBuffer.get()); + } + if (payload.length() % 2 != 0) { + newChecksum = + addAndWrapForChecksum( + newChecksum, (payloadBytes[payloadBytes.length - 1] << 8)); + } + + return onesComplement(newChecksum); + } + } + + public static class EspHeader implements Payload { + public final int nextHeader; + public final int spi; + public final int seqNum; + public final byte[] key; + public final byte[] payload; + + /** + * Generic constructor for ESP headers. + * + *

    For Tunnel mode, payload will be a full IP header + attached payloads + * + *

    For Transport mode, payload will be only the attached payloads, but with the checksum + * calculated using the pre-encryption IP header + */ + public EspHeader(int nextHeader, int spi, int seqNum, byte[] key, byte[] payload) { + this.nextHeader = nextHeader; + this.spi = spi; + this.seqNum = seqNum; + this.key = key; + this.payload = payload; + } + + public int getProtocolId() { + return IPPROTO_ESP; + } + + public short length() { + // ALWAYS uses AES-CBC, HMAC-SHA256 (128b trunc len) + return (short) + calculateEspPacketSize(payload.length, AES_CBC_IV_LEN, AES_CBC_BLK_SIZE, 128); + } + + public byte[] getPacketBytes(IpHeader header) throws Exception { + ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN); + + addPacketBytes(header, bb); + return getByteArrayFromBuffer(bb); + } + + public void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) throws Exception { + ByteBuffer espPayloadBuffer = ByteBuffer.allocate(DATA_BUFFER_LEN); + espPayloadBuffer.putInt(spi); + espPayloadBuffer.putInt(seqNum); + espPayloadBuffer.put(getCiphertext(key)); + + espPayloadBuffer.put(getIcv(getByteArrayFromBuffer(espPayloadBuffer)), 0, 16); + resultBuffer.put(getByteArrayFromBuffer(espPayloadBuffer)); + } + + private byte[] getIcv(byte[] authenticatedSection) throws GeneralSecurityException { + Mac sha256HMAC = Mac.getInstance(HMAC_SHA_256); + SecretKeySpec authKey = new SecretKeySpec(key, HMAC_SHA_256); + sha256HMAC.init(authKey); + + return sha256HMAC.doFinal(authenticatedSection); + } + + /** + * Encrypts and builds ciphertext block. Includes the IV, Padding and Next-Header blocks + * + *

    The ciphertext does NOT include the SPI/Sequence numbers, or the ICV. + */ + private byte[] getCiphertext(byte[] key) throws GeneralSecurityException { + int paddedLen = calculateEspEncryptedLength(payload.length, AES_CBC_BLK_SIZE); + ByteBuffer paddedPayload = ByteBuffer.allocate(paddedLen); + paddedPayload.put(payload); + + // Add padding - consecutive integers from 0x01 + int pad = 1; + while (paddedPayload.position() < paddedPayload.limit()) { + paddedPayload.put((byte) pad++); + } + + paddedPayload.position(paddedPayload.limit() - 2); + paddedPayload.put((byte) (paddedLen - 2 - payload.length)); // Pad length + paddedPayload.put((byte) nextHeader); + + // Generate Initialization Vector + byte[] iv = new byte[AES_CBC_IV_LEN]; + new SecureRandom().nextBytes(iv); + IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); + SecretKeySpec secretKeySpec = new SecretKeySpec(key, AES); + + // Encrypt payload + Cipher cipher = Cipher.getInstance(AES_CBC); + cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); + byte[] encrypted = cipher.doFinal(getByteArrayFromBuffer(paddedPayload)); + + // Build ciphertext + ByteBuffer cipherText = ByteBuffer.allocate(AES_CBC_IV_LEN + encrypted.length); + cipherText.put(iv); + cipherText.put(encrypted); + + return getByteArrayFromBuffer(cipherText); + } + } + + private static int addAndWrapForChecksum(int currentChecksum, int value) { + currentChecksum += value & 0x0000ffff; + + // Wrap anything beyond the first 16 bits, and add to lower order bits + return (currentChecksum >>> 16) + (currentChecksum & 0x0000ffff); + } + + private static short onesComplement(int val) { + val = (val >>> 16) + (val & 0xffff); + + if (val == 0) return 0; + return (short) ((~val) & 0xffff); + } + + public static int calculateEspPacketSize( + int payloadLen, int cryptIvLength, int cryptBlockSize, int authTruncLen) { + final int ESP_HDRLEN = 4 + 4; // SPI + Seq# + final int ICV_LEN = authTruncLen / 8; // Auth trailer; based on truncation length + payloadLen += cryptIvLength; // Initialization Vector + + // Align to block size of encryption algorithm + payloadLen = calculateEspEncryptedLength(payloadLen, cryptBlockSize); + return payloadLen + ESP_HDRLEN + ICV_LEN; + } + + private static int calculateEspEncryptedLength(int payloadLen, int cryptBlockSize) { + payloadLen += 2; // ESP trailer + + // Align to block size of encryption algorithm + return payloadLen + calculateEspPadLen(payloadLen, cryptBlockSize); + } + + private static int calculateEspPadLen(int payloadLen, int cryptBlockSize) { + return (cryptBlockSize - (payloadLen % cryptBlockSize)) % cryptBlockSize; + } + + private static byte[] getByteArrayFromBuffer(ByteBuffer buffer) { + return Arrays.copyOfRange(buffer.array(), 0, buffer.position()); + } + + /* + * Debug printing + */ + private static final char[] hexArray = "0123456789ABCDEF".toCharArray(); + + public static String bytesToHex(byte[] bytes) { + StringBuilder sb = new StringBuilder(); + for (byte b : bytes) { + sb.append(hexArray[b >>> 4]); + sb.append(hexArray[b & 0x0F]); + sb.append(' '); + } + return sb.toString(); + } +} diff --git a/tests/cts/net/src/android/net/cts/TunUtils.java b/tests/cts/net/src/android/net/cts/TunUtils.java index ca233ce1e8..4d5533fc62 100644 --- a/tests/cts/net/src/android/net/cts/TunUtils.java +++ b/tests/cts/net/src/android/net/cts/TunUtils.java @@ -16,6 +16,10 @@ package android.net.cts; +import static android.net.cts.PacketUtils.IP4_HDRLEN; +import static android.net.cts.PacketUtils.IP6_HDRLEN; +import static android.net.cts.PacketUtils.IPPROTO_ESP; +import static android.net.cts.PacketUtils.UDP_HDRLEN; import static android.system.OsConstants.IPPROTO_UDP; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -46,9 +50,6 @@ public class TunUtils { private static final int IP6_ADDR_OFFSET = 8; private static final int IP6_ADDR_LEN = 16; - // Not defined in OsConstants - private static final int IPPROTO_ESP = 50; - private final ParcelFileDescriptor mTunFd; private final List mPackets = new ArrayList<>(); private final Thread mReaderThread; @@ -178,17 +179,14 @@ public class TunUtils { private static boolean isEsp(byte[] pkt, int spi, boolean encap) { if (isIpv6(pkt)) { // IPv6 UDP encap not supported by kernels; assume non-encap. - return pkt[IP6_PROTO_OFFSET] == IPPROTO_ESP - && isSpiEqual(pkt, IpSecBaseTest.IP6_HDRLEN, spi); + return pkt[IP6_PROTO_OFFSET] == IPPROTO_ESP && isSpiEqual(pkt, IP6_HDRLEN, spi); } else { // Use default IPv4 header length (assuming no options) if (encap) { return pkt[IP4_PROTO_OFFSET] == IPPROTO_UDP - && isSpiEqual( - pkt, IpSecBaseTest.IP4_HDRLEN + IpSecBaseTest.UDP_HDRLEN, spi); + && isSpiEqual(pkt, IP4_HDRLEN + UDP_HDRLEN, spi); } else { - return pkt[IP4_PROTO_OFFSET] == IPPROTO_ESP - && isSpiEqual(pkt, IpSecBaseTest.IP4_HDRLEN, spi); + return pkt[IP4_PROTO_OFFSET] == IPPROTO_ESP && isSpiEqual(pkt, IP4_HDRLEN, spi); } } } From 817d192bc4399ab5f457eaf8c604977e9017ec25 Mon Sep 17 00:00:00 2001 From: Benedict Wong Date: Mon, 8 Apr 2019 10:15:26 -0700 Subject: [PATCH 0617/1109] Add IPsec Tunnel mode data tests This change adds single-direction tests for the IPsec Tunnel Mode API. In the outbound direction, TUNs are used to capture outgoing packets, and values are inspected. In the inbound direction, packets are built manually, using the PacketUtils framework. Additional testing for end-to-end integration tests will follow in aosp/941021 using packet reflection via the TUN. Bug: 72950854 Test: This; passing Change-Id: Ic4181fc857fa880db5553314efa914f870dbe87c Merged-In: Ic4181fc857fa880db5553314efa914f870dbe87c (cherry picked from commit d708a4c217f13c9028427d98031394f0933482bf) --- .../src/android/net/cts/IpSecBaseTest.java | 43 +- .../net/cts/IpSecManagerTunnelTest.java | 694 ++++++++++++++++-- .../cts/net/src/android/net/cts/TunUtils.java | 7 + 3 files changed, 661 insertions(+), 83 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java index 35d0f485e0..087dbdaec3 100644 --- a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java @@ -28,11 +28,12 @@ import android.system.OsConstants; import android.test.AndroidTestCase; import android.util.Log; +import androidx.test.InstrumentationRegistry; + import java.io.FileDescriptor; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; -import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.InetSocketAddress; @@ -72,8 +73,14 @@ public class IpSecBaseTest extends AndroidTestCase { protected void setUp() throws Exception { super.setUp(); - mISM = (IpSecManager) getContext().getSystemService(Context.IPSEC_SERVICE); - mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); + mISM = + (IpSecManager) + InstrumentationRegistry.getContext() + .getSystemService(Context.IPSEC_SERVICE); + mCM = + (ConnectivityManager) + InstrumentationRegistry.getContext() + .getSystemService(Context.CONNECTIVITY_SERVICE); } protected static byte[] getKey(int bitLength) { @@ -195,6 +202,17 @@ public class IpSecBaseTest extends AndroidTestCase { public static class JavaUdpSocket implements GenericUdpSocket { public final DatagramSocket mSocket; + public JavaUdpSocket(InetAddress localAddr, int port) { + try { + mSocket = new DatagramSocket(port, localAddr); + mSocket.setSoTimeout(SOCK_TIMEOUT); + } catch (SocketException e) { + // Fail loudly if we can't set up sockets properly. And without the timeout, we + // could easily end up in an endless wait. + throw new RuntimeException(e); + } + } + public JavaUdpSocket(InetAddress localAddr) { try { mSocket = new DatagramSocket(0, localAddr); @@ -425,26 +443,25 @@ public class IpSecBaseTest extends AndroidTestCase { } protected static IpSecTransform buildIpSecTransform( - Context mContext, + Context context, IpSecManager.SecurityParameterIndex spi, IpSecManager.UdpEncapsulationSocket encapSocket, InetAddress remoteAddr) throws Exception { - String localAddr = (remoteAddr instanceof Inet4Address) ? IPV4_LOOPBACK : IPV6_LOOPBACK; IpSecTransform.Builder builder = - new IpSecTransform.Builder(mContext) - .setEncryption(new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY)) - .setAuthentication( - new IpSecAlgorithm( - IpSecAlgorithm.AUTH_HMAC_SHA256, - AUTH_KEY, - AUTH_KEY.length * 4)); + new IpSecTransform.Builder(context) + .setEncryption(new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY)) + .setAuthentication( + new IpSecAlgorithm( + IpSecAlgorithm.AUTH_HMAC_SHA256, + AUTH_KEY, + AUTH_KEY.length * 4)); if (encapSocket != null) { builder.setIpv4Encapsulation(encapSocket, encapSocket.getPort()); } - return builder.buildTransportModeTransform(InetAddress.getByName(localAddr), spi); + return builder.buildTransportModeTransform(remoteAddr, spi); } private IpSecTransform buildDefaultTransform(InetAddress localAddr) throws Exception { diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java index c8c99f4a37..e8c0a7a4b2 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java @@ -16,174 +16,728 @@ package android.net.cts; +import static android.app.AppOpsManager.OP_MANAGE_IPSEC_TUNNELS; +import static android.net.IpSecManager.UdpEncapsulationSocket; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; +import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED; +import static android.net.NetworkCapabilities.TRANSPORT_TEST; +import static android.net.cts.PacketUtils.AES_CBC_BLK_SIZE; +import static android.net.cts.PacketUtils.AES_CBC_IV_LEN; +import static android.net.cts.PacketUtils.BytePayload; +import static android.net.cts.PacketUtils.EspHeader; +import static android.net.cts.PacketUtils.IP4_HDRLEN; +import static android.net.cts.PacketUtils.IP6_HDRLEN; +import static android.net.cts.PacketUtils.Ip4Header; +import static android.net.cts.PacketUtils.Ip6Header; +import static android.net.cts.PacketUtils.IpHeader; +import static android.net.cts.PacketUtils.UDP_HDRLEN; +import static android.net.cts.PacketUtils.UdpHeader; +import static android.system.OsConstants.AF_INET; +import static android.system.OsConstants.AF_INET6; + +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import android.app.AppOpsManager; +import android.content.Context; import android.content.pm.PackageManager; +import android.net.ConnectivityManager; import android.net.IpSecAlgorithm; import android.net.IpSecManager; import android.net.IpSecTransform; +import android.net.LinkAddress; import android.net.Network; +import android.net.NetworkRequest; +import android.net.TestNetworkInterface; +import android.net.TestNetworkManager; +import android.net.cts.PacketUtils.Payload; +import android.os.Binder; +import android.os.IBinder; +import android.os.ParcelFileDescriptor; + +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; import com.android.compatibility.common.util.SystemUtil; +import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.InterfaceAddress; import java.net.NetworkInterface; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) public class IpSecManagerTunnelTest extends IpSecBaseTest { - private static final String TAG = IpSecManagerTunnelTest.class.getSimpleName(); - private static final int IP4_PREFIX_LEN = 24; - private static final int IP6_PREFIX_LEN = 48; - private static final InetAddress OUTER_ADDR4 = InetAddress.parseNumericAddress("192.0.2.0"); - private static final InetAddress OUTER_ADDR6 = - InetAddress.parseNumericAddress("2001:db8:f00d::1"); - private static final InetAddress INNER_ADDR4 = InetAddress.parseNumericAddress("10.0.0.1"); - private static final InetAddress INNER_ADDR6 = - InetAddress.parseNumericAddress("2001:db8:d00d::1"); - private Network mUnderlyingNetwork; - private Network mIpSecNetwork; + private static final InetAddress LOCAL_OUTER_4 = InetAddress.parseNumericAddress("192.0.2.1"); + private static final InetAddress REMOTE_OUTER_4 = InetAddress.parseNumericAddress("192.0.2.2"); + private static final InetAddress LOCAL_OUTER_6 = + InetAddress.parseNumericAddress("2001:db8:1::1"); + private static final InetAddress REMOTE_OUTER_6 = + InetAddress.parseNumericAddress("2001:db8:1::2"); - protected void setUp() throws Exception { + private static final InetAddress LOCAL_INNER_4 = + InetAddress.parseNumericAddress("198.51.100.1"); + private static final InetAddress REMOTE_INNER_4 = + InetAddress.parseNumericAddress("198.51.100.2"); + private static final InetAddress LOCAL_INNER_6 = + InetAddress.parseNumericAddress("2001:db8:2::1"); + private static final InetAddress REMOTE_INNER_6 = + InetAddress.parseNumericAddress("2001:db8:2::2"); + + private static final int IP4_PREFIX_LEN = 32; + private static final int IP6_PREFIX_LEN = 128; + + private static final int TIMEOUT_MS = 500; + + // Static state to reduce setup/teardown + private static ConnectivityManager sCM; + private static TestNetworkManager sTNM; + private static ParcelFileDescriptor sTunFd; + private static TestNetworkCallback sTunNetworkCallback; + private static Network sTunNetwork; + private static TunUtils sTunUtils; + + private static Context sContext = InstrumentationRegistry.getContext(); + private static IBinder sBinder = new Binder(); + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .adoptShellPermissionIdentity(); + sCM = (ConnectivityManager) sContext.getSystemService(Context.CONNECTIVITY_SERVICE); + sTNM = (TestNetworkManager) sContext.getSystemService(Context.TEST_NETWORK_SERVICE); + + // 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 + // right appop permissions. + setAppop(OP_MANAGE_IPSEC_TUNNELS, true); + + TestNetworkInterface testIntf = + sTNM.createTunInterface( + new LinkAddress[] { + new LinkAddress(LOCAL_OUTER_4, IP4_PREFIX_LEN), + new LinkAddress(LOCAL_OUTER_6, IP6_PREFIX_LEN) + }); + + sTunFd = testIntf.getFileDescriptor(); + sTunNetworkCallback = setupAndGetTestNetwork(testIntf.getInterfaceName()); + sTunNetwork = sTunNetworkCallback.getNetworkBlocking(); + + sTunUtils = new TunUtils(sTunFd); + } + + @Before + public void setUp() throws Exception { super.setUp(); + + // Set to true before every run; some tests flip this. + setAppop(OP_MANAGE_IPSEC_TUNNELS, true); + + // Clear sTunUtils state + sTunUtils.reset(); } - protected void tearDown() { - setAppop(false); + @AfterClass + public static void tearDownAfterClass() throws Exception { + setAppop(OP_MANAGE_IPSEC_TUNNELS, false); + + sCM.unregisterNetworkCallback(sTunNetworkCallback); + + sTNM.teardownTestNetwork(sTunNetwork); + sTunFd.close(); + + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .dropShellPermissionIdentity(); } - private boolean hasTunnelsFeature() { - return getContext() - .getPackageManager() - .hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS); + private static boolean hasTunnelsFeature() { + return sContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS); } - private void setAppop(boolean allow) { - // Under normal circumstances, the MANAGE_IPSEC_TUNNELS appop would be auto-granted by the - // telephony framework, and the only permission that is sufficient is NETWORK_STACK. So we - // shell out the appop manager, to give us the right appop permissions. - String cmd = - "appops set " - + mContext.getPackageName() - + " MANAGE_IPSEC_TUNNELS " - + (allow ? "allow" : "deny"); - SystemUtil.runShellCommand(cmd); + private static void setAppop(int appop, boolean allow) { + String opName = AppOpsManager.opToName(appop); + for (String pkg : new String[] {"com.android.shell", sContext.getPackageName()}) { + String cmd = + String.format( + "appops set %s %s %s", + pkg, // Package name + opName, // Appop + (allow ? "allow" : "deny")); // Action + SystemUtil.runShellCommand(cmd); + } } - public void testSecurityExceptionsCreateTunnelInterface() throws Exception { + private static TestNetworkCallback setupAndGetTestNetwork(String ifname) throws Exception { + // Build a network request + NetworkRequest nr = + new NetworkRequest.Builder() + .addTransportType(TRANSPORT_TEST) + .removeCapability(NET_CAPABILITY_TRUSTED) + .removeCapability(NET_CAPABILITY_NOT_VPN) + .setNetworkSpecifier(ifname) + .build(); + + TestNetworkCallback cb = new TestNetworkCallback(); + sCM.requestNetwork(nr, cb); + + // Setup the test network after network request is filed to prevent Network from being + // reaped due to no requests matching it. + sTNM.setupTestNetwork(ifname, sBinder); + + return cb; + } + + @Test + public void testSecurityExceptionCreateTunnelInterfaceWithoutAppop() throws Exception { if (!hasTunnelsFeature()) return; // Ensure we don't have the appop. Permission is not requested in the Manifest - setAppop(false); + setAppop(OP_MANAGE_IPSEC_TUNNELS, false); // Security exceptions are thrown regardless of IPv4/IPv6. Just test one try { - mISM.createIpSecTunnelInterface(OUTER_ADDR6, OUTER_ADDR6, mUnderlyingNetwork); + mISM.createIpSecTunnelInterface(LOCAL_INNER_6, REMOTE_INNER_6, sTunNetwork); fail("Did not throw SecurityException for Tunnel creation without appop"); } catch (SecurityException expected) { } } - public void testSecurityExceptionsBuildTunnelTransform() throws Exception { + @Test + public void testSecurityExceptionBuildTunnelTransformWithoutAppop() throws Exception { if (!hasTunnelsFeature()) return; // Ensure we don't have the appop. Permission is not requested in the Manifest - setAppop(false); + setAppop(OP_MANAGE_IPSEC_TUNNELS, false); // Security exceptions are thrown regardless of IPv4/IPv6. Just test one try (IpSecManager.SecurityParameterIndex spi = - mISM.allocateSecurityParameterIndex(OUTER_ADDR4); + mISM.allocateSecurityParameterIndex(LOCAL_INNER_4); IpSecTransform transform = - new IpSecTransform.Builder(mContext) - .buildTunnelModeTransform(OUTER_ADDR4, spi)) { + new IpSecTransform.Builder(sContext) + .buildTunnelModeTransform(REMOTE_INNER_4, spi)) { fail("Did not throw SecurityException for Transform creation without appop"); } catch (SecurityException expected) { } } - private void checkTunnel(InetAddress inner, InetAddress outer, boolean useEncap) + /* Test runnables for callbacks after IPsec tunnels are set up. */ + private interface TestRunnable { + void run(Network ipsecNetwork) throws Exception; + } + + private static class TestNetworkCallback extends ConnectivityManager.NetworkCallback { + private final CompletableFuture futureNetwork = new CompletableFuture<>(); + + @Override + public void onAvailable(Network network) { + futureNetwork.complete(network); + } + + public Network getNetworkBlocking() throws Exception { + return futureNetwork.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); + } + } + + private int getPacketSize( + int innerFamily, int outerFamily, boolean useEncap, boolean transportInTunnelMode) { + int expectedPacketSize = TEST_DATA.length + UDP_HDRLEN; + + // Inner Transport mode packet size + if (transportInTunnelMode) { + expectedPacketSize = + PacketUtils.calculateEspPacketSize( + expectedPacketSize, + AES_CBC_IV_LEN, + AES_CBC_BLK_SIZE, + AUTH_KEY.length * 4); + } + + // Inner IP Header + expectedPacketSize += innerFamily == AF_INET ? IP4_HDRLEN : IP6_HDRLEN; + + // Tunnel mode transform size + expectedPacketSize = + PacketUtils.calculateEspPacketSize( + expectedPacketSize, AES_CBC_IV_LEN, AES_CBC_BLK_SIZE, AUTH_KEY.length * 4); + + // UDP encap size + expectedPacketSize += useEncap ? UDP_HDRLEN : 0; + + // Outer IP Header + expectedPacketSize += outerFamily == AF_INET ? IP4_HDRLEN : IP6_HDRLEN; + + return expectedPacketSize; + } + + private interface TestRunnableFactory { + TestRunnable getTestRunnable( + boolean transportInTunnelMode, + int spi, + InetAddress localInner, + InetAddress remoteInner, + InetAddress localOuter, + InetAddress remoteOuter, + IpSecTransform inTransportTransform, + IpSecTransform outTransportTransform, + int encapPort, + int expectedPacketSize) + throws Exception; + } + + private class OutputTestRunnableFactory implements TestRunnableFactory { + public TestRunnable getTestRunnable( + boolean transportInTunnelMode, + int spi, + InetAddress localInner, + InetAddress remoteInner, + InetAddress localOuter, + InetAddress remoteOuter, + IpSecTransform inTransportTransform, + IpSecTransform outTransportTransform, + int encapPort, + int expectedPacketSize) { + return new TestRunnable() { + @Override + public void run(Network ipsecNetwork) throws Exception { + // Build a socket and send traffic + JavaUdpSocket socket = new JavaUdpSocket(localInner); + ipsecNetwork.bindSocket(socket.mSocket); + + // For Transport-In-Tunnel mode, apply transform to socket + if (transportInTunnelMode) { + mISM.applyTransportModeTransform( + socket.mSocket, IpSecManager.DIRECTION_IN, inTransportTransform); + mISM.applyTransportModeTransform( + socket.mSocket, IpSecManager.DIRECTION_OUT, outTransportTransform); + } + + socket.sendTo(TEST_DATA, remoteInner, socket.getPort()); + + // Verify that an encrypted packet is sent. As of right now, checking encrypted + // body is not possible, due to our not knowing some of the fields of the + // inner IP header (flow label, flags, etc) + sTunUtils.awaitEspPacketNoPlaintext( + spi, TEST_DATA, encapPort != 0, expectedPacketSize); + + socket.close(); + } + }; + } + } + + private class InputPacketGeneratorTestRunnableFactory implements TestRunnableFactory { + public TestRunnable getTestRunnable( + boolean transportInTunnelMode, + int spi, + InetAddress localInner, + InetAddress remoteInner, + InetAddress localOuter, + InetAddress remoteOuter, + IpSecTransform inTransportTransform, + IpSecTransform outTransportTransform, + int encapPort, + int expectedPacketSize) + throws Exception { + return new TestRunnable() { + @Override + public void run(Network ipsecNetwork) throws Exception { + // Build a socket and receive traffic + JavaUdpSocket socket = new JavaUdpSocket(localInner); + // JavaUdpSocket socket = new JavaUdpSocket(localInner, socketPort.get()); + ipsecNetwork.bindSocket(socket.mSocket); + + // For Transport-In-Tunnel mode, apply transform to socket + if (transportInTunnelMode) { + mISM.applyTransportModeTransform( + socket.mSocket, IpSecManager.DIRECTION_IN, outTransportTransform); + mISM.applyTransportModeTransform( + socket.mSocket, IpSecManager.DIRECTION_OUT, inTransportTransform); + } + + byte[] pkt; + if (transportInTunnelMode) { + pkt = + getTransportInTunnelModePacket( + spi, + spi, + remoteInner, + localInner, + remoteOuter, + localOuter, + socket.getPort(), + encapPort); + } else { + pkt = + getTunnelModePacket( + spi, + remoteInner, + localInner, + remoteOuter, + localOuter, + socket.getPort(), + encapPort); + } + sTunUtils.injectPacket(pkt); + + // Receive packet from socket, and validate + receiveAndValidatePacket(socket); + + socket.close(); + } + }; + } + } + + private void checkTunnelOutput( + int innerFamily, int outerFamily, boolean useEncap, boolean transportInTunnelMode) + throws Exception { + checkTunnel( + innerFamily, + outerFamily, + useEncap, + transportInTunnelMode, + new OutputTestRunnableFactory()); + } + + private void checkTunnelInput( + int innerFamily, int outerFamily, boolean useEncap, boolean transportInTunnelMode) + throws Exception { + checkTunnel( + innerFamily, + outerFamily, + useEncap, + transportInTunnelMode, + new InputPacketGeneratorTestRunnableFactory()); + } + + public void checkTunnel( + int innerFamily, + int outerFamily, + boolean useEncap, + boolean transportInTunnelMode, + TestRunnableFactory factory) throws Exception { if (!hasTunnelsFeature()) return; - setAppop(true); - int innerPrefixLen = inner instanceof Inet6Address ? IP6_PREFIX_LEN : IP4_PREFIX_LEN; + InetAddress localInner = innerFamily == AF_INET ? LOCAL_INNER_4 : LOCAL_INNER_6; + InetAddress remoteInner = innerFamily == AF_INET ? REMOTE_INNER_4 : REMOTE_INNER_6; - try (IpSecManager.SecurityParameterIndex spi = mISM.allocateSecurityParameterIndex(outer); + InetAddress localOuter = outerFamily == AF_INET ? LOCAL_OUTER_4 : LOCAL_OUTER_6; + InetAddress remoteOuter = outerFamily == AF_INET ? REMOTE_OUTER_4 : REMOTE_OUTER_6; + + // Preselect both SPI and encap port, to be used for both inbound and outbound tunnels. + // Re-uses the same SPI to ensure that even in cases of symmetric SPIs shared across tunnel + // and transport mode, packets are encrypted/decrypted properly based on the src/dst. + int spi = getRandomSpi(localOuter, remoteOuter); + int expectedPacketSize = + getPacketSize(innerFamily, outerFamily, useEncap, transportInTunnelMode); + + try (IpSecManager.SecurityParameterIndex inTransportSpi = + mISM.allocateSecurityParameterIndex(localInner, spi); + IpSecManager.SecurityParameterIndex outTransportSpi = + mISM.allocateSecurityParameterIndex(remoteInner, spi); + IpSecTransform inTransportTransform = + buildIpSecTransform(sContext, inTransportSpi, null, remoteInner); + IpSecTransform outTransportTransform = + buildIpSecTransform(sContext, outTransportSpi, null, localInner); + UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) { + + buildTunnelAndNetwork( + localInner, + remoteInner, + localOuter, + remoteOuter, + spi, + useEncap ? encapSocket : null, + factory.getTestRunnable( + transportInTunnelMode, + spi, + localInner, + remoteInner, + localOuter, + remoteOuter, + inTransportTransform, + outTransportTransform, + useEncap ? encapSocket.getPort() : 0, + expectedPacketSize)); + } + } + + private void buildTunnelAndNetwork( + InetAddress localInner, + InetAddress remoteInner, + InetAddress localOuter, + InetAddress remoteOuter, + int spi, + UdpEncapsulationSocket encapSocket, + TestRunnable test) + throws Exception { + int innerPrefixLen = localInner instanceof Inet6Address ? IP6_PREFIX_LEN : IP4_PREFIX_LEN; + TestNetworkCallback testNetworkCb = null; + + try (IpSecManager.SecurityParameterIndex inSpi = + mISM.allocateSecurityParameterIndex(localOuter, spi); + IpSecManager.SecurityParameterIndex outSpi = + mISM.allocateSecurityParameterIndex(remoteOuter, spi); IpSecManager.IpSecTunnelInterface tunnelIntf = - mISM.createIpSecTunnelInterface(outer, outer, mCM.getActiveNetwork()); - IpSecManager.UdpEncapsulationSocket encapSocket = - mISM.openUdpEncapsulationSocket()) { + mISM.createIpSecTunnelInterface(localOuter, remoteOuter, sTunNetwork)) { + // Build the test network + tunnelIntf.addAddress(localInner, innerPrefixLen); + testNetworkCb = setupAndGetTestNetwork(tunnelIntf.getInterfaceName()); + Network testNetwork = testNetworkCb.getNetworkBlocking(); - IpSecTransform.Builder transformBuilder = new IpSecTransform.Builder(mContext); + // Check interface was created + NetworkInterface netIntf = NetworkInterface.getByName(tunnelIntf.getInterfaceName()); + assertNotNull(netIntf); + + // Check addresses + List intfAddrs = netIntf.getInterfaceAddresses(); + assertEquals(1, intfAddrs.size()); + assertEquals(localInner, intfAddrs.get(0).getAddress()); + assertEquals(innerPrefixLen, intfAddrs.get(0).getNetworkPrefixLength()); + + // Configure Transform parameters + IpSecTransform.Builder transformBuilder = new IpSecTransform.Builder(sContext); transformBuilder.setEncryption( new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY)); transformBuilder.setAuthentication( new IpSecAlgorithm( IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4)); - if (useEncap) { + if (encapSocket != null) { transformBuilder.setIpv4Encapsulation(encapSocket, encapSocket.getPort()); } - // Check transform application - try (IpSecTransform transform = transformBuilder.buildTunnelModeTransform(outer, spi)) { - mISM.applyTunnelModeTransform(tunnelIntf, IpSecManager.DIRECTION_IN, transform); - mISM.applyTunnelModeTransform(tunnelIntf, IpSecManager.DIRECTION_OUT, transform); + // Apply transform and check that traffic is properly encrypted + try (IpSecTransform inTransform = + transformBuilder.buildTunnelModeTransform(remoteOuter, inSpi); + IpSecTransform outTransform = + transformBuilder.buildTunnelModeTransform(localOuter, outSpi)) { + mISM.applyTunnelModeTransform(tunnelIntf, IpSecManager.DIRECTION_IN, inTransform); + mISM.applyTunnelModeTransform(tunnelIntf, IpSecManager.DIRECTION_OUT, outTransform); - // TODO: Test to ensure that send/receive works with these transforms. + test.run(testNetwork); } - // Check interface was created - NetworkInterface netIntf = NetworkInterface.getByName(tunnelIntf.getInterfaceName()); - assertNotNull(netIntf); - - // Add addresses and check - tunnelIntf.addAddress(inner, innerPrefixLen); - for (InterfaceAddress intfAddr : netIntf.getInterfaceAddresses()) { - assertEquals(intfAddr.getAddress(), inner); - assertEquals(intfAddr.getNetworkPrefixLength(), innerPrefixLen); - } + // Teardown the test network + sTNM.teardownTestNetwork(testNetwork); // Remove addresses and check - tunnelIntf.removeAddress(inner, innerPrefixLen); + tunnelIntf.removeAddress(localInner, innerPrefixLen); + netIntf = NetworkInterface.getByName(tunnelIntf.getInterfaceName()); assertTrue(netIntf.getInterfaceAddresses().isEmpty()); // Check interface was cleaned up tunnelIntf.close(); netIntf = NetworkInterface.getByName(tunnelIntf.getInterfaceName()); assertNull(netIntf); + } finally { + if (testNetworkCb != null) { + sCM.unregisterNetworkCallback(testNetworkCb); + } } } - /* - * Create, add and remove addresses, then teardown tunnel - */ + private static void receiveAndValidatePacket(JavaUdpSocket socket) throws Exception { + byte[] socketResponseBytes = socket.receive(); + assertArrayEquals(TEST_DATA, socketResponseBytes); + } + + private int getRandomSpi(InetAddress localOuter, InetAddress remoteOuter) throws Exception { + // Try to allocate both in and out SPIs using the same requested SPI value. + try (IpSecManager.SecurityParameterIndex inSpi = + mISM.allocateSecurityParameterIndex(localOuter); + IpSecManager.SecurityParameterIndex outSpi = + mISM.allocateSecurityParameterIndex(remoteOuter, inSpi.getSpi()); ) { + return inSpi.getSpi(); + } + } + + private IpHeader getIpHeader(int protocol, InetAddress src, InetAddress dst, Payload payload) { + if ((src instanceof Inet6Address) != (dst instanceof Inet6Address)) { + throw new IllegalArgumentException("Invalid src/dst address combination"); + } + + if (src instanceof Inet6Address) { + return new Ip6Header(protocol, (Inet6Address) src, (Inet6Address) dst, payload); + } else { + return new Ip4Header(protocol, (Inet4Address) src, (Inet4Address) dst, payload); + } + } + + private EspHeader buildTransportModeEspPacket( + int spi, InetAddress src, InetAddress dst, int port, Payload payload) throws Exception { + IpHeader preEspIpHeader = getIpHeader(payload.getProtocolId(), src, dst, payload); + + return new EspHeader( + payload.getProtocolId(), + spi, + 1, // sequence number + CRYPT_KEY, // Same key for auth and crypt + payload.getPacketBytes(preEspIpHeader)); + } + + private EspHeader buildTunnelModeEspPacket( + int spi, + InetAddress srcInner, + InetAddress dstInner, + InetAddress srcOuter, + InetAddress dstOuter, + int port, + int encapPort, + Payload payload) + throws Exception { + IpHeader innerIp = getIpHeader(payload.getProtocolId(), srcInner, dstInner, payload); + return new EspHeader( + innerIp.getProtocolId(), + spi, + 1, // sequence number + CRYPT_KEY, // Same key for auth and crypt + innerIp.getPacketBytes()); + } + + private IpHeader maybeEncapPacket( + InetAddress src, InetAddress dst, int encapPort, EspHeader espPayload) + throws Exception { + + Payload payload = espPayload; + if (encapPort != 0) { + payload = new UdpHeader(encapPort, encapPort, espPayload); + } + + return getIpHeader(payload.getProtocolId(), src, dst, payload); + } + + private byte[] getTunnelModePacket( + int spi, + InetAddress srcInner, + InetAddress dstInner, + InetAddress srcOuter, + InetAddress dstOuter, + int port, + int encapPort) + throws Exception { + UdpHeader udp = new UdpHeader(port, port, new BytePayload(TEST_DATA)); + + EspHeader espPayload = + buildTunnelModeEspPacket( + spi, srcInner, dstInner, srcOuter, dstOuter, port, encapPort, udp); + return maybeEncapPacket(srcOuter, dstOuter, encapPort, espPayload).getPacketBytes(); + } + + private byte[] getTransportInTunnelModePacket( + int spiInner, + int spiOuter, + InetAddress srcInner, + InetAddress dstInner, + InetAddress srcOuter, + InetAddress dstOuter, + int port, + int encapPort) + throws Exception { + UdpHeader udp = new UdpHeader(port, port, new BytePayload(TEST_DATA)); + + EspHeader espPayload = buildTransportModeEspPacket(spiInner, srcInner, dstInner, port, udp); + espPayload = + buildTunnelModeEspPacket( + spiOuter, + srcInner, + dstInner, + srcOuter, + dstOuter, + port, + encapPort, + espPayload); + return maybeEncapPacket(srcOuter, dstOuter, encapPort, espPayload).getPacketBytes(); + } + + // Transport-in-Tunnel mode tests + @Test + public void testTransportInTunnelModeV4InV4() throws Exception { + checkTunnelOutput(AF_INET, AF_INET, false, true); + checkTunnelInput(AF_INET, AF_INET, false, true); + } + + @Test + public void testTransportInTunnelModeV4InV4UdpEncap() throws Exception { + checkTunnelOutput(AF_INET, AF_INET, true, true); + checkTunnelInput(AF_INET, AF_INET, true, true); + } + + @Test + public void testTransportInTunnelModeV4InV6() throws Exception { + checkTunnelOutput(AF_INET, AF_INET6, false, true); + checkTunnelInput(AF_INET, AF_INET6, false, true); + } + + @Test + public void testTransportInTunnelModeV6InV4() throws Exception { + checkTunnelOutput(AF_INET6, AF_INET, false, true); + checkTunnelInput(AF_INET6, AF_INET, false, true); + } + + @Test + public void testTransportInTunnelModeV6InV4UdpEncap() throws Exception { + checkTunnelOutput(AF_INET6, AF_INET, true, true); + checkTunnelInput(AF_INET6, AF_INET, true, true); + } + + @Test + public void testTransportInTunnelModeV6InV6() throws Exception { + checkTunnelOutput(AF_INET, AF_INET6, false, true); + checkTunnelInput(AF_INET, AF_INET6, false, true); + } + + // Tunnel mode tests + @Test public void testTunnelV4InV4() throws Exception { - checkTunnel(INNER_ADDR4, OUTER_ADDR4, false); + checkTunnelOutput(AF_INET, AF_INET, false, false); + checkTunnelInput(AF_INET, AF_INET, false, false); } + @Test public void testTunnelV4InV4UdpEncap() throws Exception { - checkTunnel(INNER_ADDR4, OUTER_ADDR4, true); + checkTunnelOutput(AF_INET, AF_INET, true, false); + checkTunnelInput(AF_INET, AF_INET, true, false); } + @Test public void testTunnelV4InV6() throws Exception { - checkTunnel(INNER_ADDR4, OUTER_ADDR6, false); + checkTunnelOutput(AF_INET, AF_INET6, false, false); + checkTunnelInput(AF_INET, AF_INET6, false, false); } + @Test public void testTunnelV6InV4() throws Exception { - checkTunnel(INNER_ADDR6, OUTER_ADDR4, false); + checkTunnelOutput(AF_INET6, AF_INET, false, false); + checkTunnelInput(AF_INET6, AF_INET, false, false); } + @Test public void testTunnelV6InV4UdpEncap() throws Exception { - checkTunnel(INNER_ADDR6, OUTER_ADDR4, true); + checkTunnelOutput(AF_INET6, AF_INET, true, false); + checkTunnelInput(AF_INET6, AF_INET, true, false); } + @Test public void testTunnelV6InV6() throws Exception { - checkTunnel(INNER_ADDR6, OUTER_ADDR6, false); + checkTunnelOutput(AF_INET6, AF_INET6, false, false); + checkTunnelInput(AF_INET6, AF_INET6, false, false); } } diff --git a/tests/cts/net/src/android/net/cts/TunUtils.java b/tests/cts/net/src/android/net/cts/TunUtils.java index 4d5533fc62..a0307137a5 100644 --- a/tests/cts/net/src/android/net/cts/TunUtils.java +++ b/tests/cts/net/src/android/net/cts/TunUtils.java @@ -247,4 +247,11 @@ public class TunUtils { out.write(pkt); out.flush(); } + + /** Resets the intercepted packets. */ + public void reset() throws IOException { + synchronized (mPackets) { + mPackets.clear(); + } + } } From 084c8b47b674afd17ae1f648b1d0f16006812bbf Mon Sep 17 00:00:00 2001 From: Benedict Wong Date: Fri, 10 May 2019 01:16:10 -0700 Subject: [PATCH 0618/1109] Enforce IPsec Tunnel mode for Android Q This commit adds a second condition to whether the device is expected to have the tunnel mode feature. If a device's first API/launch version is Q or above, require IPsec tunnels Bug: 72950854 Test: Ran on device with first API level < Q and == Q. Change-Id: I7b849ad24a04b6b7899a80f1856236b5ceb5a839 --- .../cts/net/src/android/net/cts/IpSecManagerTunnelTest.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java index e8c0a7a4b2..6e96682b68 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java @@ -55,8 +55,10 @@ import android.net.TestNetworkInterface; import android.net.TestNetworkManager; import android.net.cts.PacketUtils.Payload; import android.os.Binder; +import android.os.Build; import android.os.IBinder; import android.os.ParcelFileDescriptor; +import android.os.SystemProperties; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; @@ -167,7 +169,9 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { } private static boolean hasTunnelsFeature() { - return sContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS); + return sContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS) + || SystemProperties.getInt("ro.product.first_api_level", 0) + >= Build.VERSION_CODES.Q; } private static void setAppop(int appop, boolean allow) { From fbbb9c9c04c7323ba25142501885e24a705f8931 Mon Sep 17 00:00:00 2001 From: Benedict Wong Date: Fri, 10 May 2019 11:05:43 -0700 Subject: [PATCH 0619/1109] Enforce IPsec Tunnel mode for Android Q This commit adds a second condition to whether the device is expected to have the tunnel mode feature. If a device's first API/launch version is Q or above, require IPsec tunnels Bug: 72950854 Test: Ran on device with first API level < Q and == Q. Merged-In: I545444bb483b0f5de45d00a07dc45aeb9e9cbdf7 Change-Id: I7b849ad24a04b6b7899a80f1856236b5ceb5a839 (cherry picked from commit d2465991d92ff4d8425c0f620ab8032609312049) --- .../cts/net/src/android/net/cts/IpSecManagerTunnelTest.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java index e8c0a7a4b2..6e96682b68 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java @@ -55,8 +55,10 @@ import android.net.TestNetworkInterface; import android.net.TestNetworkManager; import android.net.cts.PacketUtils.Payload; import android.os.Binder; +import android.os.Build; import android.os.IBinder; import android.os.ParcelFileDescriptor; +import android.os.SystemProperties; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; @@ -167,7 +169,9 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { } private static boolean hasTunnelsFeature() { - return sContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS); + return sContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS) + || SystemProperties.getInt("ro.product.first_api_level", 0) + >= Build.VERSION_CODES.Q; } private static void setAppop(int appop, boolean allow) { From 0d08e91fe7c2112f44bc12c4d0d00b386e9bebd7 Mon Sep 17 00:00:00 2001 From: Benedict Wong Date: Fri, 10 May 2019 12:41:42 -0700 Subject: [PATCH 0620/1109] Convert IPsec tests to JUnit4 This patch fixes an incompatibility where some tests in the same hierarchy were using Junit3, and other Junit4 No functional test changes made Bug: 72950854 Test: Ran on devices, working Change-Id: I79d231e202ba25ad5f57b44b387bebd7f012aa95 --- .../src/android/net/cts/IpSecBaseTest.java | 21 ++++- .../src/android/net/cts/IpSecManagerTest.java | 81 ++++++++++++++++++- .../net/cts/IpSecManagerTunnelTest.java | 2 + 3 files changed, 99 insertions(+), 5 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java index 087dbdaec3..858891f82b 100644 --- a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java @@ -25,10 +25,10 @@ import android.net.IpSecManager; import android.net.IpSecTransform; import android.system.Os; import android.system.OsConstants; -import android.test.AndroidTestCase; import android.util.Log; import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; import java.io.FileDescriptor; import java.io.IOException; @@ -43,7 +43,12 @@ import java.net.SocketException; import java.util.Arrays; import java.util.concurrent.atomic.AtomicInteger; -public class IpSecBaseTest extends AndroidTestCase { +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class IpSecBaseTest { private static final String TAG = IpSecBaseTest.class.getSimpleName(); @@ -70,9 +75,11 @@ public class IpSecBaseTest extends AndroidTestCase { protected ConnectivityManager mCM; protected IpSecManager mISM; + protected Context mContext; - protected void setUp() throws Exception { - super.setUp(); + @Before + public void setUp() throws Exception { + mContext = InstrumentationRegistry.getContext(); mISM = (IpSecManager) InstrumentationRegistry.getContext() @@ -471,6 +478,7 @@ public class IpSecBaseTest extends AndroidTestCase { } } + @Test public void testJavaTcpSocketPair() throws Exception { for (String addr : LOOPBACK_ADDRS) { InetAddress local = InetAddress.getByName(addr); @@ -481,6 +489,7 @@ public class IpSecBaseTest extends AndroidTestCase { } } + @Test public void testJavaUdpSocketPair() throws Exception { for (String addr : LOOPBACK_ADDRS) { InetAddress local = InetAddress.getByName(addr); @@ -492,6 +501,7 @@ public class IpSecBaseTest extends AndroidTestCase { } } + @Test public void testJavaUdpSocketPairUnconnected() throws Exception { for (String addr : LOOPBACK_ADDRS) { InetAddress local = InetAddress.getByName(addr); @@ -503,6 +513,7 @@ public class IpSecBaseTest extends AndroidTestCase { } } + @Test public void testNativeTcpSocketPair() throws Exception { for (String addr : LOOPBACK_ADDRS) { InetAddress local = InetAddress.getByName(addr); @@ -514,6 +525,7 @@ public class IpSecBaseTest extends AndroidTestCase { } } + @Test public void testNativeUdpSocketPair() throws Exception { for (String addr : LOOPBACK_ADDRS) { InetAddress local = InetAddress.getByName(addr); @@ -525,6 +537,7 @@ public class IpSecBaseTest extends AndroidTestCase { } } + @Test public void testNativeUdpSocketPairUnconnected() throws Exception { for (String addr : LOOPBACK_ADDRS) { InetAddress local = InetAddress.getByName(addr); diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java index 60d1c03ee2..8d5a0684a1 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java @@ -27,7 +27,9 @@ import static android.net.cts.PacketUtils.UDP_HDRLEN; import static android.system.OsConstants.IPPROTO_TCP; import static android.system.OsConstants.IPPROTO_UDP; import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import android.net.IpSecAlgorithm; import android.net.IpSecManager; @@ -37,6 +39,8 @@ import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; +import androidx.test.runner.AndroidJUnit4; + import java.io.FileDescriptor; import java.io.IOException; import java.net.DatagramPacket; @@ -45,6 +49,11 @@ import java.net.Inet6Address; import java.net.InetAddress; import java.util.Arrays; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) public class IpSecManagerTest extends IpSecBaseTest { private static final String TAG = IpSecManagerTest.class.getSimpleName(); @@ -61,7 +70,9 @@ public class IpSecManagerTest extends IpSecBaseTest { private static final byte[] AEAD_KEY = getKey(288); - protected void setUp() throws Exception { + @Before + @Override + public void setUp() throws Exception { super.setUp(); } @@ -71,6 +82,7 @@ public class IpSecManagerTest extends IpSecBaseTest { * Realloc the same SPI that was specifically created (expect SpiUnavailable) * Close SPIs */ + @Test public void testAllocSpi() throws Exception { for (InetAddress addr : GOOGLE_DNS_LIST) { IpSecManager.SecurityParameterIndex randomSpi = null, droidSpi = null; @@ -222,6 +234,7 @@ public class IpSecManagerTest extends IpSecBaseTest { * release transform * send data (expect exception) */ + @Test public void testCreateTransform() throws Exception { InetAddress localAddr = InetAddress.getByName(IPV4_LOOPBACK); IpSecManager.SecurityParameterIndex spi = @@ -591,6 +604,7 @@ public class IpSecManagerTest extends IpSecBaseTest { } } + @Test public void testIkeOverUdpEncapSocket() throws Exception { // IPv6 not supported for UDP-encap-ESP InetAddress local = InetAddress.getByName(IPV4_LOOPBACK); @@ -649,24 +663,28 @@ public class IpSecManagerTest extends IpSecBaseTest { // checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, true, 1000); // } + @Test public void testInterfaceCountersUdp4() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1000, false); } + @Test public void testInterfaceCountersUdp6() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1000, false); } + @Test public void testInterfaceCountersUdp4UdpEncap() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1000, false); } + @Test public void testAesCbcHmacMd5Tcp4() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); @@ -674,6 +692,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); } + @Test public void testAesCbcHmacMd5Tcp6() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); @@ -681,6 +700,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); } + @Test public void testAesCbcHmacMd5Udp4() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); @@ -688,6 +708,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); } + @Test public void testAesCbcHmacMd5Udp6() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); @@ -695,6 +716,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); } + @Test public void testAesCbcHmacSha1Tcp4() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); @@ -702,6 +724,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); } + @Test public void testAesCbcHmacSha1Tcp6() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); @@ -709,6 +732,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); } + @Test public void testAesCbcHmacSha1Udp4() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); @@ -716,6 +740,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); } + @Test public void testAesCbcHmacSha1Udp6() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); @@ -723,6 +748,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); } + @Test public void testAesCbcHmacSha256Tcp4() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); @@ -730,6 +756,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); } + @Test public void testAesCbcHmacSha256Tcp6() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); @@ -737,6 +764,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); } + @Test public void testAesCbcHmacSha256Udp4() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); @@ -744,6 +772,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); } + @Test public void testAesCbcHmacSha256Udp6() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); @@ -751,6 +780,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); } + @Test public void testAesCbcHmacSha384Tcp4() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); @@ -758,6 +788,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); } + @Test public void testAesCbcHmacSha384Tcp6() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); @@ -765,6 +796,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); } + @Test public void testAesCbcHmacSha384Udp4() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); @@ -772,6 +804,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); } + @Test public void testAesCbcHmacSha384Udp6() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); @@ -779,6 +812,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); } + @Test public void testAesCbcHmacSha512Tcp4() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); @@ -786,6 +820,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); } + @Test public void testAesCbcHmacSha512Tcp6() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); @@ -793,6 +828,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); } + @Test public void testAesCbcHmacSha512Udp4() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); @@ -800,6 +836,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true); } + @Test public void testAesCbcHmacSha512Udp6() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); @@ -807,6 +844,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true); } + @Test public void testAesGcm64Tcp4() throws Exception { IpSecAlgorithm authCrypt = new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); @@ -814,6 +852,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); } + @Test public void testAesGcm64Tcp6() throws Exception { IpSecAlgorithm authCrypt = new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); @@ -821,6 +860,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); } + @Test public void testAesGcm64Udp4() throws Exception { IpSecAlgorithm authCrypt = new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); @@ -828,6 +868,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); } + @Test public void testAesGcm64Udp6() throws Exception { IpSecAlgorithm authCrypt = new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); @@ -835,6 +876,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); } + @Test public void testAesGcm96Tcp4() throws Exception { IpSecAlgorithm authCrypt = new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); @@ -842,6 +884,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); } + @Test public void testAesGcm96Tcp6() throws Exception { IpSecAlgorithm authCrypt = new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); @@ -849,6 +892,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); } + @Test public void testAesGcm96Udp4() throws Exception { IpSecAlgorithm authCrypt = new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); @@ -856,6 +900,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); } + @Test public void testAesGcm96Udp6() throws Exception { IpSecAlgorithm authCrypt = new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); @@ -863,6 +908,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); } + @Test public void testAesGcm128Tcp4() throws Exception { IpSecAlgorithm authCrypt = new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); @@ -870,6 +916,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); } + @Test public void testAesGcm128Tcp6() throws Exception { IpSecAlgorithm authCrypt = new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); @@ -877,6 +924,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); } + @Test public void testAesGcm128Udp4() throws Exception { IpSecAlgorithm authCrypt = new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); @@ -884,6 +932,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true); } + @Test public void testAesGcm128Udp6() throws Exception { IpSecAlgorithm authCrypt = new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); @@ -891,6 +940,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true); } + @Test public void testAesCbcHmacMd5Tcp4UdpEncap() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); @@ -898,6 +948,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); } + @Test public void testAesCbcHmacMd5Udp4UdpEncap() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_MD5, getKey(128), 96); @@ -905,6 +956,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); } + @Test public void testAesCbcHmacSha1Tcp4UdpEncap() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); @@ -912,6 +964,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); } + @Test public void testAesCbcHmacSha1Udp4UdpEncap() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, getKey(160), 96); @@ -919,6 +972,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); } + @Test public void testAesCbcHmacSha256Tcp4UdpEncap() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); @@ -926,6 +980,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); } + @Test public void testAesCbcHmacSha256Udp4UdpEncap() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); @@ -933,6 +988,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); } + @Test public void testAesCbcHmacSha384Tcp4UdpEncap() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); @@ -940,6 +996,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); } + @Test public void testAesCbcHmacSha384Udp4UdpEncap() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA384, getKey(384), 192); @@ -947,6 +1004,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); } + @Test public void testAesCbcHmacSha512Tcp4UdpEncap() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); @@ -954,6 +1012,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); } + @Test public void testAesCbcHmacSha512Udp4UdpEncap() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA512, getKey(512), 256); @@ -961,6 +1020,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true); } + @Test public void testAesGcm64Tcp4UdpEncap() throws Exception { IpSecAlgorithm authCrypt = new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); @@ -968,6 +1028,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); } + @Test public void testAesGcm64Udp4UdpEncap() throws Exception { IpSecAlgorithm authCrypt = new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64); @@ -975,6 +1036,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); } + @Test public void testAesGcm96Tcp4UdpEncap() throws Exception { IpSecAlgorithm authCrypt = new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); @@ -982,6 +1044,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); } + @Test public void testAesGcm96Udp4UdpEncap() throws Exception { IpSecAlgorithm authCrypt = new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 96); @@ -989,6 +1052,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); } + @Test public void testAesGcm128Tcp4UdpEncap() throws Exception { IpSecAlgorithm authCrypt = new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); @@ -996,6 +1060,7 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); } + @Test public void testAesGcm128Udp4UdpEncap() throws Exception { IpSecAlgorithm authCrypt = new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128); @@ -1003,78 +1068,91 @@ public class IpSecManagerTest extends IpSecBaseTest { checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true); } + @Test public void testCryptUdp4() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, false, 1, false); checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, false, 1, true); } + @Test public void testAuthUdp4() throws Exception { IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, false, 1, false); checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, false, 1, true); } + @Test public void testCryptUdp6() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, null, null, false, 1, false); checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, null, null, false, 1, true); } + @Test public void testAuthUdp6() throws Exception { IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, auth, null, false, 1, false); checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, auth, null, false, 1, true); } + @Test public void testCryptTcp4() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, false, 1, false); checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, false, 1, true); } + @Test public void testAuthTcp4() throws Exception { IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, false, 1, false); checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, false, 1, true); } + @Test public void testCryptTcp6() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, null, null, false, 1, false); checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, null, null, false, 1, true); } + @Test public void testAuthTcp6() throws Exception { IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, auth, null, false, 1, false); checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, auth, null, false, 1, true); } + @Test public void testCryptUdp4UdpEncap() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, true, 1, false); checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, true, 1, true); } + @Test public void testAuthUdp4UdpEncap() throws Exception { IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, true, 1, false); checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, auth, null, true, 1, true); } + @Test public void testCryptTcp4UdpEncap() throws Exception { IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY); checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, true, 1, false); checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, null, null, true, 1, true); } + @Test public void testAuthTcp4UdpEncap() throws Exception { IpSecAlgorithm auth = new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, getKey(256), 128); checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, true, 1, false); checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, auth, null, true, 1, true); } + @Test public void testOpenUdpEncapSocketSpecificPort() throws Exception { IpSecManager.UdpEncapsulationSocket encapSocket = null; int port = -1; @@ -1103,6 +1181,7 @@ public class IpSecManagerTest extends IpSecBaseTest { assertTrue("Returned invalid port", encapSocket.getPort() == port); } + @Test public void testOpenUdpEncapSocketRandomPort() throws Exception { try (IpSecManager.UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) { assertTrue("Returned invalid port", encapSocket.getPort() != 0); diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java index e8c0a7a4b2..9c94dc993a 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java @@ -40,6 +40,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import android.app.AppOpsManager; import android.content.Context; @@ -142,6 +143,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { } @Before + @Override public void setUp() throws Exception { super.setUp(); From b41bc72ea31ddab47c483cf23bf4f212f8368a7e Mon Sep 17 00:00:00 2001 From: junyulai Date: Tue, 2 Apr 2019 11:36:14 +0800 Subject: [PATCH 0621/1109] [KA14] add cts for keepalive limit test. Per SDK requirement, OEM is required to support minimum number of concurrent keepalives. Implement CTS to verify this. Bug: 129371366 Test: atest android.net.cts .ConnectivityManagerTest#testSocketKeepaliveLimit --generate-new-metrics 10 Change-Id: I8be89116bed5c4dedb2ca42b6d633aa9e8c6a49a --- .../net/cts/ConnectivityManagerTest.java | 135 ++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 4180ea4396..e89a4227cb 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -43,6 +43,8 @@ import android.content.IntentFilter; import android.content.pm.PackageManager; import android.net.ConnectivityManager; import android.net.ConnectivityManager.NetworkCallback; +import android.net.IpSecManager; +import android.net.IpSecManager.UdpEncapsulationSocket; import android.net.LinkProperties; import android.net.Network; import android.net.NetworkCapabilities; @@ -52,6 +54,7 @@ import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; import android.net.NetworkRequest; import android.net.SocketKeepalive; +import android.net.util.KeepaliveUtils; import android.net.wifi.WifiManager; import android.os.Looper; import android.os.MessageQueue; @@ -85,6 +88,7 @@ import java.net.Socket; import java.net.URL; import java.net.UnknownHostException; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.concurrent.CountDownLatch; @@ -704,6 +708,16 @@ public class ConnectivityManagerTest extends AndroidTestCase { return wifiNetwork; } + private InetAddress getFirstV4Address(Network network) { + LinkProperties linkProperties = mCm.getLinkProperties(network); + for (InetAddress address : linkProperties.getAddresses()) { + if (address instanceof Inet4Address) { + return address; + } + } + return null; + } + private Socket getBoundSocket(Network network, String host, int port) throws IOException { InetSocketAddress addr = new InetSocketAddress(host, port); Socket s = network.getSocketFactory().createSocket(); @@ -1277,4 +1291,125 @@ public class ConnectivityManagerTest extends AndroidTestCase { } } + + private int createConcurrentSocketKeepalives(int nattCount, int tcpCount) throws Exception { + if (!isKeepaliveSupported()) return 0; + + final Network network = ensureWifiConnected(); + + final ArrayList kalist = new ArrayList<>(); + final TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(); + final Executor executor = mContext.getMainExecutor(); + + // Create concurrent TCP keepalives. + for (int i = 0; i < tcpCount; i++) { + // Assert that TCP connections can be established on wifi. The file descriptor of tcp + // sockets will be duplicated and kept valid in service side if the keepalives are + // successfully started. + try (Socket tcpSocket = getConnectedSocket(network, TEST_HOST, HTTP_PORT, + 0 /* Unused */, AF_INET)) { + final SocketKeepalive ka = mCm.createSocketKeepalive(network, tcpSocket, executor, + callback); + ka.start(MIN_KEEPALIVE_INTERVAL); + TestSocketKeepaliveCallback.CallbackValue cv = callback.pollCallback(); + assertNotNull(cv); + if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_ERROR + && cv.error == SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES) { + // Limit reached. + break; + } + if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_STARTED) { + kalist.add(ka); + } else { + fail("Unexpected error when creating " + (i + 1) + " TCP keepalives: " + cv); + } + } + } + + // Assert that a Nat-T socket can be created. + final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE); + final UdpEncapsulationSocket nattSocket = mIpSec.openUdpEncapsulationSocket(); + + final InetAddress srcAddr = getFirstV4Address(network); + final InetAddress dstAddr = getAddrByName(TEST_HOST, AF_INET); + assertNotNull(srcAddr); + assertNotNull(dstAddr); + + // Test concurrent Nat-T keepalives. + for (int i = 0; i < nattCount; i++) { + final SocketKeepalive ka = mCm.createSocketKeepalive(network, nattSocket, + srcAddr, dstAddr, executor, callback); + ka.start(MIN_KEEPALIVE_INTERVAL); + TestSocketKeepaliveCallback.CallbackValue cv = callback.pollCallback(); + assertNotNull(cv); + if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_ERROR + && cv.error == SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES) { + // Limit reached. + break; + } + if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_STARTED) { + kalist.add(ka); + } else { + fail("Unexpected error when creating " + (i + 1) + " Nat-T keepalives: " + cv); + } + } + + final int ret = kalist.size(); + + // Clean up. + for (final SocketKeepalive ka : kalist) { + ka.stop(); + callback.expectStopped(); + } + kalist.clear(); + nattSocket.close(); + + return ret; + } + + /** + * Verifies that the concurrent keepalive slots meet the minimum requirement, and don't + * get leaked after iterations. + */ + public void testSocketKeepaliveLimit() throws Exception { + adoptShellPermissionIdentity(); + + final Network network = ensureWifiConnected(); + final NetworkCapabilities nc = mCm.getNetworkCapabilities(network); + + // Get number of supported concurrent keepalives for testing network. + final int[] keepalivesPerTransport = KeepaliveUtils.getSupportedKeepalives(mContext); + final int supported = KeepaliveUtils.getSupportedKeepalivesForNetworkCapabilities( + keepalivesPerTransport, nc); + + // Sanity check. + if (!isKeepaliveSupported()) { + assertEquals(0, supported); + return; + } + + // Verifies that the supported keepalive slots meet MIN_SUPPORTED_KEEPALIVE_COUNT. + assertGreaterOrEqual(supported, KeepaliveUtils.MIN_SUPPORTED_KEEPALIVE_COUNT); + + // Verifies that different types of keepalives can be established. + assertEquals(supported, createConcurrentSocketKeepalives(supported + 1, 0)); + assertEquals(supported, createConcurrentSocketKeepalives(0, supported + 1)); + + // Verifies that different types can be established at the same time. + assertEquals(supported, createConcurrentSocketKeepalives( + supported / 2, supported - supported / 2)); + + // Verifies that keepalives don't get leaked in second round. + assertEquals(supported, createConcurrentSocketKeepalives(supported + 1, 0)); + assertEquals(supported, createConcurrentSocketKeepalives(0, supported + 1)); + assertEquals(supported, createConcurrentSocketKeepalives( + supported / 2, supported - supported / 2)); + + dropShellPermissionIdentity(); + } + + private static void assertGreaterOrEqual(long greater, long lesser) { + assertTrue("" + greater + " expected to be greater than or equal to " + lesser, + greater >= lesser); + } } From 80ec50b8ae0dadf5333f85a84c17e7d106eac08c Mon Sep 17 00:00:00 2001 From: junyulai Date: Wed, 8 May 2019 11:46:25 +0800 Subject: [PATCH 0622/1109] add cts for unprivileged keepalive slots Currently, unprivileged Nat-T keepalives are limited to 1 slot per uid. Add CTS to verify that the keepalive slots are limited as customized for unprivileged requests. Bug: 129371366 Test: atest android.net.cts .ConnectivityManagerTest#testSocketKeepaliveUnprivileged --generate-new-metrics 10 Change-Id: I60b9e9ae9cf2b63490493ced9738cd2f402c3f9b --- .../net/cts/ConnectivityManagerTest.java | 51 +++++++++++++++---- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index e89a4227cb..ea441a7fff 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -1184,6 +1184,16 @@ public class ConnectivityManagerTest extends AndroidTestCase { return s; } + private int getSupportedKeepalivesFromRes() throws Exception { + final Network network = ensureWifiConnected(); + final NetworkCapabilities nc = mCm.getNetworkCapabilities(network); + + // Get number of supported concurrent keepalives for testing network. + final int[] keepalivesPerTransport = KeepaliveUtils.getSupportedKeepalives(mContext); + return KeepaliveUtils.getSupportedKeepalivesForNetworkCapabilities( + keepalivesPerTransport, nc); + } + private boolean isKeepaliveSupported() throws Exception { final Network network = ensureWifiConnected(); final Executor executor = mContext.getMainExecutor(); @@ -1293,7 +1303,8 @@ public class ConnectivityManagerTest extends AndroidTestCase { } private int createConcurrentSocketKeepalives(int nattCount, int tcpCount) throws Exception { - if (!isKeepaliveSupported()) return 0; + // Use customization value in resource to prevent the need of privilege. + if (getSupportedKeepalivesFromRes() == 0) return 0; final Network network = ensureWifiConnected(); @@ -1374,16 +1385,10 @@ public class ConnectivityManagerTest extends AndroidTestCase { public void testSocketKeepaliveLimit() throws Exception { adoptShellPermissionIdentity(); - final Network network = ensureWifiConnected(); - final NetworkCapabilities nc = mCm.getNetworkCapabilities(network); + final int supported = getSupportedKeepalivesFromRes(); - // Get number of supported concurrent keepalives for testing network. - final int[] keepalivesPerTransport = KeepaliveUtils.getSupportedKeepalives(mContext); - final int supported = KeepaliveUtils.getSupportedKeepalivesForNetworkCapabilities( - keepalivesPerTransport, nc); - - // Sanity check. if (!isKeepaliveSupported()) { + // Sanity check. assertEquals(0, supported); return; } @@ -1408,6 +1413,34 @@ public class ConnectivityManagerTest extends AndroidTestCase { dropShellPermissionIdentity(); } + /** + * Verifies that the keepalive slots are limited as customized for unprivileged requests. + */ + public void testSocketKeepaliveUnprivileged() throws Exception { + final int supported = getSupportedKeepalivesFromRes(); + + adoptShellPermissionIdentity(); + if (!isKeepaliveSupported()) { + // Sanity check. + assertEquals(0, supported); + return; + } + dropShellPermissionIdentity(); + + final int allowedUnprivilegedPerUid = mContext.getResources().getInteger( + R.integer.config_allowedUnprivilegedKeepalivePerUid); + final int reservedPrivilegedSlots = mContext.getResources().getInteger( + R.integer.config_reservedPrivilegedKeepaliveSlots); + // Verifies that unprivileged request per uid cannot exceed the limit customized in the + // resource. Currently, unprivileged keepalive slots are limited to Nat-T only, this test + // does not apply to TCP. + assertGreaterOrEqual(supported, reservedPrivilegedSlots); + assertGreaterOrEqual(supported, allowedUnprivilegedPerUid); + final int expectedUnprivileged = + Math.min(allowedUnprivilegedPerUid, supported - reservedPrivilegedSlots); + assertEquals(expectedUnprivileged, createConcurrentSocketKeepalives(supported + 1, 0)); + } + private static void assertGreaterOrEqual(long greater, long lesser) { assertTrue("" + greater + " expected to be greater than or equal to " + lesser, greater >= lesser); From ad4c047f6d6e9b3dc0df58fd80f6511b7351a872 Mon Sep 17 00:00:00 2001 From: junyulai Date: Tue, 2 Apr 2019 11:36:14 +0800 Subject: [PATCH 0623/1109] [KA14] add cts for keepalive limit test. Per SDK requirement, OEM is required to support minimum number of concurrent keepalives. Implement CTS to verify this. Bug: 129371366 Test: atest android.net.cts .ConnectivityManagerTest#testSocketKeepaliveLimit --generate-new-metrics 10 (Clean cherry-pick of aosp/937026) Change-Id: I8be89116bed5c4dedb2ca42b6d633aa9e8c6a49a Merged-In: I8be89116bed5c4dedb2ca42b6d633aa9e8c6a49a --- .../net/cts/ConnectivityManagerTest.java | 135 ++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index cb1aa09599..f702042f77 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -43,6 +43,8 @@ import android.content.IntentFilter; import android.content.pm.PackageManager; import android.net.ConnectivityManager; import android.net.ConnectivityManager.NetworkCallback; +import android.net.IpSecManager; +import android.net.IpSecManager.UdpEncapsulationSocket; import android.net.LinkProperties; import android.net.Network; import android.net.NetworkCapabilities; @@ -52,6 +54,7 @@ import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; import android.net.NetworkRequest; import android.net.SocketKeepalive; +import android.net.util.KeepaliveUtils; import android.net.wifi.WifiManager; import android.os.Looper; import android.os.MessageQueue; @@ -86,6 +89,7 @@ import java.net.Socket; import java.net.URL; import java.net.UnknownHostException; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.concurrent.CountDownLatch; @@ -705,6 +709,16 @@ public class ConnectivityManagerTest extends AndroidTestCase { return wifiNetwork; } + private InetAddress getFirstV4Address(Network network) { + LinkProperties linkProperties = mCm.getLinkProperties(network); + for (InetAddress address : linkProperties.getAddresses()) { + if (address instanceof Inet4Address) { + return address; + } + } + return null; + } + private Socket getBoundSocket(Network network, String host, int port) throws IOException { InetSocketAddress addr = new InetSocketAddress(host, port); Socket s = network.getSocketFactory().createSocket(); @@ -1278,4 +1292,125 @@ public class ConnectivityManagerTest extends AndroidTestCase { } } + + private int createConcurrentSocketKeepalives(int nattCount, int tcpCount) throws Exception { + if (!isKeepaliveSupported()) return 0; + + final Network network = ensureWifiConnected(); + + final ArrayList kalist = new ArrayList<>(); + final TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(); + final Executor executor = mContext.getMainExecutor(); + + // Create concurrent TCP keepalives. + for (int i = 0; i < tcpCount; i++) { + // Assert that TCP connections can be established on wifi. The file descriptor of tcp + // sockets will be duplicated and kept valid in service side if the keepalives are + // successfully started. + try (Socket tcpSocket = getConnectedSocket(network, TEST_HOST, HTTP_PORT, + 0 /* Unused */, AF_INET)) { + final SocketKeepalive ka = mCm.createSocketKeepalive(network, tcpSocket, executor, + callback); + ka.start(MIN_KEEPALIVE_INTERVAL); + TestSocketKeepaliveCallback.CallbackValue cv = callback.pollCallback(); + assertNotNull(cv); + if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_ERROR + && cv.error == SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES) { + // Limit reached. + break; + } + if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_STARTED) { + kalist.add(ka); + } else { + fail("Unexpected error when creating " + (i + 1) + " TCP keepalives: " + cv); + } + } + } + + // Assert that a Nat-T socket can be created. + final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE); + final UdpEncapsulationSocket nattSocket = mIpSec.openUdpEncapsulationSocket(); + + final InetAddress srcAddr = getFirstV4Address(network); + final InetAddress dstAddr = getAddrByName(TEST_HOST, AF_INET); + assertNotNull(srcAddr); + assertNotNull(dstAddr); + + // Test concurrent Nat-T keepalives. + for (int i = 0; i < nattCount; i++) { + final SocketKeepalive ka = mCm.createSocketKeepalive(network, nattSocket, + srcAddr, dstAddr, executor, callback); + ka.start(MIN_KEEPALIVE_INTERVAL); + TestSocketKeepaliveCallback.CallbackValue cv = callback.pollCallback(); + assertNotNull(cv); + if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_ERROR + && cv.error == SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES) { + // Limit reached. + break; + } + if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_STARTED) { + kalist.add(ka); + } else { + fail("Unexpected error when creating " + (i + 1) + " Nat-T keepalives: " + cv); + } + } + + final int ret = kalist.size(); + + // Clean up. + for (final SocketKeepalive ka : kalist) { + ka.stop(); + callback.expectStopped(); + } + kalist.clear(); + nattSocket.close(); + + return ret; + } + + /** + * Verifies that the concurrent keepalive slots meet the minimum requirement, and don't + * get leaked after iterations. + */ + public void testSocketKeepaliveLimit() throws Exception { + adoptShellPermissionIdentity(); + + final Network network = ensureWifiConnected(); + final NetworkCapabilities nc = mCm.getNetworkCapabilities(network); + + // Get number of supported concurrent keepalives for testing network. + final int[] keepalivesPerTransport = KeepaliveUtils.getSupportedKeepalives(mContext); + final int supported = KeepaliveUtils.getSupportedKeepalivesForNetworkCapabilities( + keepalivesPerTransport, nc); + + // Sanity check. + if (!isKeepaliveSupported()) { + assertEquals(0, supported); + return; + } + + // Verifies that the supported keepalive slots meet MIN_SUPPORTED_KEEPALIVE_COUNT. + assertGreaterOrEqual(supported, KeepaliveUtils.MIN_SUPPORTED_KEEPALIVE_COUNT); + + // Verifies that different types of keepalives can be established. + assertEquals(supported, createConcurrentSocketKeepalives(supported + 1, 0)); + assertEquals(supported, createConcurrentSocketKeepalives(0, supported + 1)); + + // Verifies that different types can be established at the same time. + assertEquals(supported, createConcurrentSocketKeepalives( + supported / 2, supported - supported / 2)); + + // Verifies that keepalives don't get leaked in second round. + assertEquals(supported, createConcurrentSocketKeepalives(supported + 1, 0)); + assertEquals(supported, createConcurrentSocketKeepalives(0, supported + 1)); + assertEquals(supported, createConcurrentSocketKeepalives( + supported / 2, supported - supported / 2)); + + dropShellPermissionIdentity(); + } + + private static void assertGreaterOrEqual(long greater, long lesser) { + assertTrue("" + greater + " expected to be greater than or equal to " + lesser, + greater >= lesser); + } } From bbf160a93d10af0d521ec96c69be38c9e71803c0 Mon Sep 17 00:00:00 2001 From: junyulai Date: Wed, 8 May 2019 11:46:25 +0800 Subject: [PATCH 0624/1109] add cts for unprivileged keepalive slots Currently, unprivileged Nat-T keepalives are limited to 1 slot per uid. Add CTS to verify that the keepalive slots are limited as customized for unprivileged requests. Bug: 129371366 Test: atest android.net.cts .ConnectivityManagerTest#testSocketKeepaliveUnprivileged --generate-new-metrics 10 (Clean cherry-pick of aosp/957205) Change-Id: I60b9e9ae9cf2b63490493ced9738cd2f402c3f9b Merged-In: I60b9e9ae9cf2b63490493ced9738cd2f402c3f9b --- .../net/cts/ConnectivityManagerTest.java | 51 +++++++++++++++---- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index f702042f77..606d3fc772 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -1185,6 +1185,16 @@ public class ConnectivityManagerTest extends AndroidTestCase { return s; } + private int getSupportedKeepalivesFromRes() throws Exception { + final Network network = ensureWifiConnected(); + final NetworkCapabilities nc = mCm.getNetworkCapabilities(network); + + // Get number of supported concurrent keepalives for testing network. + final int[] keepalivesPerTransport = KeepaliveUtils.getSupportedKeepalives(mContext); + return KeepaliveUtils.getSupportedKeepalivesForNetworkCapabilities( + keepalivesPerTransport, nc); + } + private boolean isKeepaliveSupported() throws Exception { final Network network = ensureWifiConnected(); final Executor executor = mContext.getMainExecutor(); @@ -1294,7 +1304,8 @@ public class ConnectivityManagerTest extends AndroidTestCase { } private int createConcurrentSocketKeepalives(int nattCount, int tcpCount) throws Exception { - if (!isKeepaliveSupported()) return 0; + // Use customization value in resource to prevent the need of privilege. + if (getSupportedKeepalivesFromRes() == 0) return 0; final Network network = ensureWifiConnected(); @@ -1375,16 +1386,10 @@ public class ConnectivityManagerTest extends AndroidTestCase { public void testSocketKeepaliveLimit() throws Exception { adoptShellPermissionIdentity(); - final Network network = ensureWifiConnected(); - final NetworkCapabilities nc = mCm.getNetworkCapabilities(network); + final int supported = getSupportedKeepalivesFromRes(); - // Get number of supported concurrent keepalives for testing network. - final int[] keepalivesPerTransport = KeepaliveUtils.getSupportedKeepalives(mContext); - final int supported = KeepaliveUtils.getSupportedKeepalivesForNetworkCapabilities( - keepalivesPerTransport, nc); - - // Sanity check. if (!isKeepaliveSupported()) { + // Sanity check. assertEquals(0, supported); return; } @@ -1409,6 +1414,34 @@ public class ConnectivityManagerTest extends AndroidTestCase { dropShellPermissionIdentity(); } + /** + * Verifies that the keepalive slots are limited as customized for unprivileged requests. + */ + public void testSocketKeepaliveUnprivileged() throws Exception { + final int supported = getSupportedKeepalivesFromRes(); + + adoptShellPermissionIdentity(); + if (!isKeepaliveSupported()) { + // Sanity check. + assertEquals(0, supported); + return; + } + dropShellPermissionIdentity(); + + final int allowedUnprivilegedPerUid = mContext.getResources().getInteger( + R.integer.config_allowedUnprivilegedKeepalivePerUid); + final int reservedPrivilegedSlots = mContext.getResources().getInteger( + R.integer.config_reservedPrivilegedKeepaliveSlots); + // Verifies that unprivileged request per uid cannot exceed the limit customized in the + // resource. Currently, unprivileged keepalive slots are limited to Nat-T only, this test + // does not apply to TCP. + assertGreaterOrEqual(supported, reservedPrivilegedSlots); + assertGreaterOrEqual(supported, allowedUnprivilegedPerUid); + final int expectedUnprivileged = + Math.min(allowedUnprivilegedPerUid, supported - reservedPrivilegedSlots); + assertEquals(expectedUnprivileged, createConcurrentSocketKeepalives(supported + 1, 0)); + } + private static void assertGreaterOrEqual(long greater, long lesser) { assertTrue("" + greater + " expected to be greater than or equal to " + lesser, greater >= lesser); From 4af108aacfe7977484d844cefce83a75ac1cafc9 Mon Sep 17 00:00:00 2001 From: Benedict Wong Date: Wed, 15 May 2019 00:26:09 -0700 Subject: [PATCH 0625/1109] Fix IPsec CTS tests for interface address checking Fixes two potentially device/kernel specific, or flaky bugs: 1. Java interface checking by name seems to cache the lookup, resulting in interface address checks occasionally failing (on delete). 2. Link-local addresses appear to be added on all links for some set of kernels and devices. This patch addresses both by only checking that the requested address was added via a address-based NetworkInterface lookup. Bug: 72950854 Test: Ran on sargo-eng on qt-dev/HEAD Test: Manually verified that the addresses are indeed added/removed Change-Id: I3babc72dfe72337c4d68facb1695aec15e504c90 --- .../net/cts/IpSecManagerTunnelTest.java | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java index 66141960c8..93638ac3b5 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java @@ -39,7 +39,6 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.app.AppOpsManager; @@ -69,9 +68,7 @@ import com.android.compatibility.common.util.SystemUtil; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; -import java.net.InterfaceAddress; import java.net.NetworkInterface; -import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; @@ -512,11 +509,10 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { NetworkInterface netIntf = NetworkInterface.getByName(tunnelIntf.getInterfaceName()); assertNotNull(netIntf); - // Check addresses - List intfAddrs = netIntf.getInterfaceAddresses(); - assertEquals(1, intfAddrs.size()); - assertEquals(localInner, intfAddrs.get(0).getAddress()); - assertEquals(innerPrefixLen, intfAddrs.get(0).getNetworkPrefixLength()); + // Verify address was added + netIntf = NetworkInterface.getByInetAddress(localInner); + assertNotNull(netIntf); + assertEquals(tunnelIntf.getInterfaceName(), netIntf.getDisplayName()); // Configure Transform parameters IpSecTransform.Builder transformBuilder = new IpSecTransform.Builder(sContext); @@ -544,15 +540,14 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { // Teardown the test network sTNM.teardownTestNetwork(testNetwork); - // Remove addresses and check + // Remove addresses and check that interface is still present, but fails lookup-by-addr tunnelIntf.removeAddress(localInner, innerPrefixLen); - netIntf = NetworkInterface.getByName(tunnelIntf.getInterfaceName()); - assertTrue(netIntf.getInterfaceAddresses().isEmpty()); + assertNotNull(NetworkInterface.getByName(tunnelIntf.getInterfaceName())); + assertNull(NetworkInterface.getByInetAddress(localInner)); // Check interface was cleaned up tunnelIntf.close(); - netIntf = NetworkInterface.getByName(tunnelIntf.getInterfaceName()); - assertNull(netIntf); + assertNull(NetworkInterface.getByName(tunnelIntf.getInterfaceName())); } finally { if (testNetworkCb != null) { sCM.unregisterNetworkCallback(testNetworkCb); From 78e4a184a10c12978391a039f00e155d0dbff276 Mon Sep 17 00:00:00 2001 From: paulhu Date: Fri, 3 May 2019 16:30:46 +0800 Subject: [PATCH 0626/1109] Enable instant app mode for CtsNetTestCases 1. Indicating CtsNetTestCases support instant app mode but ignore some tests that cannot run in instant app mode. 2. Move some tests which need to test on API 23 into CtsNetApi23TestCases module due to instant app package must target at least API 26. Bug: 123366918 Test: atest CtsNetTestCases --instant Test: atest CtsNetApi23TestCases Test: atest FrameworksNetTests Change-Id: I4e828cbc48143e36c1be38b91c3c698122d4be5a --- tests/cts/net/AndroidManifest.xml | 9 +- tests/cts/net/AndroidTest.xml | 3 +- tests/cts/net/api23Test/Android.bp | 51 +++ tests/cts/net/api23Test/AndroidManifest.xml | 42 ++ tests/cts/net/api23Test/AndroidTest.xml | 30 ++ .../ConnectivityManagerApi23Test.java | 399 ++++++++++++++++++ .../cts/api23test}/ConnectivityReceiver.java | 2 +- .../src/android/net/cts/AirplaneModeTest.java | 3 +- .../net/cts/ConnectivityManagerTest.java | 106 +---- .../src/android/net/cts/IpSecBaseTest.java | 7 + .../src/android/net/cts/IpSecManagerTest.java | 3 + .../android/net/cts/NetworkWatchlistTest.java | 2 + .../cts/SSLCertificateSocketFactoryTest.java | 4 + .../src/android/net/cts/TheaterModeTest.java | 4 +- .../src/android/net/cts/TrafficStatsTest.java | 2 + .../src/android/net/cts/VpnServiceTest.java | 4 + .../net/http/cts/ApacheHttpClientTest.java | 2 + .../net/http/cts/HttpResponseCacheTest.java | 2 + .../android/net/rtp/cts/AudioGroupTest.java | 3 +- .../android/net/rtp/cts/AudioStreamTest.java | 2 + .../net/wifi/aware/cts/SingleDeviceTest.java | 2 + .../android/net/wifi/cts/ConcurrencyTest.java | 2 + .../net/wifi/cts/MulticastLockTest.java | 2 + .../android/net/wifi/cts/NsdManagerTest.java | 2 + .../android/net/wifi/cts/ScanResultTest.java | 2 + .../net/wifi/cts/WifiConfigurationTest.java | 2 + .../wifi/cts/WifiEnterpriseConfigTest.java | 2 + .../android/net/wifi/cts/WifiInfoTest.java | 2 + .../android/net/wifi/cts/WifiLockTest.java | 2 + .../android/net/wifi/cts/WifiManagerTest.java | 2 + .../android/net/wifi/rtt/cts/WifiRttTest.java | 2 + 31 files changed, 594 insertions(+), 108 deletions(-) create mode 100644 tests/cts/net/api23Test/Android.bp create mode 100644 tests/cts/net/api23Test/AndroidManifest.xml create mode 100644 tests/cts/net/api23Test/AndroidTest.xml create mode 100644 tests/cts/net/api23Test/src/android/net/cts/api23test/ConnectivityManagerApi23Test.java rename tests/cts/net/{src/android/net/cts => api23Test/src/android/net/cts/api23test}/ConnectivityReceiver.java (98%) diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index dbd8fef08e..44a00ef619 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -16,7 +16,8 @@ --> + package="android.net.cts" + android:targetSandboxVersion="2"> @@ -36,12 +37,6 @@ - - - - - -

    This test takes an outbound IPsec packet, reflects it (by flipping IP src/dst), and + * injects it back into the TUN. This test then verifies that a packet with the correct payload + * is found on the specified socket/port. + */ + public void checkTunnelReflected( + int innerFamily, int outerFamily, boolean useEncap, boolean transportInTunnelMode) + throws Exception { + if (!hasTunnelsFeature()) return; + + InetAddress localInner = innerFamily == AF_INET ? LOCAL_INNER_4 : LOCAL_INNER_6; + InetAddress remoteInner = innerFamily == AF_INET ? REMOTE_INNER_4 : REMOTE_INNER_6; + + InetAddress localOuter = outerFamily == AF_INET ? LOCAL_OUTER_4 : LOCAL_OUTER_6; + InetAddress remoteOuter = outerFamily == AF_INET ? REMOTE_OUTER_4 : REMOTE_OUTER_6; + + // Preselect both SPI and encap port, to be used for both inbound and outbound tunnels. + int spi = getRandomSpi(localOuter, remoteOuter); + int expectedPacketSize = + getPacketSize(innerFamily, outerFamily, useEncap, transportInTunnelMode); + + try (IpSecManager.SecurityParameterIndex inTransportSpi = + mISM.allocateSecurityParameterIndex(localInner, spi); + IpSecManager.SecurityParameterIndex outTransportSpi = + mISM.allocateSecurityParameterIndex(remoteInner, spi); + IpSecTransform inTransportTransform = + buildIpSecTransform(sContext, inTransportSpi, null, remoteInner); + IpSecTransform outTransportTransform = + buildIpSecTransform(sContext, outTransportSpi, null, localInner); + UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) { + + // Run output direction tests + IpSecTunnelTestRunnable outputIpSecTunnelTestRunnable = + new OutputIpSecTunnelTestRunnableFactory() + .getIpSecTunnelTestRunnable( + transportInTunnelMode, + spi, + localInner, + remoteInner, + localOuter, + remoteOuter, + inTransportTransform, + outTransportTransform, + useEncap ? encapSocket.getPort() : 0, + 0, + expectedPacketSize); + int innerSocketPort = + buildTunnelNetworkAndRunTests( + localInner, + remoteInner, + localOuter, + remoteOuter, + spi, + useEncap ? encapSocket : null, + outputIpSecTunnelTestRunnable); + + // Input direction tests, with matching inner socket ports. + IpSecTunnelTestRunnable inputIpSecTunnelTestRunnable = + new InputReflectedIpSecTunnelTestRunnableFactory() + .getIpSecTunnelTestRunnable( + transportInTunnelMode, + spi, + remoteInner, + localInner, + localOuter, + remoteOuter, + inTransportTransform, + outTransportTransform, + useEncap ? encapSocket.getPort() : 0, + innerSocketPort, + expectedPacketSize); + buildTunnelNetworkAndRunTests( + remoteInner, + localInner, + localOuter, + remoteOuter, + spi, + useEncap ? encapSocket : null, + inputIpSecTunnelTestRunnable); + } } public void checkTunnel( @@ -434,7 +577,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { int outerFamily, boolean useEncap, boolean transportInTunnelMode, - TestRunnableFactory factory) + IpSecTunnelTestRunnableFactory factory) throws Exception { if (!hasTunnelsFeature()) return; @@ -461,14 +604,14 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { buildIpSecTransform(sContext, outTransportSpi, null, localInner); UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) { - buildTunnelAndNetwork( + buildTunnelNetworkAndRunTests( localInner, remoteInner, localOuter, remoteOuter, spi, useEncap ? encapSocket : null, - factory.getTestRunnable( + factory.getIpSecTunnelTestRunnable( transportInTunnelMode, spi, localInner, @@ -478,21 +621,23 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { inTransportTransform, outTransportTransform, useEncap ? encapSocket.getPort() : 0, + 0, expectedPacketSize)); } } - private void buildTunnelAndNetwork( + private int buildTunnelNetworkAndRunTests( InetAddress localInner, InetAddress remoteInner, InetAddress localOuter, InetAddress remoteOuter, int spi, UdpEncapsulationSocket encapSocket, - TestRunnable test) + IpSecTunnelTestRunnable test) throws Exception { int innerPrefixLen = localInner instanceof Inet6Address ? IP6_PREFIX_LEN : IP4_PREFIX_LEN; TestNetworkCallback testNetworkCb = null; + int innerSocketPort; try (IpSecManager.SecurityParameterIndex inSpi = mISM.allocateSecurityParameterIndex(localOuter, spi); @@ -534,7 +679,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { mISM.applyTunnelModeTransform( tunnelIface, IpSecManager.DIRECTION_OUT, outTransform); - test.run(testNetwork); + innerSocketPort = test.run(testNetwork); } // Teardown the test network @@ -553,6 +698,8 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { sCM.unregisterNetworkCallback(testNetworkCb); } } + + return innerSocketPort; } private static void receiveAndValidatePacket(JavaUdpSocket socket) throws Exception { @@ -675,36 +822,66 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { checkTunnelInput(AF_INET, AF_INET, false, true); } + @Test + public void testTransportInTunnelModeV4InV4Reflected() throws Exception { + checkTunnelReflected(AF_INET, AF_INET, false, true); + } + @Test public void testTransportInTunnelModeV4InV4UdpEncap() throws Exception { checkTunnelOutput(AF_INET, AF_INET, true, true); checkTunnelInput(AF_INET, AF_INET, true, true); } + @Test + public void testTransportInTunnelModeV4InV4UdpEncapReflected() throws Exception { + checkTunnelReflected(AF_INET, AF_INET, false, true); + } + @Test public void testTransportInTunnelModeV4InV6() throws Exception { checkTunnelOutput(AF_INET, AF_INET6, false, true); checkTunnelInput(AF_INET, AF_INET6, false, true); } + @Test + public void testTransportInTunnelModeV4InV6Reflected() throws Exception { + checkTunnelReflected(AF_INET, AF_INET, false, true); + } + @Test public void testTransportInTunnelModeV6InV4() throws Exception { checkTunnelOutput(AF_INET6, AF_INET, false, true); checkTunnelInput(AF_INET6, AF_INET, false, true); } + @Test + public void testTransportInTunnelModeV6InV4Reflected() throws Exception { + checkTunnelReflected(AF_INET, AF_INET, false, true); + } + @Test public void testTransportInTunnelModeV6InV4UdpEncap() throws Exception { checkTunnelOutput(AF_INET6, AF_INET, true, true); checkTunnelInput(AF_INET6, AF_INET, true, true); } + @Test + public void testTransportInTunnelModeV6InV4UdpEncapReflected() throws Exception { + checkTunnelReflected(AF_INET, AF_INET, false, true); + } + @Test public void testTransportInTunnelModeV6InV6() throws Exception { checkTunnelOutput(AF_INET, AF_INET6, false, true); checkTunnelInput(AF_INET, AF_INET6, false, true); } + @Test + public void testTransportInTunnelModeV6InV6Reflected() throws Exception { + checkTunnelReflected(AF_INET, AF_INET, false, true); + } + // Tunnel mode tests @Test public void testTunnelV4InV4() throws Exception { @@ -712,33 +889,63 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { checkTunnelInput(AF_INET, AF_INET, false, false); } + @Test + public void testTunnelV4InV4Reflected() throws Exception { + checkTunnelReflected(AF_INET, AF_INET, false, false); + } + @Test public void testTunnelV4InV4UdpEncap() throws Exception { checkTunnelOutput(AF_INET, AF_INET, true, false); checkTunnelInput(AF_INET, AF_INET, true, false); } + @Test + public void testTunnelV4InV4UdpEncapReflected() throws Exception { + checkTunnelReflected(AF_INET, AF_INET, true, false); + } + @Test public void testTunnelV4InV6() throws Exception { checkTunnelOutput(AF_INET, AF_INET6, false, false); checkTunnelInput(AF_INET, AF_INET6, false, false); } + @Test + public void testTunnelV4InV6Reflected() throws Exception { + checkTunnelReflected(AF_INET, AF_INET6, false, false); + } + @Test public void testTunnelV6InV4() throws Exception { checkTunnelOutput(AF_INET6, AF_INET, false, false); checkTunnelInput(AF_INET6, AF_INET, false, false); } + @Test + public void testTunnelV6InV4Reflected() throws Exception { + checkTunnelReflected(AF_INET6, AF_INET, false, false); + } + @Test public void testTunnelV6InV4UdpEncap() throws Exception { checkTunnelOutput(AF_INET6, AF_INET, true, false); checkTunnelInput(AF_INET6, AF_INET, true, false); } + @Test + public void testTunnelV6InV4UdpEncapReflected() throws Exception { + checkTunnelReflected(AF_INET6, AF_INET, true, false); + } + @Test public void testTunnelV6InV6() throws Exception { checkTunnelOutput(AF_INET6, AF_INET6, false, false); checkTunnelInput(AF_INET6, AF_INET6, false, false); } + + @Test + public void testTunnelV6InV6Reflected() throws Exception { + checkTunnelReflected(AF_INET6, AF_INET6, false, false); + } } From 5c79356068f7c9946b7d61e92ec7875e4759e164 Mon Sep 17 00:00:00 2001 From: Benedict Wong Date: Wed, 15 May 2019 00:26:09 -0700 Subject: [PATCH 0631/1109] Fix IPsec CTS tests for interface address checking Fixes two potentially device/kernel specific, or flaky bugs: 1. Java interface checking by name seems to cache the lookup, resulting in interface address checks occasionally failing (on delete). 2. Link-local addresses appear to be added on all links for some set of kernels and devices. This patch addresses both by only checking that the requested address was added via a address-based NetworkInterface lookup. Bug: 72950854 Test: Ran on sargo-eng on qt-dev/HEAD Test: Manually verified that the addresses are indeed added/removed Change-Id: I3babc72dfe72337c4d68facb1695aec15e504c90 Merged-In: I3babc72dfe72337c4d68facb1695aec15e504c90 (cherry picked from commit 4af108aacfe7977484d844cefce83a75ac1cafc9) --- .../net/cts/IpSecManagerTunnelTest.java | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java index 66141960c8..93638ac3b5 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java @@ -39,7 +39,6 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.app.AppOpsManager; @@ -69,9 +68,7 @@ import com.android.compatibility.common.util.SystemUtil; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; -import java.net.InterfaceAddress; import java.net.NetworkInterface; -import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; @@ -512,11 +509,10 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { NetworkInterface netIntf = NetworkInterface.getByName(tunnelIntf.getInterfaceName()); assertNotNull(netIntf); - // Check addresses - List intfAddrs = netIntf.getInterfaceAddresses(); - assertEquals(1, intfAddrs.size()); - assertEquals(localInner, intfAddrs.get(0).getAddress()); - assertEquals(innerPrefixLen, intfAddrs.get(0).getNetworkPrefixLength()); + // Verify address was added + netIntf = NetworkInterface.getByInetAddress(localInner); + assertNotNull(netIntf); + assertEquals(tunnelIntf.getInterfaceName(), netIntf.getDisplayName()); // Configure Transform parameters IpSecTransform.Builder transformBuilder = new IpSecTransform.Builder(sContext); @@ -544,15 +540,14 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { // Teardown the test network sTNM.teardownTestNetwork(testNetwork); - // Remove addresses and check + // Remove addresses and check that interface is still present, but fails lookup-by-addr tunnelIntf.removeAddress(localInner, innerPrefixLen); - netIntf = NetworkInterface.getByName(tunnelIntf.getInterfaceName()); - assertTrue(netIntf.getInterfaceAddresses().isEmpty()); + assertNotNull(NetworkInterface.getByName(tunnelIntf.getInterfaceName())); + assertNull(NetworkInterface.getByInetAddress(localInner)); // Check interface was cleaned up tunnelIntf.close(); - netIntf = NetworkInterface.getByName(tunnelIntf.getInterfaceName()); - assertNull(netIntf); + assertNull(NetworkInterface.getByName(tunnelIntf.getInterfaceName())); } finally { if (testNetworkCb != null) { sCM.unregisterNetworkCallback(testNetworkCb); From 281d757df6eb821a8a1df0399aec25d979d3194b Mon Sep 17 00:00:00 2001 From: Benedict Wong Date: Fri, 17 May 2019 16:04:34 -0700 Subject: [PATCH 0632/1109] Cleanup IPsec CTS tests This commit addresses comments from aosp/963067 and aosp/959617. No behavioral/functional changes were made, only renames and minor style nits addressed. Bug: 72950854 Test: Ran on devices, working Change-Id: I1702b91e245412f0142e9e47b7fb373b9b4e8126 --- .../src/android/net/cts/IpSecManagerTest.java | 6 ---- .../net/cts/IpSecManagerTunnelTest.java | 34 +++++++++---------- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java index 1241785a17..d6b8a968d2 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java @@ -73,12 +73,6 @@ public class IpSecManagerTest extends IpSecBaseTest { private static final byte[] AEAD_KEY = getKey(288); - @Before - @Override - public void setUp() throws Exception { - super.setUp(); - } - /* * Allocate a random SPI * Allocate a specific SPI using previous randomly created SPI value diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java index 93638ac3b5..828abccf58 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java @@ -127,15 +127,15 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { // right appop permissions. setAppop(OP_MANAGE_IPSEC_TUNNELS, true); - TestNetworkInterface testIntf = + TestNetworkInterface testIface = sTNM.createTunInterface( new LinkAddress[] { new LinkAddress(LOCAL_OUTER_4, IP4_PREFIX_LEN), new LinkAddress(LOCAL_OUTER_6, IP6_PREFIX_LEN) }); - sTunFd = testIntf.getFileDescriptor(); - sTunNetworkCallback = setupAndGetTestNetwork(testIntf.getInterfaceName()); + sTunFd = testIface.getFileDescriptor(); + sTunNetworkCallback = setupAndGetTestNetwork(testIface.getInterfaceName()); sTunNetwork = sTunNetworkCallback.getNetworkBlocking(); sTunUtils = new TunUtils(sTunFd); @@ -498,21 +498,20 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { mISM.allocateSecurityParameterIndex(localOuter, spi); IpSecManager.SecurityParameterIndex outSpi = mISM.allocateSecurityParameterIndex(remoteOuter, spi); - IpSecManager.IpSecTunnelInterface tunnelIntf = + IpSecManager.IpSecTunnelInterface tunnelIface = mISM.createIpSecTunnelInterface(localOuter, remoteOuter, sTunNetwork)) { // Build the test network - tunnelIntf.addAddress(localInner, innerPrefixLen); - testNetworkCb = setupAndGetTestNetwork(tunnelIntf.getInterfaceName()); + tunnelIface.addAddress(localInner, innerPrefixLen); + testNetworkCb = setupAndGetTestNetwork(tunnelIface.getInterfaceName()); Network testNetwork = testNetworkCb.getNetworkBlocking(); // Check interface was created - NetworkInterface netIntf = NetworkInterface.getByName(tunnelIntf.getInterfaceName()); - assertNotNull(netIntf); + assertNotNull(NetworkInterface.getByName(tunnelIface.getInterfaceName())); // Verify address was added - netIntf = NetworkInterface.getByInetAddress(localInner); - assertNotNull(netIntf); - assertEquals(tunnelIntf.getInterfaceName(), netIntf.getDisplayName()); + final NetworkInterface netIface = NetworkInterface.getByInetAddress(localInner); + assertNotNull(netIface); + assertEquals(tunnelIface.getInterfaceName(), netIface.getDisplayName()); // Configure Transform parameters IpSecTransform.Builder transformBuilder = new IpSecTransform.Builder(sContext); @@ -531,8 +530,9 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { transformBuilder.buildTunnelModeTransform(remoteOuter, inSpi); IpSecTransform outTransform = transformBuilder.buildTunnelModeTransform(localOuter, outSpi)) { - mISM.applyTunnelModeTransform(tunnelIntf, IpSecManager.DIRECTION_IN, inTransform); - mISM.applyTunnelModeTransform(tunnelIntf, IpSecManager.DIRECTION_OUT, outTransform); + mISM.applyTunnelModeTransform(tunnelIface, IpSecManager.DIRECTION_IN, inTransform); + mISM.applyTunnelModeTransform( + tunnelIface, IpSecManager.DIRECTION_OUT, outTransform); test.run(testNetwork); } @@ -541,13 +541,13 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { sTNM.teardownTestNetwork(testNetwork); // Remove addresses and check that interface is still present, but fails lookup-by-addr - tunnelIntf.removeAddress(localInner, innerPrefixLen); - assertNotNull(NetworkInterface.getByName(tunnelIntf.getInterfaceName())); + tunnelIface.removeAddress(localInner, innerPrefixLen); + assertNotNull(NetworkInterface.getByName(tunnelIface.getInterfaceName())); assertNull(NetworkInterface.getByInetAddress(localInner)); // Check interface was cleaned up - tunnelIntf.close(); - assertNull(NetworkInterface.getByName(tunnelIntf.getInterfaceName())); + tunnelIface.close(); + assertNull(NetworkInterface.getByName(tunnelIface.getInterfaceName())); } finally { if (testNetworkCb != null) { sCM.unregisterNetworkCallback(testNetworkCb); From ee4eb2f35bfea66e1b071522fadf2003da9e6521 Mon Sep 17 00:00:00 2001 From: Benedict Wong Date: Mon, 20 May 2019 11:58:26 -0700 Subject: [PATCH 0633/1109] Remove mContext from IpSecBaseTest This commit removes the mContext from IpSecBaseTest, and replaces it with InstrumentationRegistry.getContext(). Bug: 72950854 Test: Ran on devices, passing. Change-Id: If6fa359825aa9d1f7d4c8d49aba7a34925c073ed --- tests/cts/net/src/android/net/cts/IpSecBaseTest.java | 4 +--- tests/cts/net/src/android/net/cts/IpSecManagerTest.java | 8 +++++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java index 26049cc174..10e43e7b6a 100644 --- a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java @@ -76,11 +76,9 @@ public class IpSecBaseTest { protected ConnectivityManager mCM; protected IpSecManager mISM; - protected Context mContext; @Before public void setUp() throws Exception { - mContext = InstrumentationRegistry.getContext(); mISM = (IpSecManager) InstrumentationRegistry.getContext() @@ -475,7 +473,7 @@ public class IpSecBaseTest { private IpSecTransform buildDefaultTransform(InetAddress localAddr) throws Exception { try (IpSecManager.SecurityParameterIndex spi = mISM.allocateSecurityParameterIndex(localAddr)) { - return buildIpSecTransform(mContext, spi, null, localAddr); + return buildIpSecTransform(InstrumentationRegistry.getContext(), spi, null, localAddr); } } diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java index d6b8a968d2..355b496829 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java @@ -41,6 +41,7 @@ import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; +import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import java.io.FileDescriptor; @@ -238,7 +239,7 @@ public class IpSecManagerTest extends IpSecBaseTest { mISM.allocateSecurityParameterIndex(localAddr); IpSecTransform transform = - new IpSecTransform.Builder(mContext) + new IpSecTransform.Builder(InstrumentationRegistry.getContext()) .setEncryption(new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY)) .setAuthentication( new IpSecAlgorithm( @@ -456,7 +457,8 @@ public class IpSecManagerTest extends IpSecBaseTest { IpSecManager.SecurityParameterIndex spi = mISM.allocateSecurityParameterIndex(local)) { - IpSecTransform.Builder transformBuilder = new IpSecTransform.Builder(mContext); + IpSecTransform.Builder transformBuilder = + new IpSecTransform.Builder(InstrumentationRegistry.getContext()); if (crypt != null) { transformBuilder.setEncryption(crypt); } @@ -617,7 +619,7 @@ public class IpSecManagerTest extends IpSecBaseTest { try (IpSecManager.SecurityParameterIndex spi = mISM.allocateSecurityParameterIndex(local); IpSecTransform transform = - new IpSecTransform.Builder(mContext) + new IpSecTransform.Builder(InstrumentationRegistry.getContext()) .setEncryption(crypt) .setAuthentication(auth) .setIpv4Encapsulation(encapSocket, encapSocket.getPort()) From 5f7599b6d5a0846974ad42722ba9e275dc53d8c7 Mon Sep 17 00:00:00 2001 From: paulhu Date: Fri, 24 May 2019 11:32:37 +0800 Subject: [PATCH 0634/1109] Ignore all tests in IpSecManagerTunnelTest with instant apps Test runner will crash while tring to get test network service in IpSecManagerTunnelTest. Because MANAGE_TEST_NETWORKS permission can't be granted to instant apps. So ignore all tests in this file. Bug: 133399750 Test: atest CtsNetTestCases --instant Change-Id: I5a096f20ec168133dbb65d27d3388c01e6ee895b --- tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java index 6e96682b68..55a09180df 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java @@ -59,6 +59,7 @@ import android.os.Build; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.SystemProperties; +import android.platform.test.annotations.AppModeFull; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; @@ -81,6 +82,7 @@ import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) +@AppModeFull(reason = "MANAGE_TEST_NETWORKS permission can't be granted to instant apps") public class IpSecManagerTunnelTest extends IpSecBaseTest { private static final String TAG = IpSecManagerTunnelTest.class.getSimpleName(); From db6336c0b8d2a69f143978436833c3ff477408ce Mon Sep 17 00:00:00 2001 From: jovanak Date: Tue, 14 May 2019 17:14:13 -0700 Subject: [PATCH 0635/1109] Fixing NetworkWatchlistTest#testGetWatchlistConfigHash for secondary users. Avoids relying on external storage and using the hardcoded /sdcard/ path. Unrooted adb does not have access to non-user 0 sdcard paths, and so the "cp" command fails when the test runs in user 10. Fixes: 121400865 Test: cts-tradefed run cts-dev -m CtsNetTestCases -t android.net.cts.NetworkWatchlistTest#testGetWatchlistConfigHash in user 10. Change-Id: Idc667072bcfbbe159416fa7c7b6b19045b52041d --- .../android/net/cts/NetworkWatchlistTest.java | 45 +++++++++++++------ 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkWatchlistTest.java b/tests/cts/net/src/android/net/cts/NetworkWatchlistTest.java index e0c03a1e95..8ad7820be6 100644 --- a/tests/cts/net/src/android/net/cts/NetworkWatchlistTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkWatchlistTest.java @@ -24,6 +24,7 @@ import static org.junit.Assume.assumeTrue; import android.content.Context; import android.net.ConnectivityManager; import android.os.FileUtils; +import android.os.ParcelFileDescriptor; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; @@ -38,7 +39,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Formatter; @@ -50,8 +51,6 @@ public class NetworkWatchlistTest { private static final String TEST_WATCHLIST_XML = "assets/network_watchlist_config_for_test.xml"; private static final String TEST_EMPTY_WATCHLIST_XML = "assets/network_watchlist_config_empty_for_test.xml"; - private static final String SDCARD_CONFIG_PATH = - "/sdcard/network_watchlist_config_for_test.xml"; private static final String TMP_CONFIG_PATH = "/data/local/tmp/network_watchlist_config_for_test.xml"; // Generated from sha256sum network_watchlist_config_for_test.xml @@ -83,8 +82,7 @@ public class NetworkWatchlistTest { } } - private void cleanup() throws Exception { - runCommand("rm " + SDCARD_CONFIG_PATH); + private void cleanup() throws IOException { runCommand("rm " + TMP_CONFIG_PATH); } @@ -116,22 +114,43 @@ public class NetworkWatchlistTest { } private void saveResourceToFile(String res, String filePath) throws IOException { - InputStream in = getClass().getClassLoader().getResourceAsStream(res); - FileUtils.copyToFileOrThrow(in, new File(filePath)); + // App can't access /data/local/tmp directly, so we pipe resource to file through stdin. + ParcelFileDescriptor stdin = pipeFromStdin(filePath); + pipeResourceToFileDescriptor(res, stdin); + } + + /* Pipe stdin to a file in filePath. Returns PFD for stdin. */ + private ParcelFileDescriptor pipeFromStdin(String filePath) { + // Not all devices have symlink for /dev/stdin, so use /proc/self/fd/0 directly. + // /dev/stdin maps to /proc/self/fd/0. + return runRwCommand("cp /proc/self/fd/0 " + filePath)[1]; + } + + private void pipeResourceToFileDescriptor(String res, ParcelFileDescriptor pfd) + throws IOException { + InputStream resStream = getClass().getClassLoader().getResourceAsStream(res); + FileOutputStream fdStream = new ParcelFileDescriptor.AutoCloseOutputStream(pfd); + + FileUtils.copy(resStream, fdStream); + + try { + fdStream.close(); + } catch (IOException e) { + } } private static String runCommand(String command) throws IOException { return SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(), command); } + private static ParcelFileDescriptor[] runRwCommand(String command) { + return InstrumentationRegistry.getInstrumentation() + .getUiAutomation().executeShellCommandRw(command); + } + private void setWatchlistConfig(String watchlistConfigFile) throws Exception { cleanup(); - // Save test watchlist config to sdcard as app can't access /data/local/tmp - saveResourceToFile(watchlistConfigFile, SDCARD_CONFIG_PATH); - // Copy test watchlist config from sdcard to /data/local/tmp as system service - // can't access /sdcard - runCommand("cp " + SDCARD_CONFIG_PATH + " " + TMP_CONFIG_PATH); - // Set test watchlist config to system + saveResourceToFile(watchlistConfigFile, TMP_CONFIG_PATH); final String cmdResult = runCommand( "cmd network_watchlist set-test-config " + TMP_CONFIG_PATH).trim(); assertThat(cmdResult).contains("Success"); From a138c9e4875a658cd55b3f6ae06a317098e10d3c Mon Sep 17 00:00:00 2001 From: Paul Hu Date: Fri, 24 May 2019 18:52:54 -0700 Subject: [PATCH 0636/1109] Ignore all tests in IpSecManagerTunnelTest with instant apps Test runner will crash while tring to get test network service in IpSecManagerTunnelTest. Because MANAGE_TEST_NETWORKS permission can't be granted to instant apps. So ignore all tests in this file. Bug: 133399750 Test: atest CtsNetTestCases --instant Change-Id: I31b7e12a5a0021185851ba4435a6c42d457f34b6 Merged-In: Ia18c6bfe791692f8835b127adf734ce3d2a4ba95 Merged-In: I697333a7a64d794208d80112bdc1d1e50c5d2b56 Merged-In: I31b7e12a5a0021185851ba4435a6c42d457f34b6 (cherry picked from commit eb29c90465bc7ee89fac4ded00b6354b55fb5a8c) --- tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java index 93638ac3b5..ef6bfc04b2 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java @@ -59,6 +59,7 @@ import android.os.Build; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.SystemProperties; +import android.platform.test.annotations.AppModeFull; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; @@ -79,6 +80,7 @@ import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) +@AppModeFull(reason = "MANAGE_TEST_NETWORKS permission can't be granted to instant apps") public class IpSecManagerTunnelTest extends IpSecBaseTest { private static final String TAG = IpSecManagerTunnelTest.class.getSimpleName(); From 971b79519a49640f60d6d0f4f26ca06b4dcd6320 Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Wed, 24 Apr 2019 21:27:40 -0700 Subject: [PATCH 0637/1109] Convert Android.mk to Android.bp for net cts Bug: 130623306 Test: Run the tests below on Crosshatch, Sailfish, Bonito atest CtsNativeNetTestCases CtsNativeNetDnsTestCases atest CtsNetTestCases Merged-In: I5bb6de7a07494bd13d069212223691968d4f080e (cherry picked from commit db29b055d92c2dd7aef25ee12ad6af9a6bc8558c) Change-Id: I0f1f70794c0ce303158f1aea54f0801379498071 --- tests/cts/net/Android.bp | 64 +++++++++++++++++++++++++ tests/cts/net/Android.mk | 62 ------------------------ tests/cts/net/appForApi23/Android.bp | 33 +++++++++++++ tests/cts/net/appForApi23/Android.mk | 38 --------------- tests/cts/net/jni/Android.bp | 49 +++++++++++++++++++ tests/cts/net/jni/Android.mk | 44 ----------------- tests/cts/net/native/Android.mk | 15 ------ tests/cts/net/native/qtaguid/Android.bp | 53 ++++++++++++++++++++ tests/cts/net/native/qtaguid/Android.mk | 43 ----------------- 9 files changed, 199 insertions(+), 202 deletions(-) create mode 100644 tests/cts/net/Android.bp delete mode 100644 tests/cts/net/Android.mk create mode 100644 tests/cts/net/appForApi23/Android.bp delete mode 100644 tests/cts/net/appForApi23/Android.mk create mode 100644 tests/cts/net/jni/Android.bp delete mode 100644 tests/cts/net/jni/Android.mk delete mode 100644 tests/cts/net/native/Android.mk create mode 100644 tests/cts/net/native/qtaguid/Android.bp delete mode 100644 tests/cts/net/native/qtaguid/Android.mk diff --git a/tests/cts/net/Android.bp b/tests/cts/net/Android.bp new file mode 100644 index 0000000000..779d5c4be2 --- /dev/null +++ b/tests/cts/net/Android.bp @@ -0,0 +1,64 @@ +// Copyright (C) 2008 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. + +android_test { + name: "CtsNetTestCases", + defaults: ["cts_defaults"], + + // Include both the 32 and 64 bit versions + compile_multilib: "both", + + libs: [ + "voip-common", + "org.apache.http.legacy", + "android.test.base.stubs", + ], + + jni_libs: [ + "libcts_jni", + "libnativedns_jni", + "libnativemultinetwork_jni", + "libnativehelper_compat_libc++", + ], + + // include CtsTestServer as a temporary hack to free net.cts from cts.stub. + srcs: [ + "src/**/*.java", + "src/**/*.kt", + ], + + static_libs: [ + "FrameworksNetCommonTests", + "core-tests-support", + "compatibility-device-util-axt", + "ctstestrunner-axt", + "ctstestserver", + "mockwebserver", + "junit", + "junit-params", + "truth-prebuilt", + ], + + // uncomment when b/13249961 is fixed + // sdk_version: "current", + platform_apis: true, + + // Tag this module as a cts test artifact + test_suites: [ + "cts", + "vts", + "general-tests", + ], + +} diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk deleted file mode 100644 index 04974702a6..0000000000 --- a/tests/cts/net/Android.mk +++ /dev/null @@ -1,62 +0,0 @@ -# Copyright (C) 2008 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. - -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) - -# don't include this package in any target -LOCAL_MODULE_TAGS := optional -# and when built explicitly put it in the data partition -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) - -# Include both the 32 and 64 bit versions -LOCAL_MULTILIB := both - -LOCAL_JAVA_LIBRARIES := \ - voip-common \ - org.apache.http.legacy \ - android.test.base.stubs \ - - -LOCAL_JNI_SHARED_LIBRARIES := libcts_jni libnativedns_jni \ - libnativemultinetwork_jni libnativehelper_compat_libc++ - -# include CtsTestServer as a temporary hack to free net.cts from cts.stub. -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_PACKAGE_NAME := CtsNetTestCases - -LOCAL_STATIC_JAVA_LIBRARIES := \ - FrameworksNetCommonTests \ - core-tests-support \ - compatibility-device-util-axt \ - ctstestrunner-axt \ - ctstestserver \ - mockwebserver \ - junit \ - junit-params \ - truth-prebuilt \ - - -# uncomment when b/13249961 is fixed -#LOCAL_SDK_VERSION := current -LOCAL_PRIVATE_PLATFORM_APIS := true - -# Tag this module as a cts test artifact -LOCAL_COMPATIBILITY_SUITE := cts vts general-tests - -include $(BUILD_CTS_PACKAGE) - -include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tests/cts/net/appForApi23/Android.bp b/tests/cts/net/appForApi23/Android.bp new file mode 100644 index 0000000000..82e2a08c10 --- /dev/null +++ b/tests/cts/net/appForApi23/Android.bp @@ -0,0 +1,33 @@ +// Copyright (C) 2016 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. + +android_test { + name: "CtsNetTestAppForApi23", + defaults: ["cts_defaults"], + + // Include both the 32 and 64 bit versions + compile_multilib: "both", + + srcs: ["src/**/*.java"], + + sdk_version: "23", + + // Tag this module as a cts test artifact + test_suites: [ + "cts", + "vts", + "general-tests", + ], + +} diff --git a/tests/cts/net/appForApi23/Android.mk b/tests/cts/net/appForApi23/Android.mk deleted file mode 100644 index 54b60a0219..0000000000 --- a/tests/cts/net/appForApi23/Android.mk +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright (C) 2016 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. - -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) - -# don't include this package in any target -LOCAL_MODULE_TAGS := optional -# and when built explicitly put it in the data partition -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) - -# Include both the 32 and 64 bit versions -LOCAL_MULTILIB := both - -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_PACKAGE_NAME := CtsNetTestAppForApi23 - -LOCAL_SDK_VERSION := 23 - -# Tag this module as a cts test artifact -LOCAL_COMPATIBILITY_SUITE := cts vts general-tests - -include $(BUILD_CTS_PACKAGE) - -include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tests/cts/net/jni/Android.bp b/tests/cts/net/jni/Android.bp new file mode 100644 index 0000000000..baed48dfae --- /dev/null +++ b/tests/cts/net/jni/Android.bp @@ -0,0 +1,49 @@ +// Copyright (C) 2013 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. + +cc_library_shared { + name: "libnativedns_jni", + + srcs: ["NativeDnsJni.c"], + + shared_libs: [ + "libnativehelper_compat_libc++", + "liblog", + ], + stl: "libc++_static", + + cflags: [ + "-Wall", + "-Werror", + "-Wno-unused-parameter", + ], + +} + +cc_library_shared { + name: "libnativemultinetwork_jni", + + srcs: ["NativeMultinetworkJni.cpp"], + cflags: [ + "-Wall", + "-Werror", + "-Wno-format", + ], + shared_libs: [ + "libandroid", + "libnativehelper_compat_libc++", + "liblog", + ], + stl: "libc++_static", +} diff --git a/tests/cts/net/jni/Android.mk b/tests/cts/net/jni/Android.mk deleted file mode 100644 index ccb1278f94..0000000000 --- a/tests/cts/net/jni/Android.mk +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright (C) 2013 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. - -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_MODULE := libnativedns_jni - -# Don't include this package in any configuration by default. -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := NativeDnsJni.c - -LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) - -LOCAL_SHARED_LIBRARIES := libnativehelper_compat_libc++ liblog -LOCAL_CXX_STL := libc++_static - -LOCAL_CFLAGS := -Wall -Werror -Wno-unused-parameter - -include $(BUILD_SHARED_LIBRARY) - -include $(CLEAR_VARS) -LOCAL_MODULE := libnativemultinetwork_jni -# Don't include this package in any configuration by default. -LOCAL_MODULE_TAGS := optional -LOCAL_SRC_FILES := NativeMultinetworkJni.cpp -LOCAL_CFLAGS := -Wall -Werror -Wno-format -LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) -LOCAL_SHARED_LIBRARIES := libandroid libnativehelper_compat_libc++ liblog -LOCAL_CXX_STL := libc++_static -include $(BUILD_SHARED_LIBRARY) diff --git a/tests/cts/net/native/Android.mk b/tests/cts/net/native/Android.mk deleted file mode 100644 index b798d87878..0000000000 --- a/tests/cts/net/native/Android.mk +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (C) 2017 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. - -include $(call all-subdir-makefiles) diff --git a/tests/cts/net/native/qtaguid/Android.bp b/tests/cts/net/native/qtaguid/Android.bp new file mode 100644 index 0000000000..c0f0613040 --- /dev/null +++ b/tests/cts/net/native/qtaguid/Android.bp @@ -0,0 +1,53 @@ +// Copyright (C) 2017 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. + +// Build the unit tests. + +cc_test { + name: "CtsNativeNetTestCases", + + compile_multilib: "both", + multilib: { + lib32: { + suffix: "32", + }, + lib64: { + suffix: "64", + }, + }, + + srcs: ["src/NativeQtaguidTest.cpp"], + + shared_libs: [ + "libutils", + "liblog", + ], + + static_libs: [ + "libgtest", + "libqtaguid", + ], + + // Tag this module as a cts test artifact + test_suites: [ + "cts", + "vts", + ], + + cflags: [ + "-Werror", + "-Wall", + ], + +} diff --git a/tests/cts/net/native/qtaguid/Android.mk b/tests/cts/net/native/qtaguid/Android.mk deleted file mode 100644 index bf89e5f015..0000000000 --- a/tests/cts/net/native/qtaguid/Android.mk +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (C) 2017 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. - -# Build the unit tests. - -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := CtsNativeNetTestCases -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativetest -LOCAL_MULTILIB := both -LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32 -LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64 - -LOCAL_SRC_FILES := \ - src/NativeQtaguidTest.cpp - -LOCAL_SHARED_LIBRARIES := \ - libutils \ - liblog \ - -LOCAL_STATIC_LIBRARIES := \ - libgtest \ - libqtaguid \ - -LOCAL_CTS_TEST_PACKAGE := android.net.native -# Tag this module as a cts test artifact -LOCAL_COMPATIBILITY_SUITE := cts vts - -LOCAL_CFLAGS := -Werror -Wall - -include $(BUILD_CTS_EXECUTABLE) From 1f5f11e681bd1ae6c1477c238966a5572b8d09f9 Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Tue, 16 Apr 2019 17:02:53 +0800 Subject: [PATCH 0638/1109] Add bypass private DNS test case and null network test for DnsResolver cts 1. add test case for testing bypass Private DNS 2. add null network test 3. minor change for cleanup Bug: 130594022 Test: atest DnsResolverTest Change-Id: I2da65fc1267a1975e014c0aafe2ae47df075b712 --- .../src/android/net/cts/DnsResolverTest.java | 374 +++++++++++------- 1 file changed, 227 insertions(+), 147 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/DnsResolverTest.java b/tests/cts/net/src/android/net/cts/DnsResolverTest.java index 945f51dbc8..e16fce09bf 100644 --- a/tests/cts/net/src/android/net/cts/DnsResolverTest.java +++ b/tests/cts/net/src/android/net/cts/DnsResolverTest.java @@ -21,20 +21,25 @@ import static android.net.DnsResolver.FLAG_EMPTY; import static android.net.DnsResolver.FLAG_NO_CACHE_LOOKUP; import static android.net.DnsResolver.TYPE_A; import static android.net.DnsResolver.TYPE_AAAA; -import static android.system.OsConstants.EBADF; +import static android.system.OsConstants.ETIMEDOUT; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; +import android.content.ContentResolver; import android.net.ConnectivityManager; +import android.net.ConnectivityManager.NetworkCallback; import android.net.DnsPacket; import android.net.DnsResolver; +import android.net.LinkProperties; import android.net.Network; import android.net.NetworkCapabilities; +import android.net.NetworkRequest; import android.net.ParseException; import android.os.CancellationSignal; import android.os.Handler; import android.os.Looper; +import android.provider.Settings; import android.system.ErrnoException; import android.test.AndroidTestCase; import android.util.Log; @@ -53,20 +58,63 @@ public class DnsResolverTest extends AndroidTestCase { private static final char[] HEX_CHARS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + + static final String TEST_DOMAIN = "www.google.com"; + static final String INVALID_PRIVATE_DNS_SERVER = "invalid.google"; + static final byte[] TEST_BLOB = new byte[]{ + /* Header */ + 0x55, 0x66, /* Transaction ID */ + 0x01, 0x00, /* Flags */ + 0x00, 0x01, /* Questions */ + 0x00, 0x00, /* Answer RRs */ + 0x00, 0x00, /* Authority RRs */ + 0x00, 0x00, /* Additional RRs */ + /* Queries */ + 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65, + 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */ + 0x00, 0x01, /* Type */ + 0x00, 0x01 /* Class */ + }; static final int TIMEOUT_MS = 12_000; static final int CANCEL_TIMEOUT_MS = 3_000; static final int CANCEL_RETRY_TIMES = 5; static final int NXDOMAIN = 3; + static final int PRIVATE_DNS_SETTING_TIMEOUT_MS = 2_000; + private ContentResolver mCR; private ConnectivityManager mCM; private Executor mExecutor; private DnsResolver mDns; + private String mOldMode; + private String mOldDnsSpecifier; + + @Override protected void setUp() throws Exception { super.setUp(); mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); mDns = DnsResolver.getInstance(); mExecutor = new Handler(Looper.getMainLooper())::post; + mCR = getContext().getContentResolver(); + storePrivateDnsSetting(); + } + + @Override + protected void tearDown() throws Exception { + 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() { + // 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 static String byteArrayToHexString(byte[] bytes) { @@ -94,6 +142,9 @@ public class DnsResolverTest extends AndroidTestCase { "This test requires that at least one network be connected. " + "Please ensure that the device is connected to a network.", testableNetworks.size() >= 1); + // In order to test query with null network, add null as an element. + // Test cases which query with null network will go on default network. + testableNetworks.add(null); return testableNetworks.toArray(new Network[0]); } @@ -105,15 +156,12 @@ public class DnsResolverTest extends AndroidTestCase { public DnsParseException(String msg) { super(msg); } - - public DnsParseException(String msg, Throwable cause) { - super(msg, cause); - } } private static class DnsAnswer extends DnsPacket { DnsAnswer(@NonNull byte[] data) throws DnsParseException { super(data); + // Check QR field.(query (0), or a response (1)). if ((mHeader.flags & (1 << 15)) == 0) { throw new DnsParseException("Not an answer packet"); @@ -123,10 +171,12 @@ public class DnsResolverTest extends AndroidTestCase { int getRcode() { return mHeader.rcode; } - int getANCount(){ + + int getANCount() { return mHeader.getRecordCount(ANSECTION); } - int getQDCount(){ + + int getQDCount() { return mHeader.getRecordCount(QDSECTION); } } @@ -173,7 +223,7 @@ public class DnsResolverTest extends AndroidTestCase { mRcode = rcode; try { mDnsAnswer = new DnsAnswer(answer); - } catch (DnsParseException e) { + } catch (ParseException | DnsParseException e) { fail(mMsg + e.getMessage()); } Log.d(TAG, "Reported blob: " + byteArrayToHexString(answer)); @@ -222,90 +272,76 @@ public class DnsResolverTest extends AndroidTestCase { } } - public void testRawQuery() { - final String dname = "www.google.com"; - final String msg = "RawQuery " + dname; + public void testRawQuery() throws InterruptedException { + final String msg = "RawQuery " + TEST_DOMAIN; for (Network network : getTestableNetworks()) { final VerifyCancelCallback callback = new VerifyCancelCallback(msg); - mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, + mDns.rawQuery(network, TEST_DOMAIN, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); - try { - assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", - callback.waitForAnswer()); - callback.assertHasAnswer(); - } catch (InterruptedException e) { - fail(msg + " Waiting for DNS lookup was interrupted"); - } + + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + callback.waitForAnswer()); + callback.assertHasAnswer(); } } - public void testRawQueryBlob() { + public void testRawQueryBlob() throws InterruptedException { final byte[] blob = new byte[]{ - /* Header */ - 0x55, 0x66, /* Transaction ID */ - 0x01, 0x00, /* Flags */ - 0x00, 0x01, /* Questions */ - 0x00, 0x00, /* Answer RRs */ - 0x00, 0x00, /* Authority RRs */ - 0x00, 0x00, /* Additional RRs */ - /* Queries */ - 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65, - 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */ - 0x00, 0x01, /* Type */ - 0x00, 0x01 /* Class */ + /* Header */ + 0x55, 0x66, /* Transaction ID */ + 0x01, 0x00, /* Flags */ + 0x00, 0x01, /* Questions */ + 0x00, 0x00, /* Answer RRs */ + 0x00, 0x00, /* Authority RRs */ + 0x00, 0x00, /* Additional RRs */ + /* Queries */ + 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65, + 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */ + 0x00, 0x01, /* Type */ + 0x00, 0x01 /* Class */ }; final String msg = "RawQuery blob " + byteArrayToHexString(blob); for (Network network : getTestableNetworks()) { final VerifyCancelCallback callback = new VerifyCancelCallback(msg); mDns.rawQuery(network, blob, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); - try { - assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", - callback.waitForAnswer()); - callback.assertHasAnswer(); - } catch (InterruptedException e) { - fail(msg + " Waiting for DNS lookup was interrupted"); - } + + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + callback.waitForAnswer()); + callback.assertHasAnswer(); } } - public void testRawQueryRoot() { + public void testRawQueryRoot() throws InterruptedException { final String dname = ""; final String msg = "RawQuery empty dname(ROOT) "; for (Network network : getTestableNetworks()) { final VerifyCancelCallback callback = new VerifyCancelCallback(msg); mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); - try { - assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", - callback.waitForAnswer()); - // Except no answer record because the root does not have AAAA records. - callback.assertEmptyAnswer(); - } catch (InterruptedException e) { - fail(msg + " Waiting for DNS lookup was interrupted"); - } + + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + callback.waitForAnswer()); + // Except no answer record because the root does not have AAAA records. + callback.assertEmptyAnswer(); } } - public void testRawQueryNXDomain() { + public void testRawQueryNXDomain() throws InterruptedException { final String dname = "test1-nx.metric.gstatic.com"; final String msg = "RawQuery " + dname; for (Network network : getTestableNetworks()) { final VerifyCancelCallback callback = new VerifyCancelCallback(msg); mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); - try { - assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", - callback.waitForAnswer()); - callback.assertNXDomain(); - } catch (InterruptedException e) { - fail(msg + " Waiting for DNS lookup was interrupted"); - } + + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + callback.waitForAnswer()); + callback.assertNXDomain(); } } - public void testRawQueryCancel() throws ErrnoException { - final String dname = "www.google.com"; - final String msg = "Test cancel RawQuery " + dname; + public void testRawQueryCancel() throws InterruptedException { + final String msg = "Test cancel RawQuery " + TEST_DOMAIN; // Start a DNS query and the cancel it immediately. Use VerifyCancelCallback to expect // that the query is cancelled before it succeeds. If it is not cancelled before it // succeeds, retry the test until it is. @@ -319,39 +355,22 @@ public class DnsResolverTest extends AndroidTestCase { final CountDownLatch latch = new CountDownLatch(1); final CancellationSignal cancelSignal = new CancellationSignal(); final VerifyCancelCallback callback = new VerifyCancelCallback(msg, cancelSignal); - mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_EMPTY, + mDns.rawQuery(network, TEST_DOMAIN, CLASS_IN, TYPE_AAAA, FLAG_EMPTY, mExecutor, cancelSignal, callback); mExecutor.execute(() -> { cancelSignal.cancel(); latch.countDown(); }); - try { - retry = callback.needRetry(); - assertTrue(msg + " query was not cancelled", - latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - } catch (InterruptedException e) { - fail(msg + " Waiting for DNS lookup was interrupted"); - } + + retry = callback.needRetry(); + assertTrue(msg + " query was not cancelled", + latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); } while (retry); } } - public void testRawQueryBlobCancel() throws ErrnoException { - final byte[] blob = new byte[]{ - /* Header */ - 0x55, 0x66, /* Transaction ID */ - 0x01, 0x00, /* Flags */ - 0x00, 0x01, /* Questions */ - 0x00, 0x00, /* Answer RRs */ - 0x00, 0x00, /* Authority RRs */ - 0x00, 0x00, /* Additional RRs */ - /* Queries */ - 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65, - 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */ - 0x00, 0x01, /* Type */ - 0x00, 0x01 /* Class */ - }; - final String msg = "Test cancel RawQuery blob " + byteArrayToHexString(blob); + public void testRawQueryBlobCancel() throws InterruptedException { + final String msg = "Test cancel RawQuery blob " + byteArrayToHexString(TEST_BLOB); // Start a DNS query and the cancel it immediately. Use VerifyCancelCallback to expect // that the query is cancelled before it succeeds. If it is not cancelled before it // succeeds, retry the test until it is. @@ -365,37 +384,30 @@ public class DnsResolverTest extends AndroidTestCase { final CountDownLatch latch = new CountDownLatch(1); final CancellationSignal cancelSignal = new CancellationSignal(); final VerifyCancelCallback callback = new VerifyCancelCallback(msg, cancelSignal); - mDns.rawQuery(network, blob, FLAG_EMPTY, mExecutor, cancelSignal, callback); + mDns.rawQuery(network, TEST_BLOB, FLAG_EMPTY, mExecutor, cancelSignal, callback); mExecutor.execute(() -> { cancelSignal.cancel(); latch.countDown(); }); - try { - retry = callback.needRetry(); - assertTrue(msg + " cancel is not done", - latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - } catch (InterruptedException e) { - fail(msg + " Waiting for DNS lookup was interrupted"); - } + + retry = callback.needRetry(); + assertTrue(msg + " cancel is not done", + latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); } while (retry); } } - public void testCancelBeforeQuery() throws ErrnoException { - final String dname = "www.google.com"; - final String msg = "Test cancelled RawQuery " + dname; + public void testCancelBeforeQuery() throws InterruptedException { + final String msg = "Test cancelled RawQuery " + TEST_DOMAIN; for (Network network : getTestableNetworks()) { final VerifyCancelCallback callback = new VerifyCancelCallback(msg); final CancellationSignal cancelSignal = new CancellationSignal(); cancelSignal.cancel(); - mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_EMPTY, + mDns.rawQuery(network, TEST_DOMAIN, CLASS_IN, TYPE_AAAA, FLAG_EMPTY, mExecutor, cancelSignal, callback); - try { - assertTrue(msg + " should not return any answers", - !callback.waitForAnswer(CANCEL_TIMEOUT_MS)); - } catch (InterruptedException e) { - fail(msg + " Waiting for DNS lookup was interrupted"); - } + + assertTrue(msg + " should not return any answers", + !callback.waitForAnswer(CANCEL_TIMEOUT_MS)); } } @@ -462,27 +474,21 @@ public class DnsResolverTest extends AndroidTestCase { } } - public void testQueryForInetAddress() { - final String dname = "www.google.com"; - final String msg = "Test query for InetAddress " + dname; + public void testQueryForInetAddress() throws InterruptedException { + final String msg = "Test query for InetAddress " + TEST_DOMAIN; for (Network network : getTestableNetworks()) { final VerifyCancelInetAddressCallback callback = new VerifyCancelInetAddressCallback(msg, null); - mDns.query(network, dname, FLAG_NO_CACHE_LOOKUP, - mExecutor, null, callback); - try { - assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", - callback.waitForAnswer()); - assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty()); - } catch (InterruptedException e) { - fail(msg + " Waiting for DNS lookup was interrupted"); - } + mDns.query(network, TEST_DOMAIN, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); + + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + callback.waitForAnswer()); + assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty()); } } - public void testQueryCancelForInetAddress() throws ErrnoException { - final String dname = "www.google.com"; - final String msg = "Test cancel query for InetAddress " + dname; + public void testQueryCancelForInetAddress() throws InterruptedException { + final String msg = "Test cancel query for InetAddress " + TEST_DOMAIN; // Start a DNS query and the cancel it immediately. Use VerifyCancelInetAddressCallback to // expect that the query is cancelled before it succeeds. If it is not cancelled before it // succeeds, retry the test until it is. @@ -497,57 +503,131 @@ public class DnsResolverTest extends AndroidTestCase { final CancellationSignal cancelSignal = new CancellationSignal(); final VerifyCancelInetAddressCallback callback = new VerifyCancelInetAddressCallback(msg, cancelSignal); - mDns.query(network, dname, FLAG_EMPTY, mExecutor, cancelSignal, callback); + mDns.query(network, TEST_DOMAIN, FLAG_EMPTY, mExecutor, cancelSignal, callback); mExecutor.execute(() -> { cancelSignal.cancel(); latch.countDown(); }); - try { - retry = callback.needRetry(); - assertTrue(msg + " query was not cancelled", - latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - } catch (InterruptedException e) { - fail(msg + " Waiting for DNS lookup was interrupted"); - } + + retry = callback.needRetry(); + assertTrue(msg + " query was not cancelled", + latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); } while (retry); } } - public void testQueryForInetAddressIpv4() { - final String dname = "www.google.com"; - final String msg = "Test query for IPv4 InetAddress " + dname; + public void testQueryForInetAddressIpv4() throws InterruptedException { + final String msg = "Test query for IPv4 InetAddress " + TEST_DOMAIN; for (Network network : getTestableNetworks()) { final VerifyCancelInetAddressCallback callback = new VerifyCancelInetAddressCallback(msg, null); - mDns.query(network, dname, TYPE_A, FLAG_NO_CACHE_LOOKUP, + mDns.query(network, TEST_DOMAIN, TYPE_A, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); - try { - assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", - callback.waitForAnswer()); - assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty()); - assertTrue(msg + " returned Ipv6 results", !callback.hasIpv6Answer()); - } catch (InterruptedException e) { - fail(msg + " Waiting for DNS lookup was interrupted"); - } + + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + callback.waitForAnswer()); + assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty()); + assertTrue(msg + " returned Ipv6 results", !callback.hasIpv6Answer()); } } - public void testQueryForInetAddressIpv6() { - final String dname = "www.google.com"; - final String msg = "Test query for IPv6 InetAddress " + dname; + public void testQueryForInetAddressIpv6() throws InterruptedException { + final String msg = "Test query for IPv6 InetAddress " + TEST_DOMAIN; for (Network network : getTestableNetworks()) { final VerifyCancelInetAddressCallback callback = new VerifyCancelInetAddressCallback(msg, null); - mDns.query(network, dname, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, + mDns.query(network, TEST_DOMAIN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); - try { - assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", - callback.waitForAnswer()); - assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty()); - assertTrue(msg + " returned Ipv4 results", !callback.hasIpv4Answer()); - } catch (InterruptedException e) { - fail(msg + " Waiting for DNS lookup was interrupted"); + + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + callback.waitForAnswer()); + assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty()); + assertTrue(msg + " returned Ipv4 results", !callback.hasIpv4Answer()); + } + } + + private void awaitPrivateDnsSetting(@NonNull String msg, + @NonNull Network network, @NonNull String server) throws InterruptedException { + CountDownLatch latch = new CountDownLatch(1); + NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build(); + NetworkCallback callback = new NetworkCallback() { + @Override + public void onLinkPropertiesChanged(Network n, LinkProperties lp) { + if (network.equals(n) && server.equals(lp.getPrivateDnsServerName())) { + latch.countDown(); + } } + }; + mCM.registerNetworkCallback(request, callback); + assertTrue(msg, latch.await(PRIVATE_DNS_SETTING_TIMEOUT_MS, TimeUnit.MILLISECONDS)); + mCM.unregisterNetworkCallback(callback); + } + + public void testPrivateDnsBypass() throws InterruptedException { + 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); + + 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 + // private DNS bypassable network or bind one. + if (network == null) continue; + + // wait for private DNS setting propagating + awaitPrivateDnsSetting(msg + " wait private DNS setting timeout", + network, INVALID_PRIVATE_DNS_SERVER); + + final CountDownLatch latch = new CountDownLatch(1); + final DnsResolver.Callback> errorCallback = + new DnsResolver.Callback>() { + @Override + public void onAnswer(@NonNull List answerList, int rcode) { + fail(msg + " should not get valid answer"); + } + + @Override + public void onError(@NonNull DnsResolver.DnsException error) { + assertEquals(DnsResolver.ERROR_SYSTEM, error.code); + assertEquals(ETIMEDOUT, ((ErrnoException) error.getCause()).errno); + latch.countDown(); + } + }; + // Private DNS strict mode with invalid DNS server is set + // Expect no valid answer returned but ErrnoException with ETIMEDOUT + mDns.query(network, TEST_DOMAIN, FLAG_NO_CACHE_LOOKUP, mExecutor, null, errorCallback); + + assertTrue(msg + " invalid server round. No response after " + TIMEOUT_MS + "ms.", + latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); + + final VerifyCancelInetAddressCallback callback = + new VerifyCancelInetAddressCallback(msg, null); + // Bypass privateDns, expect query works fine + mDns.query(network.getPrivateDnsBypassingCopy(), + TEST_DOMAIN, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); + + assertTrue(msg + " bypass private DNS round. No answer after " + TIMEOUT_MS + "ms.", + callback.waitForAnswer()); + assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty()); + + // To ensure private DNS bypass still work even if passing null network. + // Bind process network with a private DNS bypassable network. + mCM.bindProcessToNetwork(network.getPrivateDnsBypassingCopy()); + final VerifyCancelInetAddressCallback callbackWithNullNetwork = + new VerifyCancelInetAddressCallback(msg + " with null network ", null); + mDns.query(null, + TEST_DOMAIN, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callbackWithNullNetwork); + + assertTrue(msg + " with null network bypass private DNS round. No answer after " + + TIMEOUT_MS + "ms.", callbackWithNullNetwork.waitForAnswer()); + assertTrue(msg + " with null network returned 0 results", + !callbackWithNullNetwork.isAnswerEmpty()); + + // Reset process network to default. + mCM.bindProcessToNetwork(null); } } } From 063b4e109e41ea63c52724f9a6e978aae25483aa Mon Sep 17 00:00:00 2001 From: junyulai Date: Tue, 28 May 2019 10:44:43 +0800 Subject: [PATCH 0639/1109] Fix keepalive CTS fail for devices with kernel older than 4.8 If kernel < 4.8 then it doesn't support get socket option TCP_REPAIR_WINDOW, thus TCP keepalive cannot be supported. However, it might still support NAT-T keepalive. Test TCP keepalive only if it is supported by kernel. Bug: 133652079 Test: atest android.net.cts.ConnectivityManagerTest#testMajorMinorVersionCompare \ android.net.cts.ConnectivityManagerTest#testSocketKeepaliveLimit \ android.net.cts.ConnectivityManagerTest#testSocketKeepaliveUnprivileged \ android.net.cts.ConnectivityManagerTest#testKeepaliveUnsupported \ android.net.cts.ConnectivityManagerTest#testCreateTcpKeepalive Change-Id: I3f8456deea2b4ded762a413c8e27b58ce54ce0aa --- .../net/cts/ConnectivityManagerTest.java | 178 ++++++++++++------ 1 file changed, 119 insertions(+), 59 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 4b2c5794ed..fd4fdebea4 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -59,6 +59,7 @@ import android.os.Looper; import android.os.MessageQueue; import android.os.SystemClock; import android.os.SystemProperties; +import android.os.VintfRuntimeInfo; import android.platform.test.annotations.AppModeFull; import android.provider.Settings; import android.system.Os; @@ -66,6 +67,7 @@ import android.system.OsConstants; import android.test.AndroidTestCase; import android.text.TextUtils; import android.util.Log; +import android.util.Pair; import androidx.test.InstrumentationRegistry; @@ -1107,30 +1109,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { keepalivesPerTransport, nc); } - private boolean isKeepaliveSupported() throws Exception { - final Network network = ensureWifiConnected(); - final Executor executor = mContext.getMainExecutor(); - final TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(); - try (Socket s = getConnectedSocket(network, TEST_HOST, - HTTP_PORT, KEEPALIVE_SOCKET_TIMEOUT_MS, AF_INET); - SocketKeepalive sk = mCm.createSocketKeepalive(network, s, executor, callback)) { - sk.start(MIN_KEEPALIVE_INTERVAL); - final TestSocketKeepaliveCallback.CallbackValue result = callback.pollCallback(); - switch (result.callbackType) { - case ON_STARTED: - sk.stop(); - callback.expectStopped(); - return true; - case ON_ERROR: - if (result.error == SocketKeepalive.ERROR_UNSUPPORTED) return false; - // else fallthrough. - default: - fail("Got unexpected callback: " + result); - return false; - } - } - } - private void adoptShellPermissionIdentity() { mUiAutomation.adoptShellPermissionIdentity(); mShellPermissionIdentityAdopted = true; @@ -1143,11 +1121,85 @@ public class ConnectivityManagerTest extends AndroidTestCase { } } + private static boolean isTcpKeepaliveSupportedByKernel() { + final String kVersionString = VintfRuntimeInfo.getKernelVersion(); + return compareMajorMinorVersion(kVersionString, "4.8") >= 0; + } + + private static Pair getVersionFromString(String version) { + // Only gets major and minor number of the version string. + final Pattern versionPattern = Pattern.compile("^(\\d+)(\\.(\\d+))?.*"); + final Matcher m = versionPattern.matcher(version); + if (m.matches()) { + final int major = Integer.parseInt(m.group(1)); + final int minor = TextUtils.isEmpty(m.group(3)) ? 0 : Integer.parseInt(m.group(3)); + return new Pair<>(major, minor); + } else { + return new Pair<>(0, 0); + } + } + + // TODO: Move to util class. + private static int compareMajorMinorVersion(final String s1, final String s2) { + final Pair v1 = getVersionFromString(s1); + final Pair v2 = getVersionFromString(s2); + + if (v1.first == v2.first) { + return Integer.compare(v1.second, v2.second); + } else { + return Integer.compare(v1.first, v2.first); + } + } + + /** + * Verifies that version string compare logic returns expected result for various cases. + * Note that only major and minor number are compared. + */ + public void testMajorMinorVersionCompare() { + assertEquals(0, compareMajorMinorVersion("4.8.1", "4.8")); + assertEquals(1, compareMajorMinorVersion("4.9", "4.8.1")); + assertEquals(1, compareMajorMinorVersion("5.0", "4.8")); + assertEquals(1, compareMajorMinorVersion("5", "4.8")); + assertEquals(0, compareMajorMinorVersion("5", "5.0")); + assertEquals(1, compareMajorMinorVersion("5-beta1", "4.8")); + assertEquals(0, compareMajorMinorVersion("4.8.0.0", "4.8")); + assertEquals(0, compareMajorMinorVersion("4.8-RC1", "4.8")); + assertEquals(0, compareMajorMinorVersion("4.8", "4.8")); + assertEquals(-1, compareMajorMinorVersion("3.10", "4.8.0")); + assertEquals(-1, compareMajorMinorVersion("4.7.10.10", "4.8")); + } + + /** + * Verifies that the keepalive API cannot create any keepalive when the maximum number of + * keepalives is set to 0. + */ + @AppModeFull(reason = "Cannot get WifiManager in instant app mode") + public void testKeepaliveUnsupported() throws Exception { + if (getSupportedKeepalivesFromRes() != 0) return; + + adoptShellPermissionIdentity(); + + assertEquals(0, createConcurrentSocketKeepalives(1, 0)); + assertEquals(0, createConcurrentSocketKeepalives(0, 1)); + + dropShellPermissionIdentity(); + } + @AppModeFull(reason = "Cannot get WifiManager in instant app mode") public void testCreateTcpKeepalive() throws Exception { adoptShellPermissionIdentity(); - if (!isKeepaliveSupported()) return; + if (getSupportedKeepalivesFromRes() == 0) return; + // If kernel < 4.8 then it doesn't support TCP keepalive, but it might still support + // NAT-T keepalive. If keepalive limits from resource overlay is not zero, TCP keepalive + // needs to be supported except if the kernel doesn't support it. + if (!isTcpKeepaliveSupportedByKernel()) { + // Sanity check to ensure the callback result is expected. + assertEquals(0, createConcurrentSocketKeepalives(0, 1)); + Log.i(TAG, "testCreateTcpKeepalive is skipped for kernel " + + VintfRuntimeInfo.getKernelVersion()); + return; + } final Network network = ensureWifiConnected(); final byte[] requestBytes = HTTP_REQUEST.getBytes("UTF-8"); @@ -1212,14 +1264,16 @@ public class ConnectivityManagerTest extends AndroidTestCase { sk.start(MIN_KEEPALIVE_INTERVAL); callback.expectError(SocketKeepalive.ERROR_SOCKET_NOT_IDLE); } - } } + /** + * Creates concurrent keepalives until the specified counts of each type of keepalives are + * reached or the expected error callbacks are received for each type of keepalives. + * + * @return the total number of keepalives created. + */ private int createConcurrentSocketKeepalives(int nattCount, int tcpCount) throws Exception { - // Use customization value in resource to prevent the need of privilege. - if (getSupportedKeepalivesFromRes() == 0) return 0; - final Network network = ensureWifiConnected(); final ArrayList kalist = new ArrayList<>(); @@ -1238,10 +1292,14 @@ public class ConnectivityManagerTest extends AndroidTestCase { ka.start(MIN_KEEPALIVE_INTERVAL); TestSocketKeepaliveCallback.CallbackValue cv = callback.pollCallback(); assertNotNull(cv); - if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_ERROR - && cv.error == SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES) { - // Limit reached. - break; + if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_ERROR) { + if (i == 0 && cv.error == SocketKeepalive.ERROR_UNSUPPORTED) { + // Unsupported. + break; + } else if (i != 0 && cv.error == SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES) { + // Limit reached. + break; + } } if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_STARTED) { kalist.add(ka); @@ -1267,10 +1325,14 @@ public class ConnectivityManagerTest extends AndroidTestCase { ka.start(MIN_KEEPALIVE_INTERVAL); TestSocketKeepaliveCallback.CallbackValue cv = callback.pollCallback(); assertNotNull(cv); - if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_ERROR - && cv.error == SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES) { - // Limit reached. - break; + if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_ERROR) { + if (i == 0 && cv.error == SocketKeepalive.ERROR_UNSUPPORTED) { + // Unsupported. + break; + } else if (i != 0 && cv.error == SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES) { + // Limit reached. + break; + } } if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_STARTED) { kalist.add(ka); @@ -1298,32 +1360,35 @@ public class ConnectivityManagerTest extends AndroidTestCase { */ @AppModeFull(reason = "Cannot get WifiManager in instant app mode") public void testSocketKeepaliveLimit() throws Exception { - adoptShellPermissionIdentity(); - final int supported = getSupportedKeepalivesFromRes(); - - if (!isKeepaliveSupported()) { - // Sanity check. - assertEquals(0, supported); + if (supported == 0) { return; } + adoptShellPermissionIdentity(); + // Verifies that the supported keepalive slots meet MIN_SUPPORTED_KEEPALIVE_COUNT. assertGreaterOrEqual(supported, KeepaliveUtils.MIN_SUPPORTED_KEEPALIVE_COUNT); - // Verifies that different types of keepalives can be established. + // Verifies that Nat-T keepalives can be established. assertEquals(supported, createConcurrentSocketKeepalives(supported + 1, 0)); - assertEquals(supported, createConcurrentSocketKeepalives(0, supported + 1)); - - // Verifies that different types can be established at the same time. - assertEquals(supported, createConcurrentSocketKeepalives( - supported / 2, supported - supported / 2)); - // Verifies that keepalives don't get leaked in second round. assertEquals(supported, createConcurrentSocketKeepalives(supported + 1, 0)); - assertEquals(supported, createConcurrentSocketKeepalives(0, supported + 1)); - assertEquals(supported, createConcurrentSocketKeepalives( - supported / 2, supported - supported / 2)); + + // If kernel < 4.8 then it doesn't support TCP keepalive, but it might still support + // NAT-T keepalive. Test below cases only if TCP keepalive is supported by kernel. + if (isTcpKeepaliveSupportedByKernel()) { + assertEquals(supported, createConcurrentSocketKeepalives(0, supported + 1)); + + // Verifies that different types can be established at the same time. + assertEquals(supported, createConcurrentSocketKeepalives( + supported / 2, supported - supported / 2)); + + // Verifies that keepalives don't get leaked in second round. + assertEquals(supported, createConcurrentSocketKeepalives(0, supported + 1)); + assertEquals(supported, createConcurrentSocketKeepalives( + supported / 2, supported - supported / 2)); + } dropShellPermissionIdentity(); } @@ -1334,14 +1399,9 @@ public class ConnectivityManagerTest extends AndroidTestCase { @AppModeFull(reason = "Cannot get WifiManager in instant app mode") public void testSocketKeepaliveUnprivileged() throws Exception { final int supported = getSupportedKeepalivesFromRes(); - - adoptShellPermissionIdentity(); - if (!isKeepaliveSupported()) { - // Sanity check. - assertEquals(0, supported); + if (supported == 0) { return; } - dropShellPermissionIdentity(); final int allowedUnprivilegedPerUid = mContext.getResources().getInteger( R.integer.config_allowedUnprivilegedKeepalivePerUid); From 3cdc25cbc47e08c1f216f18cdedeb3a9337301e7 Mon Sep 17 00:00:00 2001 From: paulhu Date: Thu, 23 May 2019 19:16:47 +0800 Subject: [PATCH 0640/1109] Fix ConnectivityManagerApi23Test failures and remove duplication. 1. All ConnectivityManagerApi23Test were failed due to WifiManager#setWifiEnabled doesn't allow to use since Android Q. So we need to use shell command to enable/disable Wi-Fi instead. 2. Some methods are duplicated between ConnectivityManagerApi23Test and ConnectivityManagerTest, but they are not identical. So put these methods into ConnectivityUtils to clean up duplications and prevent fork happened again. Bug: 133334943 Bug: 133209319 Test: Run the below tests on Crosshatch, Sailfish, Bonito. atest CtsNetApi23TestCases atest CtsNetTestCases Change-Id: Ic37111cb12a46f5c36c2be887250c5d762216f6e --- tests/cts/net/Android.bp | 1 + tests/cts/net/api23Test/Android.bp | 1 + .../ConnectivityManagerApi23Test.java | 279 +------------- .../net/cts/ConnectivityManagerTest.java | 299 +-------------- tests/cts/net/util/Android.bp | 25 ++ .../android/net/cts/util/CtsNetUtils.java | 353 ++++++++++++++++++ 6 files changed, 405 insertions(+), 553 deletions(-) create mode 100644 tests/cts/net/util/Android.bp create mode 100644 tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java diff --git a/tests/cts/net/Android.bp b/tests/cts/net/Android.bp index 779d5c4be2..b6ea4afe80 100644 --- a/tests/cts/net/Android.bp +++ b/tests/cts/net/Android.bp @@ -42,6 +42,7 @@ android_test { "FrameworksNetCommonTests", "core-tests-support", "compatibility-device-util-axt", + "cts-net-utils", "ctstestrunner-axt", "ctstestserver", "mockwebserver", diff --git a/tests/cts/net/api23Test/Android.bp b/tests/cts/net/api23Test/Android.bp index 48161cf7e7..ffe854e2e9 100644 --- a/tests/cts/net/api23Test/Android.bp +++ b/tests/cts/net/api23Test/Android.bp @@ -31,6 +31,7 @@ android_test { static_libs: [ "core-tests-support", "compatibility-device-util-axt", + "cts-net-utils", "ctstestrunner-axt", "ctstestserver", "mockwebserver", diff --git a/tests/cts/net/api23Test/src/android/net/cts/api23test/ConnectivityManagerApi23Test.java b/tests/cts/net/api23Test/src/android/net/cts/api23test/ConnectivityManagerApi23Test.java index f38490e60e..cdb66e3d5a 100644 --- a/tests/cts/net/api23Test/src/android/net/cts/api23test/ConnectivityManagerApi23Test.java +++ b/tests/cts/net/api23Test/src/android/net/cts/api23test/ConnectivityManagerApi23Test.java @@ -25,58 +25,33 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.net.ConnectivityManager; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.NetworkInfo; -import android.net.NetworkInfo.State; -import android.net.NetworkRequest; -import android.net.wifi.WifiManager; +import android.net.cts.util.CtsNetUtils; import android.os.Looper; -import android.system.Os; -import android.system.OsConstants; import android.test.AndroidTestCase; import android.util.Log; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; public class ConnectivityManagerApi23Test extends AndroidTestCase { private static final String TAG = ConnectivityManagerApi23Test.class.getSimpleName(); - - private static final String TEST_HOST = "connectivitycheck.gstatic.com"; - private static final int SOCKET_TIMEOUT_MS = 2000; private static final int SEND_BROADCAST_TIMEOUT = 30000; - private static final int HTTP_PORT = 80; // Intent string to get the number of wifi CONNECTIVITY_ACTION callbacks the test app has seen public static final String GET_WIFI_CONNECTIVITY_ACTION_COUNT = "android.net.cts.appForApi23.getWifiConnectivityActionCount"; // Action sent to ConnectivityActionReceiver when a network callback is sent via PendingIntent. - private static final String NETWORK_CALLBACK_ACTION = - "ConnectivityManagerTest.NetworkCallbackAction"; - private static final String HTTP_REQUEST = - "GET /generate_204 HTTP/1.0\r\n" + - "Host: " + TEST_HOST + "\r\n" + - "Connection: keep-alive\r\n\r\n"; private Context mContext; - private ConnectivityManager mCm; - private WifiManager mWifiManager; private PackageManager mPackageManager; + private CtsNetUtils mCtsNetUtils; @Override protected void setUp() throws Exception { super.setUp(); Looper.prepare(); mContext = getContext(); - mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); - mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); mPackageManager = mContext.getPackageManager(); + mCtsNetUtils = new CtsNetUtils(mContext); } /** @@ -89,7 +64,7 @@ public class ConnectivityManagerApi23Test extends AndroidTestCase { } ConnectivityReceiver.prepare(); - toggleWifi(); + mCtsNetUtils.toggleWifi(); // The connectivity broadcast has been sent; push through a terminal broadcast // to wait for in the receive to confirm it didn't see the connectivity change. @@ -112,7 +87,7 @@ public class ConnectivityManagerApi23Test extends AndroidTestCase { .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); Thread.sleep(200); - toggleWifi(); + mCtsNetUtils.toggleWifi(); Intent getConnectivityCount = new Intent(GET_WIFI_CONNECTIVITY_ACTION_COUNT); assertEquals(2, sendOrderedBroadcastAndReturnResultCode( @@ -130,7 +105,7 @@ public class ConnectivityManagerApi23Test extends AndroidTestCase { filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); mContext.registerReceiver(receiver, filter); - toggleWifi(); + mCtsNetUtils.toggleWifi(); Intent finalIntent = new Intent(ConnectivityReceiver.FINAL_ACTION); finalIntent.setClass(mContext, ConnectivityReceiver.class); mContext.sendBroadcast(finalIntent); @@ -138,19 +113,6 @@ public class ConnectivityManagerApi23Test extends AndroidTestCase { assertTrue(ConnectivityReceiver.waitForBroadcast()); } - // Toggle WiFi twice, leaving it in the state it started in - private void toggleWifi() { - if (mWifiManager.isWifiEnabled()) { - Network wifiNetwork = getWifiNetwork(); - disconnectFromWifi(wifiNetwork); - connectToWifi(); - } else { - connectToWifi(); - Network wifiNetwork = getWifiNetwork(); - disconnectFromWifi(wifiNetwork); - } - } - private int sendOrderedBroadcastAndReturnResultCode( Intent intent, int timeoutMs) throws InterruptedException { final LinkedBlockingQueue result = new LinkedBlockingQueue<>(1); @@ -167,233 +129,4 @@ public class ConnectivityManagerApi23Test extends AndroidTestCase { return resultCode; } - private Network getWifiNetwork() { - TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); - Network network = null; - try { - network = callback.waitForAvailable(); - } catch (InterruptedException e) { - fail("NetworkCallback wait was interrupted."); - } finally { - mCm.unregisterNetworkCallback(callback); - } - assertNotNull("Cannot find Network for wifi. Is wifi connected?", network); - return network; - } - - /** Disable WiFi and wait for it to become disconnected from the network. */ - private void disconnectFromWifi(Network wifiNetworkToCheck) { - final TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); - Network lostWifiNetwork = null; - - ConnectivityActionReceiver receiver = new ConnectivityActionReceiver( - ConnectivityManager.TYPE_WIFI, NetworkInfo.State.DISCONNECTED); - IntentFilter filter = new IntentFilter(); - filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); - mContext.registerReceiver(receiver, filter); - - // Assert that we can establish a TCP connection on wifi. - Socket wifiBoundSocket = null; - if (wifiNetworkToCheck != null) { - try { - wifiBoundSocket = getBoundSocket(wifiNetworkToCheck, TEST_HOST, HTTP_PORT); - testHttpRequest(wifiBoundSocket); - } catch (IOException e) { - fail("HTTP request before wifi disconnected failed with: " + e); - } - } - - boolean disconnected = false; - try { - assertTrue(mWifiManager.setWifiEnabled(false)); - // Ensure we get both an onLost callback and a CONNECTIVITY_ACTION. - lostWifiNetwork = callback.waitForLost(); - assertNotNull(lostWifiNetwork); - disconnected = receiver.waitForState(); - } catch (InterruptedException ex) { - fail("disconnectFromWifi was interrupted"); - } finally { - mCm.unregisterNetworkCallback(callback); - mContext.unregisterReceiver(receiver); - } - - assertTrue("Wifi failed to reach DISCONNECTED state.", disconnected); - - // Check that the socket is closed when wifi disconnects. - if (wifiBoundSocket != null) { - try { - testHttpRequest(wifiBoundSocket); - fail("HTTP request should not succeed after wifi disconnects"); - } catch (IOException expected) { - assertEquals(Os.strerror(OsConstants.ECONNABORTED), expected.getMessage()); - } - } - } - - /** Enable WiFi and wait for it to become connected to a network. */ - private Network connectToWifi() { - final TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); - Network wifiNetwork = null; - - ConnectivityActionReceiver receiver = new ConnectivityActionReceiver( - ConnectivityManager.TYPE_WIFI, NetworkInfo.State.CONNECTED); - IntentFilter filter = new IntentFilter(); - filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); - mContext.registerReceiver(receiver, filter); - - boolean connected = false; - try { - assertTrue(mWifiManager.setWifiEnabled(true)); - // Ensure we get both an onAvailable callback and a CONNECTIVITY_ACTION. - wifiNetwork = callback.waitForAvailable(); - assertNotNull(wifiNetwork); - connected = receiver.waitForState(); - } catch (InterruptedException ex) { - fail("connectToWifi was interrupted"); - } finally { - mCm.unregisterNetworkCallback(callback); - mContext.unregisterReceiver(receiver); - } - - assertTrue("Wifi must be configured to connect to an access point for this test.", - connected); - return wifiNetwork; - } - - private NetworkRequest makeWifiNetworkRequest() { - return new NetworkRequest.Builder() - .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) - .build(); - } - - private void testHttpRequest(Socket s) throws IOException { - OutputStream out = s.getOutputStream(); - InputStream in = s.getInputStream(); - - final byte[] requestBytes = HTTP_REQUEST.getBytes("UTF-8"); - byte[] responseBytes = new byte[4096]; - out.write(requestBytes); - in.read(responseBytes); - assertTrue(new String(responseBytes, "UTF-8").startsWith("HTTP/1.0 204 No Content\r\n")); - } - - private Socket getBoundSocket(Network network, String host, int port) throws IOException { - InetSocketAddress addr = new InetSocketAddress(host, port); - Socket s = network.getSocketFactory().createSocket(); - try { - s.setSoTimeout(SOCKET_TIMEOUT_MS); - s.connect(addr, SOCKET_TIMEOUT_MS); - } catch (IOException e) { - s.close(); - throw e; - } - return s; - } - - /** - * Receiver that captures the last connectivity change's network type and state. Recognizes - * both {@code CONNECTIVITY_ACTION} and {@code NETWORK_CALLBACK_ACTION} intents. - */ - private class ConnectivityActionReceiver extends BroadcastReceiver { - - private final CountDownLatch mReceiveLatch = new CountDownLatch(1); - - private final int mNetworkType; - private final NetworkInfo.State mNetState; - - ConnectivityActionReceiver(int networkType, NetworkInfo.State netState) { - mNetworkType = networkType; - mNetState = netState; - } - - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - NetworkInfo networkInfo = null; - - // When receiving ConnectivityManager.CONNECTIVITY_ACTION, the NetworkInfo parcelable - // is stored in EXTRA_NETWORK_INFO. With a NETWORK_CALLBACK_ACTION, the Network is - // sent in EXTRA_NETWORK and we need to ask the ConnectivityManager for the NetworkInfo. - if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) { - networkInfo = intent.getExtras() - .getParcelable(ConnectivityManager.EXTRA_NETWORK_INFO); - assertNotNull("ConnectivityActionReceiver expected EXTRA_NETWORK_INFO", networkInfo); - } else if (NETWORK_CALLBACK_ACTION.equals(action)) { - Network network = intent.getExtras() - .getParcelable(ConnectivityManager.EXTRA_NETWORK); - assertNotNull("ConnectivityActionReceiver expected EXTRA_NETWORK", network); - networkInfo = mCm.getNetworkInfo(network); - if (networkInfo == null) { - // When disconnecting, it seems like we get an intent sent with an invalid - // Network; that is, by the time we call ConnectivityManager.getNetworkInfo(), - // it is invalid. Ignore these. - Log.i(TAG, "ConnectivityActionReceiver NETWORK_CALLBACK_ACTION ignoring " - + "invalid network"); - return; - } - } else { - fail("ConnectivityActionReceiver received unxpected intent action: " + action); - } - - assertNotNull("ConnectivityActionReceiver didn't find NetworkInfo", networkInfo); - int networkType = networkInfo.getType(); - State networkState = networkInfo.getState(); - Log.i(TAG, "Network type: " + networkType + " state: " + networkState); - if (networkType == mNetworkType && networkInfo.getState() == mNetState) { - mReceiveLatch.countDown(); - } - } - - public boolean waitForState() throws InterruptedException { - return mReceiveLatch.await(30, TimeUnit.SECONDS); - } - } - - /** - * Callback used in testRegisterNetworkCallback that allows caller to block on - * {@code onAvailable}. - */ - private static class TestNetworkCallback extends ConnectivityManager.NetworkCallback { - private final CountDownLatch mAvailableLatch = new CountDownLatch(1); - private final CountDownLatch mLostLatch = new CountDownLatch(1); - private final CountDownLatch mUnavailableLatch = new CountDownLatch(1); - - public Network currentNetwork; - public Network lastLostNetwork; - - public Network waitForAvailable() throws InterruptedException { - return mAvailableLatch.await(30, TimeUnit.SECONDS) ? currentNetwork : null; - } - - public Network waitForLost() throws InterruptedException { - return mLostLatch.await(30, TimeUnit.SECONDS) ? lastLostNetwork : null; - } - - public boolean waitForUnavailable() throws InterruptedException { - return mUnavailableLatch.await(2, TimeUnit.SECONDS); - } - - - @Override - public void onAvailable(Network network) { - currentNetwork = network; - mAvailableLatch.countDown(); - } - - @Override - public void onLost(Network network) { - lastLostNetwork = network; - if (network.equals(currentNetwork)) { - currentNetwork = null; - } - mLostLatch.countDown(); - } - - @Override - public void onUnavailable() { - mUnavailableLatch.countDown(); - } - } } \ No newline at end of file diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index c444445b2a..c3ae793aae 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -21,8 +21,12 @@ import static android.content.pm.PackageManager.FEATURE_WIFI; import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; -import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; +import static android.net.cts.util.CtsNetUtils.ConnectivityActionReceiver; +import static android.net.cts.util.CtsNetUtils.HTTP_PORT; +import static android.net.cts.util.CtsNetUtils.NETWORK_CALLBACK_ACTION; +import static android.net.cts.util.CtsNetUtils.TEST_HOST; +import static android.net.cts.util.CtsNetUtils.TestNetworkCallback; import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT; import static android.provider.Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE; import static android.system.OsConstants.AF_INET; @@ -34,7 +38,6 @@ import static com.android.compatibility.common.util.SystemUtil.runShellCommand; import android.app.Instrumentation; import android.app.PendingIntent; import android.app.UiAutomation; -import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; @@ -53,6 +56,7 @@ import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; import android.net.NetworkRequest; import android.net.SocketKeepalive; +import android.net.cts.util.CtsNetUtils; import android.net.util.KeepaliveUtils; import android.net.wifi.WifiManager; import android.os.Looper; @@ -61,15 +65,12 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.platform.test.annotations.AppModeFull; import android.provider.Settings; -import android.system.Os; -import android.system.OsConstants; import android.test.AndroidTestCase; import android.text.TextUtils; import android.util.Log; import androidx.test.InstrumentationRegistry; -import com.android.compatibility.common.util.SystemUtil; import com.android.internal.R; import com.android.internal.telephony.PhoneConstants; @@ -107,8 +108,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI; private static final int HOST_ADDRESS = 0x7f000001;// represent ip 127.0.0.1 - private static final String TEST_HOST = "connectivitycheck.gstatic.com"; - private static final int SOCKET_TIMEOUT_MS = 2000; private static final int CONNECT_TIMEOUT_MS = 2000; private static final int KEEPALIVE_CALLBACK_TIMEOUT_MS = 2000; private static final int KEEPALIVE_SOCKET_TIMEOUT_MS = 5000; @@ -116,16 +115,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { private static final int NETWORK_CHANGE_METEREDNESS_TIMEOUT = 5000; private static final int NUM_TRIES_MULTIPATH_PREF_CHECK = 20; private static final long INTERVAL_MULTIPATH_PREF_CHECK_MS = 500; - private static final int HTTP_PORT = 80; - private static final String HTTP_REQUEST = - "GET /generate_204 HTTP/1.0\r\n" + - "Host: " + TEST_HOST + "\r\n" + - "Connection: keep-alive\r\n\r\n"; - - // Action sent to ConnectivityActionReceiver when a network callback is sent via PendingIntent. - private static final String NETWORK_CALLBACK_ACTION = - "ConnectivityManagerTest.NetworkCallbackAction"; - // device could have only one interface: data, wifi. private static final int MIN_NUM_NETWORK_TYPES = 1; @@ -137,8 +126,8 @@ public class ConnectivityManagerTest extends AndroidTestCase { private final HashMap mNetworks = new HashMap(); boolean mWifiConnectAttempted; - private TestNetworkCallback mCellNetworkCallback; private UiAutomation mUiAutomation; + private CtsNetUtils mCtsNetUtils; private boolean mShellPermissionIdentityAdopted; @Override @@ -150,6 +139,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); mPackageManager = mContext.getPackageManager(); + mCtsNetUtils = new CtsNetUtils(mContext); mWifiConnectAttempted = false; // Get com.android.internal.R.array.networkAttributes @@ -174,10 +164,10 @@ public class ConnectivityManagerTest extends AndroidTestCase { protected void tearDown() throws Exception { // Return WiFi to its original disabled state after tests that explicitly connect. if (mWifiConnectAttempted) { - disconnectFromWifi(null); + mCtsNetUtils.disconnectFromWifi(null); } - if (cellConnectAttempted()) { - disconnectFromCell(); + if (mCtsNetUtils.cellConnectAttempted()) { + mCtsNetUtils.disconnectFromCell(); } dropShellPermissionIdentity(); super.tearDown(); @@ -190,10 +180,10 @@ public class ConnectivityManagerTest extends AndroidTestCase { */ private Network ensureWifiConnected() { if (mWifiManager.isWifiEnabled()) { - return getWifiNetwork(); + return mCtsNetUtils.getWifiNetwork(); } mWifiConnectAttempted = true; - return connectToWifi(); + return mCtsNetUtils.connectToWifi(); } public void testIsNetworkTypeValid() { @@ -301,8 +291,8 @@ public class ConnectivityManagerTest extends AndroidTestCase { return; } - Network wifiNetwork = connectToWifi(); - Network cellNetwork = connectToCell(); + Network wifiNetwork = mCtsNetUtils.connectToWifi(); + Network cellNetwork = mCtsNetUtils.connectToCell(); // This server returns the requestor's IP address as the response body. URL url = new URL("http://google-ipv6test.appspot.com/ip.js?fmt=text"); String wifiAddressString = httpGet(wifiNetwork, url); @@ -320,33 +310,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { assertFalse("Unexpectedly equal: " + wifiNetwork, wifiNetwork.equals(cellNetwork)); } - private Network connectToCell() throws InterruptedException { - if (cellConnectAttempted()) { - throw new IllegalStateException("Already connected"); - } - NetworkRequest cellRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_CELLULAR) - .addCapability(NET_CAPABILITY_INTERNET) - .build(); - mCellNetworkCallback = new TestNetworkCallback(); - mCm.requestNetwork(cellRequest, mCellNetworkCallback); - final Network cellNetwork = mCellNetworkCallback.waitForAvailable(); - assertNotNull("Cell network not available within timeout", cellNetwork); - return cellNetwork; - } - - private boolean cellConnectAttempted() { - return mCellNetworkCallback != null; - } - - private void disconnectFromCell() { - if (!cellConnectAttempted()) { - throw new IllegalStateException("Cell connection not attempted"); - } - mCm.unregisterNetworkCallback(mCellNetworkCallback); - mCellNetworkCallback = null; - } - /** * Performs a HTTP GET to the specified URL on the specified Network, and returns * the response body decoded as UTF-8. @@ -508,7 +471,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { filter.addAction(NETWORK_CALLBACK_ACTION); ConnectivityActionReceiver receiver = new ConnectivityActionReceiver( - ConnectivityManager.TYPE_WIFI, NetworkInfo.State.CONNECTED); + mCm, ConnectivityManager.TYPE_WIFI, NetworkInfo.State.CONNECTED); mContext.registerReceiver(receiver, filter); // Create a broadcast PendingIntent for NETWORK_CALLBACK_ACTION. @@ -567,7 +530,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { public void testRequestNetworkCallback_onUnavailable() { final boolean previousWifiEnabledState = mWifiManager.isWifiEnabled(); if (previousWifiEnabledState) { - disconnectFromWifi(null); + mCtsNetUtils.disconnectFromWifi(null); } final TestNetworkCallback callback = new TestNetworkCallback(); @@ -584,42 +547,11 @@ public class ConnectivityManagerTest extends AndroidTestCase { } finally { mCm.unregisterNetworkCallback(callback); if (previousWifiEnabledState) { - connectToWifi(); + mCtsNetUtils.connectToWifi(); } } } - /** Enable WiFi and wait for it to become connected to a network. */ - private Network connectToWifi() { - final TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); - Network wifiNetwork = null; - - ConnectivityActionReceiver receiver = new ConnectivityActionReceiver( - ConnectivityManager.TYPE_WIFI, NetworkInfo.State.CONNECTED); - IntentFilter filter = new IntentFilter(); - filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); - mContext.registerReceiver(receiver, filter); - - boolean connected = false; - try { - SystemUtil.runShellCommand("svc wifi enable"); - // Ensure we get both an onAvailable callback and a CONNECTIVITY_ACTION. - wifiNetwork = callback.waitForAvailable(); - assertNotNull(wifiNetwork); - connected = receiver.waitForState(); - } catch (InterruptedException ex) { - fail("connectToWifi was interrupted"); - } finally { - mCm.unregisterNetworkCallback(callback); - mContext.unregisterReceiver(receiver); - } - - assertTrue("Wifi must be configured to connect to an access point for this test.", - connected); - return wifiNetwork; - } - private InetAddress getFirstV4Address(Network network) { LinkProperties linkProperties = mCm.getLinkProperties(network); for (InetAddress address : linkProperties.getAddresses()) { @@ -630,199 +562,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { return null; } - private Socket getBoundSocket(Network network, String host, int port) throws IOException { - InetSocketAddress addr = new InetSocketAddress(host, port); - Socket s = network.getSocketFactory().createSocket(); - try { - s.setSoTimeout(SOCKET_TIMEOUT_MS); - s.connect(addr, SOCKET_TIMEOUT_MS); - } catch (IOException e) { - s.close(); - throw e; - } - return s; - } - - private void testHttpRequest(Socket s) throws IOException { - OutputStream out = s.getOutputStream(); - InputStream in = s.getInputStream(); - - final byte[] requestBytes = HTTP_REQUEST.getBytes("UTF-8"); - byte[] responseBytes = new byte[4096]; - out.write(requestBytes); - in.read(responseBytes); - assertTrue(new String(responseBytes, "UTF-8").startsWith("HTTP/1.0 204 No Content\r\n")); - } - - /** Disable WiFi and wait for it to become disconnected from the network. */ - private void disconnectFromWifi(Network wifiNetworkToCheck) { - final TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); - Network lostWifiNetwork = null; - - ConnectivityActionReceiver receiver = new ConnectivityActionReceiver( - ConnectivityManager.TYPE_WIFI, NetworkInfo.State.DISCONNECTED); - IntentFilter filter = new IntentFilter(); - filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); - mContext.registerReceiver(receiver, filter); - - // Assert that we can establish a TCP connection on wifi. - Socket wifiBoundSocket = null; - if (wifiNetworkToCheck != null) { - try { - wifiBoundSocket = getBoundSocket(wifiNetworkToCheck, TEST_HOST, HTTP_PORT); - testHttpRequest(wifiBoundSocket); - } catch (IOException e) { - fail("HTTP request before wifi disconnected failed with: " + e); - } - } - - boolean disconnected = false; - try { - SystemUtil.runShellCommand("svc wifi disable"); - // Ensure we get both an onLost callback and a CONNECTIVITY_ACTION. - lostWifiNetwork = callback.waitForLost(); - assertNotNull(lostWifiNetwork); - disconnected = receiver.waitForState(); - } catch (InterruptedException ex) { - fail("disconnectFromWifi was interrupted"); - } finally { - mCm.unregisterNetworkCallback(callback); - mContext.unregisterReceiver(receiver); - } - - assertTrue("Wifi failed to reach DISCONNECTED state.", disconnected); - - // Check that the socket is closed when wifi disconnects. - if (wifiBoundSocket != null) { - try { - testHttpRequest(wifiBoundSocket); - fail("HTTP request should not succeed after wifi disconnects"); - } catch (IOException expected) { - assertEquals(Os.strerror(OsConstants.ECONNABORTED), expected.getMessage()); - } - } - } - - /** - * Receiver that captures the last connectivity change's network type and state. Recognizes - * both {@code CONNECTIVITY_ACTION} and {@code NETWORK_CALLBACK_ACTION} intents. - */ - private class ConnectivityActionReceiver extends BroadcastReceiver { - - private final CountDownLatch mReceiveLatch = new CountDownLatch(1); - - private final int mNetworkType; - private final NetworkInfo.State mNetState; - - ConnectivityActionReceiver(int networkType, NetworkInfo.State netState) { - mNetworkType = networkType; - mNetState = netState; - } - - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - NetworkInfo networkInfo = null; - - // When receiving ConnectivityManager.CONNECTIVITY_ACTION, the NetworkInfo parcelable - // is stored in EXTRA_NETWORK_INFO. With a NETWORK_CALLBACK_ACTION, the Network is - // sent in EXTRA_NETWORK and we need to ask the ConnectivityManager for the NetworkInfo. - if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) { - networkInfo = intent.getExtras() - .getParcelable(ConnectivityManager.EXTRA_NETWORK_INFO); - assertNotNull("ConnectivityActionReceiver expected EXTRA_NETWORK_INFO", networkInfo); - } else if (NETWORK_CALLBACK_ACTION.equals(action)) { - Network network = intent.getExtras() - .getParcelable(ConnectivityManager.EXTRA_NETWORK); - assertNotNull("ConnectivityActionReceiver expected EXTRA_NETWORK", network); - networkInfo = mCm.getNetworkInfo(network); - if (networkInfo == null) { - // When disconnecting, it seems like we get an intent sent with an invalid - // Network; that is, by the time we call ConnectivityManager.getNetworkInfo(), - // it is invalid. Ignore these. - Log.i(TAG, "ConnectivityActionReceiver NETWORK_CALLBACK_ACTION ignoring " - + "invalid network"); - return; - } - } else { - fail("ConnectivityActionReceiver received unxpected intent action: " + action); - } - - assertNotNull("ConnectivityActionReceiver didn't find NetworkInfo", networkInfo); - int networkType = networkInfo.getType(); - State networkState = networkInfo.getState(); - Log.i(TAG, "Network type: " + networkType + " state: " + networkState); - if (networkType == mNetworkType && networkInfo.getState() == mNetState) { - mReceiveLatch.countDown(); - } - } - - public boolean waitForState() throws InterruptedException { - return mReceiveLatch.await(30, TimeUnit.SECONDS); - } - } - - /** - * Callback used in testRegisterNetworkCallback that allows caller to block on - * {@code onAvailable}. - */ - private static class TestNetworkCallback extends ConnectivityManager.NetworkCallback { - private final CountDownLatch mAvailableLatch = new CountDownLatch(1); - private final CountDownLatch mLostLatch = new CountDownLatch(1); - private final CountDownLatch mUnavailableLatch = new CountDownLatch(1); - - public Network currentNetwork; - public Network lastLostNetwork; - - public Network waitForAvailable() throws InterruptedException { - return mAvailableLatch.await(30, TimeUnit.SECONDS) ? currentNetwork : null; - } - - public Network waitForLost() throws InterruptedException { - return mLostLatch.await(30, TimeUnit.SECONDS) ? lastLostNetwork : null; - } - - public boolean waitForUnavailable() throws InterruptedException { - return mUnavailableLatch.await(2, TimeUnit.SECONDS); - } - - - @Override - public void onAvailable(Network network) { - currentNetwork = network; - mAvailableLatch.countDown(); - } - - @Override - public void onLost(Network network) { - lastLostNetwork = network; - if (network.equals(currentNetwork)) { - currentNetwork = null; - } - mLostLatch.countDown(); - } - - @Override - public void onUnavailable() { - mUnavailableLatch.countDown(); - } - } - - private Network getWifiNetwork() { - TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); - Network network = null; - try { - network = callback.waitForAvailable(); - } catch (InterruptedException e) { - fail("NetworkCallback wait was interrupted."); - } finally { - mCm.unregisterNetworkCallback(callback); - } - assertNotNull("Cannot find Network for wifi. Is wifi connected?", network); - return network; - } - /** Verify restricted networks cannot be requested. */ @AppModeFull(reason = "CHANGE_NETWORK_STATE permission can't be granted to instant apps") public void testRestrictedNetworks() { @@ -1151,7 +890,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { if (!isKeepaliveSupported()) return; final Network network = ensureWifiConnected(); - final byte[] requestBytes = HTTP_REQUEST.getBytes("UTF-8"); + final byte[] requestBytes = CtsNetUtils.HTTP_REQUEST.getBytes("UTF-8"); // So far only ipv4 tcp keepalive offload is supported. // TODO: add test case for ipv6 tcp keepalive offload when it is supported. try (Socket s = getConnectedSocket(network, TEST_HOST, HTTP_PORT, diff --git a/tests/cts/net/util/Android.bp b/tests/cts/net/util/Android.bp new file mode 100644 index 0000000000..1f94613ffb --- /dev/null +++ b/tests/cts/net/util/Android.bp @@ -0,0 +1,25 @@ +// +// Copyright (C) 2019 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. +// + +// Common utilities for cts net tests. +java_library { + name: "cts-net-utils", + srcs: ["java/**/*.java", "java/**/*.kt"], + static_libs: [ + "compatibility-device-util-axt", + "junit", + ], +} \ No newline at end of file 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 new file mode 100644 index 0000000000..e19d2bafb7 --- /dev/null +++ b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java @@ -0,0 +1,353 @@ +/* + * Copyright (C) 2019 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.util; + +import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; +import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.ConnectivityManager; +import android.net.ConnectivityManager.NetworkCallback; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.NetworkInfo; +import android.net.NetworkInfo.State; +import android.net.NetworkRequest; +import android.net.wifi.WifiManager; +import android.system.Os; +import android.system.OsConstants; +import android.util.Log; + +import com.android.compatibility.common.util.SystemUtil; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +public final class CtsNetUtils { + private static final String TAG = CtsNetUtils.class.getSimpleName(); + private static final int DURATION = 10000; + private static final int SOCKET_TIMEOUT_MS = 2000; + + public static final int HTTP_PORT = 80; + public static final String TEST_HOST = "connectivitycheck.gstatic.com"; + public static final String HTTP_REQUEST = + "GET /generate_204 HTTP/1.0\r\n" + + "Host: " + TEST_HOST + "\r\n" + + "Connection: keep-alive\r\n\r\n"; + // Action sent to ConnectivityActionReceiver when a network callback is sent via PendingIntent. + public static final String NETWORK_CALLBACK_ACTION = + "ConnectivityManagerTest.NetworkCallbackAction"; + + private Context mContext; + private ConnectivityManager mCm; + private WifiManager mWifiManager; + private TestNetworkCallback mCellNetworkCallback; + + public CtsNetUtils(Context context) { + mContext = context; + mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); + mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); + } + + // Toggle WiFi twice, leaving it in the state it started in + public void toggleWifi() { + if (mWifiManager.isWifiEnabled()) { + Network wifiNetwork = getWifiNetwork(); + disconnectFromWifi(wifiNetwork); + connectToWifi(); + } else { + connectToWifi(); + Network wifiNetwork = getWifiNetwork(); + disconnectFromWifi(wifiNetwork); + } + } + + /** Enable WiFi and wait for it to become connected to a network. */ + public Network connectToWifi() { + final TestNetworkCallback callback = new TestNetworkCallback(); + mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); + Network wifiNetwork = null; + + ConnectivityActionReceiver receiver = new ConnectivityActionReceiver( + mCm, ConnectivityManager.TYPE_WIFI, NetworkInfo.State.CONNECTED); + IntentFilter filter = new IntentFilter(); + filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); + mContext.registerReceiver(receiver, filter); + + boolean connected = false; + try { + SystemUtil.runShellCommand("svc wifi enable"); + // Ensure we get both an onAvailable callback and a CONNECTIVITY_ACTION. + wifiNetwork = callback.waitForAvailable(); + assertNotNull(wifiNetwork); + connected = receiver.waitForState(); + } catch (InterruptedException ex) { + fail("connectToWifi was interrupted"); + } finally { + mCm.unregisterNetworkCallback(callback); + mContext.unregisterReceiver(receiver); + } + + assertTrue("Wifi must be configured to connect to an access point for this test.", + connected); + return wifiNetwork; + } + + /** Disable WiFi and wait for it to become disconnected from the network. */ + public void disconnectFromWifi(Network wifiNetworkToCheck) { + final TestNetworkCallback callback = new TestNetworkCallback(); + mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); + Network lostWifiNetwork = null; + + ConnectivityActionReceiver receiver = new ConnectivityActionReceiver( + mCm, ConnectivityManager.TYPE_WIFI, NetworkInfo.State.DISCONNECTED); + IntentFilter filter = new IntentFilter(); + filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); + mContext.registerReceiver(receiver, filter); + + // Assert that we can establish a TCP connection on wifi. + Socket wifiBoundSocket = null; + if (wifiNetworkToCheck != null) { + try { + wifiBoundSocket = getBoundSocket(wifiNetworkToCheck, TEST_HOST, HTTP_PORT); + testHttpRequest(wifiBoundSocket); + } catch (IOException e) { + fail("HTTP request before wifi disconnected failed with: " + e); + } + } + + boolean disconnected = false; + try { + SystemUtil.runShellCommand("svc wifi disable"); + // Ensure we get both an onLost callback and a CONNECTIVITY_ACTION. + lostWifiNetwork = callback.waitForLost(); + assertNotNull(lostWifiNetwork); + disconnected = receiver.waitForState(); + } catch (InterruptedException ex) { + fail("disconnectFromWifi was interrupted"); + } finally { + mCm.unregisterNetworkCallback(callback); + mContext.unregisterReceiver(receiver); + } + + assertTrue("Wifi failed to reach DISCONNECTED state.", disconnected); + + // Check that the socket is closed when wifi disconnects. + if (wifiBoundSocket != null) { + try { + testHttpRequest(wifiBoundSocket); + fail("HTTP request should not succeed after wifi disconnects"); + } catch (IOException expected) { + assertEquals(Os.strerror(OsConstants.ECONNABORTED), expected.getMessage()); + } + } + } + + public Network getWifiNetwork() { + TestNetworkCallback callback = new TestNetworkCallback(); + mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); + Network network = null; + try { + network = callback.waitForAvailable(); + } catch (InterruptedException e) { + fail("NetworkCallback wait was interrupted."); + } finally { + mCm.unregisterNetworkCallback(callback); + } + assertNotNull("Cannot find Network for wifi. Is wifi connected?", network); + return network; + } + + public Network connectToCell() throws InterruptedException { + if (cellConnectAttempted()) { + throw new IllegalStateException("Already connected"); + } + NetworkRequest cellRequest = new NetworkRequest.Builder() + .addTransportType(TRANSPORT_CELLULAR) + .addCapability(NET_CAPABILITY_INTERNET) + .build(); + mCellNetworkCallback = new TestNetworkCallback(); + mCm.requestNetwork(cellRequest, mCellNetworkCallback); + final Network cellNetwork = mCellNetworkCallback.waitForAvailable(); + assertNotNull("Cell network not available. " + + "Please ensure the device has working mobile data.", cellNetwork); + return cellNetwork; + } + + public void disconnectFromCell() { + if (!cellConnectAttempted()) { + throw new IllegalStateException("Cell connection not attempted"); + } + mCm.unregisterNetworkCallback(mCellNetworkCallback); + mCellNetworkCallback = null; + } + + public boolean cellConnectAttempted() { + return mCellNetworkCallback != null; + } + + private NetworkRequest makeWifiNetworkRequest() { + return new NetworkRequest.Builder() + .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) + .build(); + } + + private void testHttpRequest(Socket s) throws IOException { + OutputStream out = s.getOutputStream(); + InputStream in = s.getInputStream(); + + final byte[] requestBytes = HTTP_REQUEST.getBytes("UTF-8"); + byte[] responseBytes = new byte[4096]; + out.write(requestBytes); + in.read(responseBytes); + assertTrue(new String(responseBytes, "UTF-8").startsWith("HTTP/1.0 204 No Content\r\n")); + } + + private Socket getBoundSocket(Network network, String host, int port) throws IOException { + InetSocketAddress addr = new InetSocketAddress(host, port); + Socket s = network.getSocketFactory().createSocket(); + try { + s.setSoTimeout(SOCKET_TIMEOUT_MS); + s.connect(addr, SOCKET_TIMEOUT_MS); + } catch (IOException e) { + s.close(); + throw e; + } + return s; + } + + /** + * Receiver that captures the last connectivity change's network type and state. Recognizes + * both {@code CONNECTIVITY_ACTION} and {@code NETWORK_CALLBACK_ACTION} intents. + */ + public static class ConnectivityActionReceiver extends BroadcastReceiver { + + private final CountDownLatch mReceiveLatch = new CountDownLatch(1); + + private final int mNetworkType; + private final NetworkInfo.State mNetState; + private final ConnectivityManager mCm; + + public ConnectivityActionReceiver(ConnectivityManager cm, int networkType, + NetworkInfo.State netState) { + this.mCm = cm; + mNetworkType = networkType; + mNetState = netState; + } + + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + NetworkInfo networkInfo = null; + + // When receiving ConnectivityManager.CONNECTIVITY_ACTION, the NetworkInfo parcelable + // is stored in EXTRA_NETWORK_INFO. With a NETWORK_CALLBACK_ACTION, the Network is + // sent in EXTRA_NETWORK and we need to ask the ConnectivityManager for the NetworkInfo. + if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) { + networkInfo = intent.getExtras() + .getParcelable(ConnectivityManager.EXTRA_NETWORK_INFO); + assertNotNull("ConnectivityActionReceiver expected EXTRA_NETWORK_INFO", + networkInfo); + } else if (NETWORK_CALLBACK_ACTION.equals(action)) { + Network network = intent.getExtras() + .getParcelable(ConnectivityManager.EXTRA_NETWORK); + assertNotNull("ConnectivityActionReceiver expected EXTRA_NETWORK", network); + networkInfo = this.mCm.getNetworkInfo(network); + if (networkInfo == null) { + // When disconnecting, it seems like we get an intent sent with an invalid + // Network; that is, by the time we call ConnectivityManager.getNetworkInfo(), + // it is invalid. Ignore these. + Log.i(TAG, "ConnectivityActionReceiver NETWORK_CALLBACK_ACTION ignoring " + + "invalid network"); + return; + } + } else { + fail("ConnectivityActionReceiver received unxpected intent action: " + action); + } + + assertNotNull("ConnectivityActionReceiver didn't find NetworkInfo", networkInfo); + int networkType = networkInfo.getType(); + State networkState = networkInfo.getState(); + Log.i(TAG, "Network type: " + networkType + " state: " + networkState); + if (networkType == mNetworkType && networkInfo.getState() == mNetState) { + mReceiveLatch.countDown(); + } + } + + public boolean waitForState() throws InterruptedException { + return mReceiveLatch.await(30, TimeUnit.SECONDS); + } + } + + /** + * Callback used in testRegisterNetworkCallback that allows caller to block on + * {@code onAvailable}. + */ + public static class TestNetworkCallback extends ConnectivityManager.NetworkCallback { + private final CountDownLatch mAvailableLatch = new CountDownLatch(1); + private final CountDownLatch mLostLatch = new CountDownLatch(1); + private final CountDownLatch mUnavailableLatch = new CountDownLatch(1); + + public Network currentNetwork; + public Network lastLostNetwork; + + public Network waitForAvailable() throws InterruptedException { + return mAvailableLatch.await(30, TimeUnit.SECONDS) ? currentNetwork : null; + } + + public Network waitForLost() throws InterruptedException { + return mLostLatch.await(30, TimeUnit.SECONDS) ? lastLostNetwork : null; + } + + public boolean waitForUnavailable() throws InterruptedException { + return mUnavailableLatch.await(2, TimeUnit.SECONDS); + } + + + @Override + public void onAvailable(Network network) { + currentNetwork = network; + mAvailableLatch.countDown(); + } + + @Override + public void onLost(Network network) { + lastLostNetwork = network; + if (network.equals(currentNetwork)) { + currentNetwork = null; + } + mLostLatch.countDown(); + } + + @Override + public void onUnavailable() { + mUnavailableLatch.countDown(); + } + } +} From e3288fddcd7c91572c91c4c06a242d9aed14865e Mon Sep 17 00:00:00 2001 From: paulhu Date: Thu, 23 May 2019 19:16:47 +0800 Subject: [PATCH 0641/1109] Fix ConnectivityManagerApi23Test failures and remove duplication. 1. All ConnectivityManagerApi23Test were failed due to WifiManager#setWifiEnabled doesn't allow to use since Android Q. So we need to use shell command to enable/disable Wi-Fi instead. 2. Some methods are duplicated between ConnectivityManagerApi23Test and ConnectivityManagerTest, but they are not identical. So put these methods into ConnectivityUtils to clean up duplications and prevent fork happened again. Bug: 133334943 Bug: 133209319 Test: Run the below tests on Crosshatch, Sailfish, Bonito. atest CtsNetApi23TestCases atest CtsNetTestCases Change-Id: Ic37111cb12a46f5c36c2be887250c5d762216f6e Merged-In: I075b7408d2a1e1145c7a9031075e07fa1db37fed Merged-In: I0c02357eff07b98c1745de35d08ae6b8349de7fb Merged-In: I04d1e1d096bcd4a9626cf9f00396fca7f9892a82 --- tests/cts/net/Android.bp | 1 + tests/cts/net/api23Test/Android.bp | 1 + .../ConnectivityManagerApi23Test.java | 279 +------------- .../net/cts/ConnectivityManagerTest.java | 298 +-------------- tests/cts/net/util/Android.bp | 25 ++ .../android/net/cts/util/CtsNetUtils.java | 353 ++++++++++++++++++ 6 files changed, 405 insertions(+), 552 deletions(-) create mode 100644 tests/cts/net/util/Android.bp create mode 100644 tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java diff --git a/tests/cts/net/Android.bp b/tests/cts/net/Android.bp index 779d5c4be2..b6ea4afe80 100644 --- a/tests/cts/net/Android.bp +++ b/tests/cts/net/Android.bp @@ -42,6 +42,7 @@ android_test { "FrameworksNetCommonTests", "core-tests-support", "compatibility-device-util-axt", + "cts-net-utils", "ctstestrunner-axt", "ctstestserver", "mockwebserver", diff --git a/tests/cts/net/api23Test/Android.bp b/tests/cts/net/api23Test/Android.bp index 48161cf7e7..ffe854e2e9 100644 --- a/tests/cts/net/api23Test/Android.bp +++ b/tests/cts/net/api23Test/Android.bp @@ -31,6 +31,7 @@ android_test { static_libs: [ "core-tests-support", "compatibility-device-util-axt", + "cts-net-utils", "ctstestrunner-axt", "ctstestserver", "mockwebserver", diff --git a/tests/cts/net/api23Test/src/android/net/cts/api23test/ConnectivityManagerApi23Test.java b/tests/cts/net/api23Test/src/android/net/cts/api23test/ConnectivityManagerApi23Test.java index f38490e60e..cdb66e3d5a 100644 --- a/tests/cts/net/api23Test/src/android/net/cts/api23test/ConnectivityManagerApi23Test.java +++ b/tests/cts/net/api23Test/src/android/net/cts/api23test/ConnectivityManagerApi23Test.java @@ -25,58 +25,33 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.net.ConnectivityManager; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.NetworkInfo; -import android.net.NetworkInfo.State; -import android.net.NetworkRequest; -import android.net.wifi.WifiManager; +import android.net.cts.util.CtsNetUtils; import android.os.Looper; -import android.system.Os; -import android.system.OsConstants; import android.test.AndroidTestCase; import android.util.Log; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; public class ConnectivityManagerApi23Test extends AndroidTestCase { private static final String TAG = ConnectivityManagerApi23Test.class.getSimpleName(); - - private static final String TEST_HOST = "connectivitycheck.gstatic.com"; - private static final int SOCKET_TIMEOUT_MS = 2000; private static final int SEND_BROADCAST_TIMEOUT = 30000; - private static final int HTTP_PORT = 80; // Intent string to get the number of wifi CONNECTIVITY_ACTION callbacks the test app has seen public static final String GET_WIFI_CONNECTIVITY_ACTION_COUNT = "android.net.cts.appForApi23.getWifiConnectivityActionCount"; // Action sent to ConnectivityActionReceiver when a network callback is sent via PendingIntent. - private static final String NETWORK_CALLBACK_ACTION = - "ConnectivityManagerTest.NetworkCallbackAction"; - private static final String HTTP_REQUEST = - "GET /generate_204 HTTP/1.0\r\n" + - "Host: " + TEST_HOST + "\r\n" + - "Connection: keep-alive\r\n\r\n"; private Context mContext; - private ConnectivityManager mCm; - private WifiManager mWifiManager; private PackageManager mPackageManager; + private CtsNetUtils mCtsNetUtils; @Override protected void setUp() throws Exception { super.setUp(); Looper.prepare(); mContext = getContext(); - mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); - mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); mPackageManager = mContext.getPackageManager(); + mCtsNetUtils = new CtsNetUtils(mContext); } /** @@ -89,7 +64,7 @@ public class ConnectivityManagerApi23Test extends AndroidTestCase { } ConnectivityReceiver.prepare(); - toggleWifi(); + mCtsNetUtils.toggleWifi(); // The connectivity broadcast has been sent; push through a terminal broadcast // to wait for in the receive to confirm it didn't see the connectivity change. @@ -112,7 +87,7 @@ public class ConnectivityManagerApi23Test extends AndroidTestCase { .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); Thread.sleep(200); - toggleWifi(); + mCtsNetUtils.toggleWifi(); Intent getConnectivityCount = new Intent(GET_WIFI_CONNECTIVITY_ACTION_COUNT); assertEquals(2, sendOrderedBroadcastAndReturnResultCode( @@ -130,7 +105,7 @@ public class ConnectivityManagerApi23Test extends AndroidTestCase { filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); mContext.registerReceiver(receiver, filter); - toggleWifi(); + mCtsNetUtils.toggleWifi(); Intent finalIntent = new Intent(ConnectivityReceiver.FINAL_ACTION); finalIntent.setClass(mContext, ConnectivityReceiver.class); mContext.sendBroadcast(finalIntent); @@ -138,19 +113,6 @@ public class ConnectivityManagerApi23Test extends AndroidTestCase { assertTrue(ConnectivityReceiver.waitForBroadcast()); } - // Toggle WiFi twice, leaving it in the state it started in - private void toggleWifi() { - if (mWifiManager.isWifiEnabled()) { - Network wifiNetwork = getWifiNetwork(); - disconnectFromWifi(wifiNetwork); - connectToWifi(); - } else { - connectToWifi(); - Network wifiNetwork = getWifiNetwork(); - disconnectFromWifi(wifiNetwork); - } - } - private int sendOrderedBroadcastAndReturnResultCode( Intent intent, int timeoutMs) throws InterruptedException { final LinkedBlockingQueue result = new LinkedBlockingQueue<>(1); @@ -167,233 +129,4 @@ public class ConnectivityManagerApi23Test extends AndroidTestCase { return resultCode; } - private Network getWifiNetwork() { - TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); - Network network = null; - try { - network = callback.waitForAvailable(); - } catch (InterruptedException e) { - fail("NetworkCallback wait was interrupted."); - } finally { - mCm.unregisterNetworkCallback(callback); - } - assertNotNull("Cannot find Network for wifi. Is wifi connected?", network); - return network; - } - - /** Disable WiFi and wait for it to become disconnected from the network. */ - private void disconnectFromWifi(Network wifiNetworkToCheck) { - final TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); - Network lostWifiNetwork = null; - - ConnectivityActionReceiver receiver = new ConnectivityActionReceiver( - ConnectivityManager.TYPE_WIFI, NetworkInfo.State.DISCONNECTED); - IntentFilter filter = new IntentFilter(); - filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); - mContext.registerReceiver(receiver, filter); - - // Assert that we can establish a TCP connection on wifi. - Socket wifiBoundSocket = null; - if (wifiNetworkToCheck != null) { - try { - wifiBoundSocket = getBoundSocket(wifiNetworkToCheck, TEST_HOST, HTTP_PORT); - testHttpRequest(wifiBoundSocket); - } catch (IOException e) { - fail("HTTP request before wifi disconnected failed with: " + e); - } - } - - boolean disconnected = false; - try { - assertTrue(mWifiManager.setWifiEnabled(false)); - // Ensure we get both an onLost callback and a CONNECTIVITY_ACTION. - lostWifiNetwork = callback.waitForLost(); - assertNotNull(lostWifiNetwork); - disconnected = receiver.waitForState(); - } catch (InterruptedException ex) { - fail("disconnectFromWifi was interrupted"); - } finally { - mCm.unregisterNetworkCallback(callback); - mContext.unregisterReceiver(receiver); - } - - assertTrue("Wifi failed to reach DISCONNECTED state.", disconnected); - - // Check that the socket is closed when wifi disconnects. - if (wifiBoundSocket != null) { - try { - testHttpRequest(wifiBoundSocket); - fail("HTTP request should not succeed after wifi disconnects"); - } catch (IOException expected) { - assertEquals(Os.strerror(OsConstants.ECONNABORTED), expected.getMessage()); - } - } - } - - /** Enable WiFi and wait for it to become connected to a network. */ - private Network connectToWifi() { - final TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); - Network wifiNetwork = null; - - ConnectivityActionReceiver receiver = new ConnectivityActionReceiver( - ConnectivityManager.TYPE_WIFI, NetworkInfo.State.CONNECTED); - IntentFilter filter = new IntentFilter(); - filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); - mContext.registerReceiver(receiver, filter); - - boolean connected = false; - try { - assertTrue(mWifiManager.setWifiEnabled(true)); - // Ensure we get both an onAvailable callback and a CONNECTIVITY_ACTION. - wifiNetwork = callback.waitForAvailable(); - assertNotNull(wifiNetwork); - connected = receiver.waitForState(); - } catch (InterruptedException ex) { - fail("connectToWifi was interrupted"); - } finally { - mCm.unregisterNetworkCallback(callback); - mContext.unregisterReceiver(receiver); - } - - assertTrue("Wifi must be configured to connect to an access point for this test.", - connected); - return wifiNetwork; - } - - private NetworkRequest makeWifiNetworkRequest() { - return new NetworkRequest.Builder() - .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) - .build(); - } - - private void testHttpRequest(Socket s) throws IOException { - OutputStream out = s.getOutputStream(); - InputStream in = s.getInputStream(); - - final byte[] requestBytes = HTTP_REQUEST.getBytes("UTF-8"); - byte[] responseBytes = new byte[4096]; - out.write(requestBytes); - in.read(responseBytes); - assertTrue(new String(responseBytes, "UTF-8").startsWith("HTTP/1.0 204 No Content\r\n")); - } - - private Socket getBoundSocket(Network network, String host, int port) throws IOException { - InetSocketAddress addr = new InetSocketAddress(host, port); - Socket s = network.getSocketFactory().createSocket(); - try { - s.setSoTimeout(SOCKET_TIMEOUT_MS); - s.connect(addr, SOCKET_TIMEOUT_MS); - } catch (IOException e) { - s.close(); - throw e; - } - return s; - } - - /** - * Receiver that captures the last connectivity change's network type and state. Recognizes - * both {@code CONNECTIVITY_ACTION} and {@code NETWORK_CALLBACK_ACTION} intents. - */ - private class ConnectivityActionReceiver extends BroadcastReceiver { - - private final CountDownLatch mReceiveLatch = new CountDownLatch(1); - - private final int mNetworkType; - private final NetworkInfo.State mNetState; - - ConnectivityActionReceiver(int networkType, NetworkInfo.State netState) { - mNetworkType = networkType; - mNetState = netState; - } - - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - NetworkInfo networkInfo = null; - - // When receiving ConnectivityManager.CONNECTIVITY_ACTION, the NetworkInfo parcelable - // is stored in EXTRA_NETWORK_INFO. With a NETWORK_CALLBACK_ACTION, the Network is - // sent in EXTRA_NETWORK and we need to ask the ConnectivityManager for the NetworkInfo. - if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) { - networkInfo = intent.getExtras() - .getParcelable(ConnectivityManager.EXTRA_NETWORK_INFO); - assertNotNull("ConnectivityActionReceiver expected EXTRA_NETWORK_INFO", networkInfo); - } else if (NETWORK_CALLBACK_ACTION.equals(action)) { - Network network = intent.getExtras() - .getParcelable(ConnectivityManager.EXTRA_NETWORK); - assertNotNull("ConnectivityActionReceiver expected EXTRA_NETWORK", network); - networkInfo = mCm.getNetworkInfo(network); - if (networkInfo == null) { - // When disconnecting, it seems like we get an intent sent with an invalid - // Network; that is, by the time we call ConnectivityManager.getNetworkInfo(), - // it is invalid. Ignore these. - Log.i(TAG, "ConnectivityActionReceiver NETWORK_CALLBACK_ACTION ignoring " - + "invalid network"); - return; - } - } else { - fail("ConnectivityActionReceiver received unxpected intent action: " + action); - } - - assertNotNull("ConnectivityActionReceiver didn't find NetworkInfo", networkInfo); - int networkType = networkInfo.getType(); - State networkState = networkInfo.getState(); - Log.i(TAG, "Network type: " + networkType + " state: " + networkState); - if (networkType == mNetworkType && networkInfo.getState() == mNetState) { - mReceiveLatch.countDown(); - } - } - - public boolean waitForState() throws InterruptedException { - return mReceiveLatch.await(30, TimeUnit.SECONDS); - } - } - - /** - * Callback used in testRegisterNetworkCallback that allows caller to block on - * {@code onAvailable}. - */ - private static class TestNetworkCallback extends ConnectivityManager.NetworkCallback { - private final CountDownLatch mAvailableLatch = new CountDownLatch(1); - private final CountDownLatch mLostLatch = new CountDownLatch(1); - private final CountDownLatch mUnavailableLatch = new CountDownLatch(1); - - public Network currentNetwork; - public Network lastLostNetwork; - - public Network waitForAvailable() throws InterruptedException { - return mAvailableLatch.await(30, TimeUnit.SECONDS) ? currentNetwork : null; - } - - public Network waitForLost() throws InterruptedException { - return mLostLatch.await(30, TimeUnit.SECONDS) ? lastLostNetwork : null; - } - - public boolean waitForUnavailable() throws InterruptedException { - return mUnavailableLatch.await(2, TimeUnit.SECONDS); - } - - - @Override - public void onAvailable(Network network) { - currentNetwork = network; - mAvailableLatch.countDown(); - } - - @Override - public void onLost(Network network) { - lastLostNetwork = network; - if (network.equals(currentNetwork)) { - currentNetwork = null; - } - mLostLatch.countDown(); - } - - @Override - public void onUnavailable() { - mUnavailableLatch.countDown(); - } - } } \ No newline at end of file diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 4b2c5794ed..c3ae793aae 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -21,8 +21,12 @@ import static android.content.pm.PackageManager.FEATURE_WIFI; import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; -import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; +import static android.net.cts.util.CtsNetUtils.ConnectivityActionReceiver; +import static android.net.cts.util.CtsNetUtils.HTTP_PORT; +import static android.net.cts.util.CtsNetUtils.NETWORK_CALLBACK_ACTION; +import static android.net.cts.util.CtsNetUtils.TEST_HOST; +import static android.net.cts.util.CtsNetUtils.TestNetworkCallback; import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT; import static android.provider.Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE; import static android.system.OsConstants.AF_INET; @@ -34,7 +38,6 @@ import static com.android.compatibility.common.util.SystemUtil.runShellCommand; import android.app.Instrumentation; import android.app.PendingIntent; import android.app.UiAutomation; -import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; @@ -53,6 +56,7 @@ import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; import android.net.NetworkRequest; import android.net.SocketKeepalive; +import android.net.cts.util.CtsNetUtils; import android.net.util.KeepaliveUtils; import android.net.wifi.WifiManager; import android.os.Looper; @@ -61,8 +65,6 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.platform.test.annotations.AppModeFull; import android.provider.Settings; -import android.system.Os; -import android.system.OsConstants; import android.test.AndroidTestCase; import android.text.TextUtils; import android.util.Log; @@ -106,8 +108,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI; private static final int HOST_ADDRESS = 0x7f000001;// represent ip 127.0.0.1 - private static final String TEST_HOST = "connectivitycheck.gstatic.com"; - private static final int SOCKET_TIMEOUT_MS = 2000; private static final int CONNECT_TIMEOUT_MS = 2000; private static final int KEEPALIVE_CALLBACK_TIMEOUT_MS = 2000; private static final int KEEPALIVE_SOCKET_TIMEOUT_MS = 5000; @@ -115,16 +115,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { private static final int NETWORK_CHANGE_METEREDNESS_TIMEOUT = 5000; private static final int NUM_TRIES_MULTIPATH_PREF_CHECK = 20; private static final long INTERVAL_MULTIPATH_PREF_CHECK_MS = 500; - private static final int HTTP_PORT = 80; - private static final String HTTP_REQUEST = - "GET /generate_204 HTTP/1.0\r\n" + - "Host: " + TEST_HOST + "\r\n" + - "Connection: keep-alive\r\n\r\n"; - - // Action sent to ConnectivityActionReceiver when a network callback is sent via PendingIntent. - private static final String NETWORK_CALLBACK_ACTION = - "ConnectivityManagerTest.NetworkCallbackAction"; - // device could have only one interface: data, wifi. private static final int MIN_NUM_NETWORK_TYPES = 1; @@ -136,8 +126,8 @@ public class ConnectivityManagerTest extends AndroidTestCase { private final HashMap mNetworks = new HashMap(); boolean mWifiConnectAttempted; - private TestNetworkCallback mCellNetworkCallback; private UiAutomation mUiAutomation; + private CtsNetUtils mCtsNetUtils; private boolean mShellPermissionIdentityAdopted; @Override @@ -149,6 +139,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); mPackageManager = mContext.getPackageManager(); + mCtsNetUtils = new CtsNetUtils(mContext); mWifiConnectAttempted = false; // Get com.android.internal.R.array.networkAttributes @@ -173,10 +164,10 @@ public class ConnectivityManagerTest extends AndroidTestCase { protected void tearDown() throws Exception { // Return WiFi to its original disabled state after tests that explicitly connect. if (mWifiConnectAttempted) { - disconnectFromWifi(null); + mCtsNetUtils.disconnectFromWifi(null); } - if (cellConnectAttempted()) { - disconnectFromCell(); + if (mCtsNetUtils.cellConnectAttempted()) { + mCtsNetUtils.disconnectFromCell(); } dropShellPermissionIdentity(); super.tearDown(); @@ -189,10 +180,10 @@ public class ConnectivityManagerTest extends AndroidTestCase { */ private Network ensureWifiConnected() { if (mWifiManager.isWifiEnabled()) { - return getWifiNetwork(); + return mCtsNetUtils.getWifiNetwork(); } mWifiConnectAttempted = true; - return connectToWifi(); + return mCtsNetUtils.connectToWifi(); } public void testIsNetworkTypeValid() { @@ -300,8 +291,8 @@ public class ConnectivityManagerTest extends AndroidTestCase { return; } - Network wifiNetwork = connectToWifi(); - Network cellNetwork = connectToCell(); + Network wifiNetwork = mCtsNetUtils.connectToWifi(); + Network cellNetwork = mCtsNetUtils.connectToCell(); // This server returns the requestor's IP address as the response body. URL url = new URL("http://google-ipv6test.appspot.com/ip.js?fmt=text"); String wifiAddressString = httpGet(wifiNetwork, url); @@ -319,33 +310,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { assertFalse("Unexpectedly equal: " + wifiNetwork, wifiNetwork.equals(cellNetwork)); } - private Network connectToCell() throws InterruptedException { - if (cellConnectAttempted()) { - throw new IllegalStateException("Already connected"); - } - NetworkRequest cellRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_CELLULAR) - .addCapability(NET_CAPABILITY_INTERNET) - .build(); - mCellNetworkCallback = new TestNetworkCallback(); - mCm.requestNetwork(cellRequest, mCellNetworkCallback); - final Network cellNetwork = mCellNetworkCallback.waitForAvailable(); - assertNotNull("Cell network not available within timeout", cellNetwork); - return cellNetwork; - } - - private boolean cellConnectAttempted() { - return mCellNetworkCallback != null; - } - - private void disconnectFromCell() { - if (!cellConnectAttempted()) { - throw new IllegalStateException("Cell connection not attempted"); - } - mCm.unregisterNetworkCallback(mCellNetworkCallback); - mCellNetworkCallback = null; - } - /** * Performs a HTTP GET to the specified URL on the specified Network, and returns * the response body decoded as UTF-8. @@ -507,7 +471,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { filter.addAction(NETWORK_CALLBACK_ACTION); ConnectivityActionReceiver receiver = new ConnectivityActionReceiver( - ConnectivityManager.TYPE_WIFI, NetworkInfo.State.CONNECTED); + mCm, ConnectivityManager.TYPE_WIFI, NetworkInfo.State.CONNECTED); mContext.registerReceiver(receiver, filter); // Create a broadcast PendingIntent for NETWORK_CALLBACK_ACTION. @@ -566,7 +530,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { public void testRequestNetworkCallback_onUnavailable() { final boolean previousWifiEnabledState = mWifiManager.isWifiEnabled(); if (previousWifiEnabledState) { - disconnectFromWifi(null); + mCtsNetUtils.disconnectFromWifi(null); } final TestNetworkCallback callback = new TestNetworkCallback(); @@ -583,42 +547,11 @@ public class ConnectivityManagerTest extends AndroidTestCase { } finally { mCm.unregisterNetworkCallback(callback); if (previousWifiEnabledState) { - connectToWifi(); + mCtsNetUtils.connectToWifi(); } } } - /** Enable WiFi and wait for it to become connected to a network. */ - private Network connectToWifi() { - final TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); - Network wifiNetwork = null; - - ConnectivityActionReceiver receiver = new ConnectivityActionReceiver( - ConnectivityManager.TYPE_WIFI, NetworkInfo.State.CONNECTED); - IntentFilter filter = new IntentFilter(); - filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); - mContext.registerReceiver(receiver, filter); - - boolean connected = false; - try { - assertTrue(mWifiManager.setWifiEnabled(true)); - // Ensure we get both an onAvailable callback and a CONNECTIVITY_ACTION. - wifiNetwork = callback.waitForAvailable(); - assertNotNull(wifiNetwork); - connected = receiver.waitForState(); - } catch (InterruptedException ex) { - fail("connectToWifi was interrupted"); - } finally { - mCm.unregisterNetworkCallback(callback); - mContext.unregisterReceiver(receiver); - } - - assertTrue("Wifi must be configured to connect to an access point for this test.", - connected); - return wifiNetwork; - } - private InetAddress getFirstV4Address(Network network) { LinkProperties linkProperties = mCm.getLinkProperties(network); for (InetAddress address : linkProperties.getAddresses()) { @@ -629,199 +562,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { return null; } - private Socket getBoundSocket(Network network, String host, int port) throws IOException { - InetSocketAddress addr = new InetSocketAddress(host, port); - Socket s = network.getSocketFactory().createSocket(); - try { - s.setSoTimeout(SOCKET_TIMEOUT_MS); - s.connect(addr, SOCKET_TIMEOUT_MS); - } catch (IOException e) { - s.close(); - throw e; - } - return s; - } - - private void testHttpRequest(Socket s) throws IOException { - OutputStream out = s.getOutputStream(); - InputStream in = s.getInputStream(); - - final byte[] requestBytes = HTTP_REQUEST.getBytes("UTF-8"); - byte[] responseBytes = new byte[4096]; - out.write(requestBytes); - in.read(responseBytes); - assertTrue(new String(responseBytes, "UTF-8").startsWith("HTTP/1.0 204 No Content\r\n")); - } - - /** Disable WiFi and wait for it to become disconnected from the network. */ - private void disconnectFromWifi(Network wifiNetworkToCheck) { - final TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); - Network lostWifiNetwork = null; - - ConnectivityActionReceiver receiver = new ConnectivityActionReceiver( - ConnectivityManager.TYPE_WIFI, NetworkInfo.State.DISCONNECTED); - IntentFilter filter = new IntentFilter(); - filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); - mContext.registerReceiver(receiver, filter); - - // Assert that we can establish a TCP connection on wifi. - Socket wifiBoundSocket = null; - if (wifiNetworkToCheck != null) { - try { - wifiBoundSocket = getBoundSocket(wifiNetworkToCheck, TEST_HOST, HTTP_PORT); - testHttpRequest(wifiBoundSocket); - } catch (IOException e) { - fail("HTTP request before wifi disconnected failed with: " + e); - } - } - - boolean disconnected = false; - try { - assertTrue(mWifiManager.setWifiEnabled(false)); - // Ensure we get both an onLost callback and a CONNECTIVITY_ACTION. - lostWifiNetwork = callback.waitForLost(); - assertNotNull(lostWifiNetwork); - disconnected = receiver.waitForState(); - } catch (InterruptedException ex) { - fail("disconnectFromWifi was interrupted"); - } finally { - mCm.unregisterNetworkCallback(callback); - mContext.unregisterReceiver(receiver); - } - - assertTrue("Wifi failed to reach DISCONNECTED state.", disconnected); - - // Check that the socket is closed when wifi disconnects. - if (wifiBoundSocket != null) { - try { - testHttpRequest(wifiBoundSocket); - fail("HTTP request should not succeed after wifi disconnects"); - } catch (IOException expected) { - assertEquals(Os.strerror(OsConstants.ECONNABORTED), expected.getMessage()); - } - } - } - - /** - * Receiver that captures the last connectivity change's network type and state. Recognizes - * both {@code CONNECTIVITY_ACTION} and {@code NETWORK_CALLBACK_ACTION} intents. - */ - private class ConnectivityActionReceiver extends BroadcastReceiver { - - private final CountDownLatch mReceiveLatch = new CountDownLatch(1); - - private final int mNetworkType; - private final NetworkInfo.State mNetState; - - ConnectivityActionReceiver(int networkType, NetworkInfo.State netState) { - mNetworkType = networkType; - mNetState = netState; - } - - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - NetworkInfo networkInfo = null; - - // When receiving ConnectivityManager.CONNECTIVITY_ACTION, the NetworkInfo parcelable - // is stored in EXTRA_NETWORK_INFO. With a NETWORK_CALLBACK_ACTION, the Network is - // sent in EXTRA_NETWORK and we need to ask the ConnectivityManager for the NetworkInfo. - if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) { - networkInfo = intent.getExtras() - .getParcelable(ConnectivityManager.EXTRA_NETWORK_INFO); - assertNotNull("ConnectivityActionReceiver expected EXTRA_NETWORK_INFO", networkInfo); - } else if (NETWORK_CALLBACK_ACTION.equals(action)) { - Network network = intent.getExtras() - .getParcelable(ConnectivityManager.EXTRA_NETWORK); - assertNotNull("ConnectivityActionReceiver expected EXTRA_NETWORK", network); - networkInfo = mCm.getNetworkInfo(network); - if (networkInfo == null) { - // When disconnecting, it seems like we get an intent sent with an invalid - // Network; that is, by the time we call ConnectivityManager.getNetworkInfo(), - // it is invalid. Ignore these. - Log.i(TAG, "ConnectivityActionReceiver NETWORK_CALLBACK_ACTION ignoring " - + "invalid network"); - return; - } - } else { - fail("ConnectivityActionReceiver received unxpected intent action: " + action); - } - - assertNotNull("ConnectivityActionReceiver didn't find NetworkInfo", networkInfo); - int networkType = networkInfo.getType(); - State networkState = networkInfo.getState(); - Log.i(TAG, "Network type: " + networkType + " state: " + networkState); - if (networkType == mNetworkType && networkInfo.getState() == mNetState) { - mReceiveLatch.countDown(); - } - } - - public boolean waitForState() throws InterruptedException { - return mReceiveLatch.await(30, TimeUnit.SECONDS); - } - } - - /** - * Callback used in testRegisterNetworkCallback that allows caller to block on - * {@code onAvailable}. - */ - private static class TestNetworkCallback extends ConnectivityManager.NetworkCallback { - private final CountDownLatch mAvailableLatch = new CountDownLatch(1); - private final CountDownLatch mLostLatch = new CountDownLatch(1); - private final CountDownLatch mUnavailableLatch = new CountDownLatch(1); - - public Network currentNetwork; - public Network lastLostNetwork; - - public Network waitForAvailable() throws InterruptedException { - return mAvailableLatch.await(30, TimeUnit.SECONDS) ? currentNetwork : null; - } - - public Network waitForLost() throws InterruptedException { - return mLostLatch.await(30, TimeUnit.SECONDS) ? lastLostNetwork : null; - } - - public boolean waitForUnavailable() throws InterruptedException { - return mUnavailableLatch.await(2, TimeUnit.SECONDS); - } - - - @Override - public void onAvailable(Network network) { - currentNetwork = network; - mAvailableLatch.countDown(); - } - - @Override - public void onLost(Network network) { - lastLostNetwork = network; - if (network.equals(currentNetwork)) { - currentNetwork = null; - } - mLostLatch.countDown(); - } - - @Override - public void onUnavailable() { - mUnavailableLatch.countDown(); - } - } - - private Network getWifiNetwork() { - TestNetworkCallback callback = new TestNetworkCallback(); - mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); - Network network = null; - try { - network = callback.waitForAvailable(); - } catch (InterruptedException e) { - fail("NetworkCallback wait was interrupted."); - } finally { - mCm.unregisterNetworkCallback(callback); - } - assertNotNull("Cannot find Network for wifi. Is wifi connected?", network); - return network; - } - /** Verify restricted networks cannot be requested. */ @AppModeFull(reason = "CHANGE_NETWORK_STATE permission can't be granted to instant apps") public void testRestrictedNetworks() { @@ -1150,7 +890,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { if (!isKeepaliveSupported()) return; final Network network = ensureWifiConnected(); - final byte[] requestBytes = HTTP_REQUEST.getBytes("UTF-8"); + final byte[] requestBytes = CtsNetUtils.HTTP_REQUEST.getBytes("UTF-8"); // So far only ipv4 tcp keepalive offload is supported. // TODO: add test case for ipv6 tcp keepalive offload when it is supported. try (Socket s = getConnectedSocket(network, TEST_HOST, HTTP_PORT, diff --git a/tests/cts/net/util/Android.bp b/tests/cts/net/util/Android.bp new file mode 100644 index 0000000000..1f94613ffb --- /dev/null +++ b/tests/cts/net/util/Android.bp @@ -0,0 +1,25 @@ +// +// Copyright (C) 2019 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. +// + +// Common utilities for cts net tests. +java_library { + name: "cts-net-utils", + srcs: ["java/**/*.java", "java/**/*.kt"], + static_libs: [ + "compatibility-device-util-axt", + "junit", + ], +} \ No newline at end of file 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 new file mode 100644 index 0000000000..e19d2bafb7 --- /dev/null +++ b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java @@ -0,0 +1,353 @@ +/* + * Copyright (C) 2019 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.util; + +import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; +import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.ConnectivityManager; +import android.net.ConnectivityManager.NetworkCallback; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.NetworkInfo; +import android.net.NetworkInfo.State; +import android.net.NetworkRequest; +import android.net.wifi.WifiManager; +import android.system.Os; +import android.system.OsConstants; +import android.util.Log; + +import com.android.compatibility.common.util.SystemUtil; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +public final class CtsNetUtils { + private static final String TAG = CtsNetUtils.class.getSimpleName(); + private static final int DURATION = 10000; + private static final int SOCKET_TIMEOUT_MS = 2000; + + public static final int HTTP_PORT = 80; + public static final String TEST_HOST = "connectivitycheck.gstatic.com"; + public static final String HTTP_REQUEST = + "GET /generate_204 HTTP/1.0\r\n" + + "Host: " + TEST_HOST + "\r\n" + + "Connection: keep-alive\r\n\r\n"; + // Action sent to ConnectivityActionReceiver when a network callback is sent via PendingIntent. + public static final String NETWORK_CALLBACK_ACTION = + "ConnectivityManagerTest.NetworkCallbackAction"; + + private Context mContext; + private ConnectivityManager mCm; + private WifiManager mWifiManager; + private TestNetworkCallback mCellNetworkCallback; + + public CtsNetUtils(Context context) { + mContext = context; + mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); + mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); + } + + // Toggle WiFi twice, leaving it in the state it started in + public void toggleWifi() { + if (mWifiManager.isWifiEnabled()) { + Network wifiNetwork = getWifiNetwork(); + disconnectFromWifi(wifiNetwork); + connectToWifi(); + } else { + connectToWifi(); + Network wifiNetwork = getWifiNetwork(); + disconnectFromWifi(wifiNetwork); + } + } + + /** Enable WiFi and wait for it to become connected to a network. */ + public Network connectToWifi() { + final TestNetworkCallback callback = new TestNetworkCallback(); + mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); + Network wifiNetwork = null; + + ConnectivityActionReceiver receiver = new ConnectivityActionReceiver( + mCm, ConnectivityManager.TYPE_WIFI, NetworkInfo.State.CONNECTED); + IntentFilter filter = new IntentFilter(); + filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); + mContext.registerReceiver(receiver, filter); + + boolean connected = false; + try { + SystemUtil.runShellCommand("svc wifi enable"); + // Ensure we get both an onAvailable callback and a CONNECTIVITY_ACTION. + wifiNetwork = callback.waitForAvailable(); + assertNotNull(wifiNetwork); + connected = receiver.waitForState(); + } catch (InterruptedException ex) { + fail("connectToWifi was interrupted"); + } finally { + mCm.unregisterNetworkCallback(callback); + mContext.unregisterReceiver(receiver); + } + + assertTrue("Wifi must be configured to connect to an access point for this test.", + connected); + return wifiNetwork; + } + + /** Disable WiFi and wait for it to become disconnected from the network. */ + public void disconnectFromWifi(Network wifiNetworkToCheck) { + final TestNetworkCallback callback = new TestNetworkCallback(); + mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); + Network lostWifiNetwork = null; + + ConnectivityActionReceiver receiver = new ConnectivityActionReceiver( + mCm, ConnectivityManager.TYPE_WIFI, NetworkInfo.State.DISCONNECTED); + IntentFilter filter = new IntentFilter(); + filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); + mContext.registerReceiver(receiver, filter); + + // Assert that we can establish a TCP connection on wifi. + Socket wifiBoundSocket = null; + if (wifiNetworkToCheck != null) { + try { + wifiBoundSocket = getBoundSocket(wifiNetworkToCheck, TEST_HOST, HTTP_PORT); + testHttpRequest(wifiBoundSocket); + } catch (IOException e) { + fail("HTTP request before wifi disconnected failed with: " + e); + } + } + + boolean disconnected = false; + try { + SystemUtil.runShellCommand("svc wifi disable"); + // Ensure we get both an onLost callback and a CONNECTIVITY_ACTION. + lostWifiNetwork = callback.waitForLost(); + assertNotNull(lostWifiNetwork); + disconnected = receiver.waitForState(); + } catch (InterruptedException ex) { + fail("disconnectFromWifi was interrupted"); + } finally { + mCm.unregisterNetworkCallback(callback); + mContext.unregisterReceiver(receiver); + } + + assertTrue("Wifi failed to reach DISCONNECTED state.", disconnected); + + // Check that the socket is closed when wifi disconnects. + if (wifiBoundSocket != null) { + try { + testHttpRequest(wifiBoundSocket); + fail("HTTP request should not succeed after wifi disconnects"); + } catch (IOException expected) { + assertEquals(Os.strerror(OsConstants.ECONNABORTED), expected.getMessage()); + } + } + } + + public Network getWifiNetwork() { + TestNetworkCallback callback = new TestNetworkCallback(); + mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); + Network network = null; + try { + network = callback.waitForAvailable(); + } catch (InterruptedException e) { + fail("NetworkCallback wait was interrupted."); + } finally { + mCm.unregisterNetworkCallback(callback); + } + assertNotNull("Cannot find Network for wifi. Is wifi connected?", network); + return network; + } + + public Network connectToCell() throws InterruptedException { + if (cellConnectAttempted()) { + throw new IllegalStateException("Already connected"); + } + NetworkRequest cellRequest = new NetworkRequest.Builder() + .addTransportType(TRANSPORT_CELLULAR) + .addCapability(NET_CAPABILITY_INTERNET) + .build(); + mCellNetworkCallback = new TestNetworkCallback(); + mCm.requestNetwork(cellRequest, mCellNetworkCallback); + final Network cellNetwork = mCellNetworkCallback.waitForAvailable(); + assertNotNull("Cell network not available. " + + "Please ensure the device has working mobile data.", cellNetwork); + return cellNetwork; + } + + public void disconnectFromCell() { + if (!cellConnectAttempted()) { + throw new IllegalStateException("Cell connection not attempted"); + } + mCm.unregisterNetworkCallback(mCellNetworkCallback); + mCellNetworkCallback = null; + } + + public boolean cellConnectAttempted() { + return mCellNetworkCallback != null; + } + + private NetworkRequest makeWifiNetworkRequest() { + return new NetworkRequest.Builder() + .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) + .build(); + } + + private void testHttpRequest(Socket s) throws IOException { + OutputStream out = s.getOutputStream(); + InputStream in = s.getInputStream(); + + final byte[] requestBytes = HTTP_REQUEST.getBytes("UTF-8"); + byte[] responseBytes = new byte[4096]; + out.write(requestBytes); + in.read(responseBytes); + assertTrue(new String(responseBytes, "UTF-8").startsWith("HTTP/1.0 204 No Content\r\n")); + } + + private Socket getBoundSocket(Network network, String host, int port) throws IOException { + InetSocketAddress addr = new InetSocketAddress(host, port); + Socket s = network.getSocketFactory().createSocket(); + try { + s.setSoTimeout(SOCKET_TIMEOUT_MS); + s.connect(addr, SOCKET_TIMEOUT_MS); + } catch (IOException e) { + s.close(); + throw e; + } + return s; + } + + /** + * Receiver that captures the last connectivity change's network type and state. Recognizes + * both {@code CONNECTIVITY_ACTION} and {@code NETWORK_CALLBACK_ACTION} intents. + */ + public static class ConnectivityActionReceiver extends BroadcastReceiver { + + private final CountDownLatch mReceiveLatch = new CountDownLatch(1); + + private final int mNetworkType; + private final NetworkInfo.State mNetState; + private final ConnectivityManager mCm; + + public ConnectivityActionReceiver(ConnectivityManager cm, int networkType, + NetworkInfo.State netState) { + this.mCm = cm; + mNetworkType = networkType; + mNetState = netState; + } + + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + NetworkInfo networkInfo = null; + + // When receiving ConnectivityManager.CONNECTIVITY_ACTION, the NetworkInfo parcelable + // is stored in EXTRA_NETWORK_INFO. With a NETWORK_CALLBACK_ACTION, the Network is + // sent in EXTRA_NETWORK and we need to ask the ConnectivityManager for the NetworkInfo. + if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) { + networkInfo = intent.getExtras() + .getParcelable(ConnectivityManager.EXTRA_NETWORK_INFO); + assertNotNull("ConnectivityActionReceiver expected EXTRA_NETWORK_INFO", + networkInfo); + } else if (NETWORK_CALLBACK_ACTION.equals(action)) { + Network network = intent.getExtras() + .getParcelable(ConnectivityManager.EXTRA_NETWORK); + assertNotNull("ConnectivityActionReceiver expected EXTRA_NETWORK", network); + networkInfo = this.mCm.getNetworkInfo(network); + if (networkInfo == null) { + // When disconnecting, it seems like we get an intent sent with an invalid + // Network; that is, by the time we call ConnectivityManager.getNetworkInfo(), + // it is invalid. Ignore these. + Log.i(TAG, "ConnectivityActionReceiver NETWORK_CALLBACK_ACTION ignoring " + + "invalid network"); + return; + } + } else { + fail("ConnectivityActionReceiver received unxpected intent action: " + action); + } + + assertNotNull("ConnectivityActionReceiver didn't find NetworkInfo", networkInfo); + int networkType = networkInfo.getType(); + State networkState = networkInfo.getState(); + Log.i(TAG, "Network type: " + networkType + " state: " + networkState); + if (networkType == mNetworkType && networkInfo.getState() == mNetState) { + mReceiveLatch.countDown(); + } + } + + public boolean waitForState() throws InterruptedException { + return mReceiveLatch.await(30, TimeUnit.SECONDS); + } + } + + /** + * Callback used in testRegisterNetworkCallback that allows caller to block on + * {@code onAvailable}. + */ + public static class TestNetworkCallback extends ConnectivityManager.NetworkCallback { + private final CountDownLatch mAvailableLatch = new CountDownLatch(1); + private final CountDownLatch mLostLatch = new CountDownLatch(1); + private final CountDownLatch mUnavailableLatch = new CountDownLatch(1); + + public Network currentNetwork; + public Network lastLostNetwork; + + public Network waitForAvailable() throws InterruptedException { + return mAvailableLatch.await(30, TimeUnit.SECONDS) ? currentNetwork : null; + } + + public Network waitForLost() throws InterruptedException { + return mLostLatch.await(30, TimeUnit.SECONDS) ? lastLostNetwork : null; + } + + public boolean waitForUnavailable() throws InterruptedException { + return mUnavailableLatch.await(2, TimeUnit.SECONDS); + } + + + @Override + public void onAvailable(Network network) { + currentNetwork = network; + mAvailableLatch.countDown(); + } + + @Override + public void onLost(Network network) { + lastLostNetwork = network; + if (network.equals(currentNetwork)) { + currentNetwork = null; + } + mLostLatch.countDown(); + } + + @Override + public void onUnavailable() { + mUnavailableLatch.countDown(); + } + } +} From 87ac083a3b72ee3462f15b296dde541e07797daf Mon Sep 17 00:00:00 2001 From: Junyu Lai Date: Wed, 29 May 2019 22:34:02 -0700 Subject: [PATCH 0642/1109] Fix keepalive CTS fail for devices with kernel older than 4.8 If kernel < 4.8 then it doesn't support get socket option TCP_REPAIR_WINDOW, thus TCP keepalive cannot be supported. However, it might still support NAT-T keepalive. Test TCP keepalive only if it is supported by kernel. Bug: 133652079 Test: atest android.net.cts.ConnectivityManagerTest#testMajorMinorVersionCompare \ android.net.cts.ConnectivityManagerTest#testSocketKeepaliveLimit \ android.net.cts.ConnectivityManagerTest#testSocketKeepaliveUnprivileged \ android.net.cts.ConnectivityManagerTest#testKeepaliveUnsupported \ android.net.cts.ConnectivityManagerTest#testCreateTcpKeepalive Change-Id: I0a3ff07c482bb7c8cb05663678c10afcc0500861 Merged-In: I3f8456deea2b4ded762a413c8e27b58ce54ce0aa (cherry picked from commit 57d91e6276b50bf0dd78f3643c4a979f584fcf38) --- .../net/cts/ConnectivityManagerTest.java | 178 ++++++++++++------ 1 file changed, 119 insertions(+), 59 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index c3ae793aae..8c9bf6ee21 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -63,11 +63,13 @@ import android.os.Looper; import android.os.MessageQueue; import android.os.SystemClock; import android.os.SystemProperties; +import android.os.VintfRuntimeInfo; import android.platform.test.annotations.AppModeFull; import android.provider.Settings; import android.test.AndroidTestCase; import android.text.TextUtils; import android.util.Log; +import android.util.Pair; import androidx.test.InstrumentationRegistry; @@ -847,30 +849,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { keepalivesPerTransport, nc); } - private boolean isKeepaliveSupported() throws Exception { - final Network network = ensureWifiConnected(); - final Executor executor = mContext.getMainExecutor(); - final TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(); - try (Socket s = getConnectedSocket(network, TEST_HOST, - HTTP_PORT, KEEPALIVE_SOCKET_TIMEOUT_MS, AF_INET); - SocketKeepalive sk = mCm.createSocketKeepalive(network, s, executor, callback)) { - sk.start(MIN_KEEPALIVE_INTERVAL); - final TestSocketKeepaliveCallback.CallbackValue result = callback.pollCallback(); - switch (result.callbackType) { - case ON_STARTED: - sk.stop(); - callback.expectStopped(); - return true; - case ON_ERROR: - if (result.error == SocketKeepalive.ERROR_UNSUPPORTED) return false; - // else fallthrough. - default: - fail("Got unexpected callback: " + result); - return false; - } - } - } - private void adoptShellPermissionIdentity() { mUiAutomation.adoptShellPermissionIdentity(); mShellPermissionIdentityAdopted = true; @@ -883,11 +861,85 @@ public class ConnectivityManagerTest extends AndroidTestCase { } } + private static boolean isTcpKeepaliveSupportedByKernel() { + final String kVersionString = VintfRuntimeInfo.getKernelVersion(); + return compareMajorMinorVersion(kVersionString, "4.8") >= 0; + } + + private static Pair getVersionFromString(String version) { + // Only gets major and minor number of the version string. + final Pattern versionPattern = Pattern.compile("^(\\d+)(\\.(\\d+))?.*"); + final Matcher m = versionPattern.matcher(version); + if (m.matches()) { + final int major = Integer.parseInt(m.group(1)); + final int minor = TextUtils.isEmpty(m.group(3)) ? 0 : Integer.parseInt(m.group(3)); + return new Pair<>(major, minor); + } else { + return new Pair<>(0, 0); + } + } + + // TODO: Move to util class. + private static int compareMajorMinorVersion(final String s1, final String s2) { + final Pair v1 = getVersionFromString(s1); + final Pair v2 = getVersionFromString(s2); + + if (v1.first == v2.first) { + return Integer.compare(v1.second, v2.second); + } else { + return Integer.compare(v1.first, v2.first); + } + } + + /** + * Verifies that version string compare logic returns expected result for various cases. + * Note that only major and minor number are compared. + */ + public void testMajorMinorVersionCompare() { + assertEquals(0, compareMajorMinorVersion("4.8.1", "4.8")); + assertEquals(1, compareMajorMinorVersion("4.9", "4.8.1")); + assertEquals(1, compareMajorMinorVersion("5.0", "4.8")); + assertEquals(1, compareMajorMinorVersion("5", "4.8")); + assertEquals(0, compareMajorMinorVersion("5", "5.0")); + assertEquals(1, compareMajorMinorVersion("5-beta1", "4.8")); + assertEquals(0, compareMajorMinorVersion("4.8.0.0", "4.8")); + assertEquals(0, compareMajorMinorVersion("4.8-RC1", "4.8")); + assertEquals(0, compareMajorMinorVersion("4.8", "4.8")); + assertEquals(-1, compareMajorMinorVersion("3.10", "4.8.0")); + assertEquals(-1, compareMajorMinorVersion("4.7.10.10", "4.8")); + } + + /** + * Verifies that the keepalive API cannot create any keepalive when the maximum number of + * keepalives is set to 0. + */ + @AppModeFull(reason = "Cannot get WifiManager in instant app mode") + public void testKeepaliveUnsupported() throws Exception { + if (getSupportedKeepalivesFromRes() != 0) return; + + adoptShellPermissionIdentity(); + + assertEquals(0, createConcurrentSocketKeepalives(1, 0)); + assertEquals(0, createConcurrentSocketKeepalives(0, 1)); + + dropShellPermissionIdentity(); + } + @AppModeFull(reason = "Cannot get WifiManager in instant app mode") public void testCreateTcpKeepalive() throws Exception { adoptShellPermissionIdentity(); - if (!isKeepaliveSupported()) return; + if (getSupportedKeepalivesFromRes() == 0) return; + // If kernel < 4.8 then it doesn't support TCP keepalive, but it might still support + // NAT-T keepalive. If keepalive limits from resource overlay is not zero, TCP keepalive + // needs to be supported except if the kernel doesn't support it. + if (!isTcpKeepaliveSupportedByKernel()) { + // Sanity check to ensure the callback result is expected. + assertEquals(0, createConcurrentSocketKeepalives(0, 1)); + Log.i(TAG, "testCreateTcpKeepalive is skipped for kernel " + + VintfRuntimeInfo.getKernelVersion()); + return; + } final Network network = ensureWifiConnected(); final byte[] requestBytes = CtsNetUtils.HTTP_REQUEST.getBytes("UTF-8"); @@ -952,14 +1004,16 @@ public class ConnectivityManagerTest extends AndroidTestCase { sk.start(MIN_KEEPALIVE_INTERVAL); callback.expectError(SocketKeepalive.ERROR_SOCKET_NOT_IDLE); } - } } + /** + * Creates concurrent keepalives until the specified counts of each type of keepalives are + * reached or the expected error callbacks are received for each type of keepalives. + * + * @return the total number of keepalives created. + */ private int createConcurrentSocketKeepalives(int nattCount, int tcpCount) throws Exception { - // Use customization value in resource to prevent the need of privilege. - if (getSupportedKeepalivesFromRes() == 0) return 0; - final Network network = ensureWifiConnected(); final ArrayList kalist = new ArrayList<>(); @@ -978,10 +1032,14 @@ public class ConnectivityManagerTest extends AndroidTestCase { ka.start(MIN_KEEPALIVE_INTERVAL); TestSocketKeepaliveCallback.CallbackValue cv = callback.pollCallback(); assertNotNull(cv); - if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_ERROR - && cv.error == SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES) { - // Limit reached. - break; + if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_ERROR) { + if (i == 0 && cv.error == SocketKeepalive.ERROR_UNSUPPORTED) { + // Unsupported. + break; + } else if (i != 0 && cv.error == SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES) { + // Limit reached. + break; + } } if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_STARTED) { kalist.add(ka); @@ -1007,10 +1065,14 @@ public class ConnectivityManagerTest extends AndroidTestCase { ka.start(MIN_KEEPALIVE_INTERVAL); TestSocketKeepaliveCallback.CallbackValue cv = callback.pollCallback(); assertNotNull(cv); - if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_ERROR - && cv.error == SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES) { - // Limit reached. - break; + if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_ERROR) { + if (i == 0 && cv.error == SocketKeepalive.ERROR_UNSUPPORTED) { + // Unsupported. + break; + } else if (i != 0 && cv.error == SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES) { + // Limit reached. + break; + } } if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_STARTED) { kalist.add(ka); @@ -1038,32 +1100,35 @@ public class ConnectivityManagerTest extends AndroidTestCase { */ @AppModeFull(reason = "Cannot get WifiManager in instant app mode") public void testSocketKeepaliveLimit() throws Exception { - adoptShellPermissionIdentity(); - final int supported = getSupportedKeepalivesFromRes(); - - if (!isKeepaliveSupported()) { - // Sanity check. - assertEquals(0, supported); + if (supported == 0) { return; } + adoptShellPermissionIdentity(); + // Verifies that the supported keepalive slots meet MIN_SUPPORTED_KEEPALIVE_COUNT. assertGreaterOrEqual(supported, KeepaliveUtils.MIN_SUPPORTED_KEEPALIVE_COUNT); - // Verifies that different types of keepalives can be established. + // Verifies that Nat-T keepalives can be established. assertEquals(supported, createConcurrentSocketKeepalives(supported + 1, 0)); - assertEquals(supported, createConcurrentSocketKeepalives(0, supported + 1)); - - // Verifies that different types can be established at the same time. - assertEquals(supported, createConcurrentSocketKeepalives( - supported / 2, supported - supported / 2)); - // Verifies that keepalives don't get leaked in second round. assertEquals(supported, createConcurrentSocketKeepalives(supported + 1, 0)); - assertEquals(supported, createConcurrentSocketKeepalives(0, supported + 1)); - assertEquals(supported, createConcurrentSocketKeepalives( - supported / 2, supported - supported / 2)); + + // If kernel < 4.8 then it doesn't support TCP keepalive, but it might still support + // NAT-T keepalive. Test below cases only if TCP keepalive is supported by kernel. + if (isTcpKeepaliveSupportedByKernel()) { + assertEquals(supported, createConcurrentSocketKeepalives(0, supported + 1)); + + // Verifies that different types can be established at the same time. + assertEquals(supported, createConcurrentSocketKeepalives( + supported / 2, supported - supported / 2)); + + // Verifies that keepalives don't get leaked in second round. + assertEquals(supported, createConcurrentSocketKeepalives(0, supported + 1)); + assertEquals(supported, createConcurrentSocketKeepalives( + supported / 2, supported - supported / 2)); + } dropShellPermissionIdentity(); } @@ -1074,14 +1139,9 @@ public class ConnectivityManagerTest extends AndroidTestCase { @AppModeFull(reason = "Cannot get WifiManager in instant app mode") public void testSocketKeepaliveUnprivileged() throws Exception { final int supported = getSupportedKeepalivesFromRes(); - - adoptShellPermissionIdentity(); - if (!isKeepaliveSupported()) { - // Sanity check. - assertEquals(0, supported); + if (supported == 0) { return; } - dropShellPermissionIdentity(); final int allowedUnprivilegedPerUid = mContext.getResources().getInteger( R.integer.config_allowedUnprivilegedKeepalivePerUid); From 0b35214faaca44f77e9d0972c2cfd12f2c2c8523 Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Thu, 30 May 2019 04:46:32 -0700 Subject: [PATCH 0643/1109] Add bypass private DNS test case and null network test for DnsResolver cts 1. add test case for testing bypass Private DNS 2. add null network test 3. minor change for cleanup Bug: 130594022 Test: atest DnsResolverTest Merged-In: I8dd48f11baf92d953ded237204a3c2cd3b58581d (cherry picked from commit da665a0a78a2919c3e2edabafec463de3de9ddb7) Change-Id: Iabb100c51fd80eca5ab0284bc891f4fb98492e8b --- .../src/android/net/cts/DnsResolverTest.java | 374 +++++++++++------- 1 file changed, 227 insertions(+), 147 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/DnsResolverTest.java b/tests/cts/net/src/android/net/cts/DnsResolverTest.java index 945f51dbc8..e16fce09bf 100644 --- a/tests/cts/net/src/android/net/cts/DnsResolverTest.java +++ b/tests/cts/net/src/android/net/cts/DnsResolverTest.java @@ -21,20 +21,25 @@ import static android.net.DnsResolver.FLAG_EMPTY; import static android.net.DnsResolver.FLAG_NO_CACHE_LOOKUP; import static android.net.DnsResolver.TYPE_A; import static android.net.DnsResolver.TYPE_AAAA; -import static android.system.OsConstants.EBADF; +import static android.system.OsConstants.ETIMEDOUT; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; +import android.content.ContentResolver; import android.net.ConnectivityManager; +import android.net.ConnectivityManager.NetworkCallback; import android.net.DnsPacket; import android.net.DnsResolver; +import android.net.LinkProperties; import android.net.Network; import android.net.NetworkCapabilities; +import android.net.NetworkRequest; import android.net.ParseException; import android.os.CancellationSignal; import android.os.Handler; import android.os.Looper; +import android.provider.Settings; import android.system.ErrnoException; import android.test.AndroidTestCase; import android.util.Log; @@ -53,20 +58,63 @@ public class DnsResolverTest extends AndroidTestCase { private static final char[] HEX_CHARS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + + static final String TEST_DOMAIN = "www.google.com"; + static final String INVALID_PRIVATE_DNS_SERVER = "invalid.google"; + static final byte[] TEST_BLOB = new byte[]{ + /* Header */ + 0x55, 0x66, /* Transaction ID */ + 0x01, 0x00, /* Flags */ + 0x00, 0x01, /* Questions */ + 0x00, 0x00, /* Answer RRs */ + 0x00, 0x00, /* Authority RRs */ + 0x00, 0x00, /* Additional RRs */ + /* Queries */ + 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65, + 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */ + 0x00, 0x01, /* Type */ + 0x00, 0x01 /* Class */ + }; static final int TIMEOUT_MS = 12_000; static final int CANCEL_TIMEOUT_MS = 3_000; static final int CANCEL_RETRY_TIMES = 5; static final int NXDOMAIN = 3; + static final int PRIVATE_DNS_SETTING_TIMEOUT_MS = 2_000; + private ContentResolver mCR; private ConnectivityManager mCM; private Executor mExecutor; private DnsResolver mDns; + private String mOldMode; + private String mOldDnsSpecifier; + + @Override protected void setUp() throws Exception { super.setUp(); mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); mDns = DnsResolver.getInstance(); mExecutor = new Handler(Looper.getMainLooper())::post; + mCR = getContext().getContentResolver(); + storePrivateDnsSetting(); + } + + @Override + protected void tearDown() throws Exception { + 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() { + // 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 static String byteArrayToHexString(byte[] bytes) { @@ -94,6 +142,9 @@ public class DnsResolverTest extends AndroidTestCase { "This test requires that at least one network be connected. " + "Please ensure that the device is connected to a network.", testableNetworks.size() >= 1); + // In order to test query with null network, add null as an element. + // Test cases which query with null network will go on default network. + testableNetworks.add(null); return testableNetworks.toArray(new Network[0]); } @@ -105,15 +156,12 @@ public class DnsResolverTest extends AndroidTestCase { public DnsParseException(String msg) { super(msg); } - - public DnsParseException(String msg, Throwable cause) { - super(msg, cause); - } } private static class DnsAnswer extends DnsPacket { DnsAnswer(@NonNull byte[] data) throws DnsParseException { super(data); + // Check QR field.(query (0), or a response (1)). if ((mHeader.flags & (1 << 15)) == 0) { throw new DnsParseException("Not an answer packet"); @@ -123,10 +171,12 @@ public class DnsResolverTest extends AndroidTestCase { int getRcode() { return mHeader.rcode; } - int getANCount(){ + + int getANCount() { return mHeader.getRecordCount(ANSECTION); } - int getQDCount(){ + + int getQDCount() { return mHeader.getRecordCount(QDSECTION); } } @@ -173,7 +223,7 @@ public class DnsResolverTest extends AndroidTestCase { mRcode = rcode; try { mDnsAnswer = new DnsAnswer(answer); - } catch (DnsParseException e) { + } catch (ParseException | DnsParseException e) { fail(mMsg + e.getMessage()); } Log.d(TAG, "Reported blob: " + byteArrayToHexString(answer)); @@ -222,90 +272,76 @@ public class DnsResolverTest extends AndroidTestCase { } } - public void testRawQuery() { - final String dname = "www.google.com"; - final String msg = "RawQuery " + dname; + public void testRawQuery() throws InterruptedException { + final String msg = "RawQuery " + TEST_DOMAIN; for (Network network : getTestableNetworks()) { final VerifyCancelCallback callback = new VerifyCancelCallback(msg); - mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, + mDns.rawQuery(network, TEST_DOMAIN, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); - try { - assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", - callback.waitForAnswer()); - callback.assertHasAnswer(); - } catch (InterruptedException e) { - fail(msg + " Waiting for DNS lookup was interrupted"); - } + + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + callback.waitForAnswer()); + callback.assertHasAnswer(); } } - public void testRawQueryBlob() { + public void testRawQueryBlob() throws InterruptedException { final byte[] blob = new byte[]{ - /* Header */ - 0x55, 0x66, /* Transaction ID */ - 0x01, 0x00, /* Flags */ - 0x00, 0x01, /* Questions */ - 0x00, 0x00, /* Answer RRs */ - 0x00, 0x00, /* Authority RRs */ - 0x00, 0x00, /* Additional RRs */ - /* Queries */ - 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65, - 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */ - 0x00, 0x01, /* Type */ - 0x00, 0x01 /* Class */ + /* Header */ + 0x55, 0x66, /* Transaction ID */ + 0x01, 0x00, /* Flags */ + 0x00, 0x01, /* Questions */ + 0x00, 0x00, /* Answer RRs */ + 0x00, 0x00, /* Authority RRs */ + 0x00, 0x00, /* Additional RRs */ + /* Queries */ + 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65, + 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */ + 0x00, 0x01, /* Type */ + 0x00, 0x01 /* Class */ }; final String msg = "RawQuery blob " + byteArrayToHexString(blob); for (Network network : getTestableNetworks()) { final VerifyCancelCallback callback = new VerifyCancelCallback(msg); mDns.rawQuery(network, blob, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); - try { - assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", - callback.waitForAnswer()); - callback.assertHasAnswer(); - } catch (InterruptedException e) { - fail(msg + " Waiting for DNS lookup was interrupted"); - } + + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + callback.waitForAnswer()); + callback.assertHasAnswer(); } } - public void testRawQueryRoot() { + public void testRawQueryRoot() throws InterruptedException { final String dname = ""; final String msg = "RawQuery empty dname(ROOT) "; for (Network network : getTestableNetworks()) { final VerifyCancelCallback callback = new VerifyCancelCallback(msg); mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); - try { - assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", - callback.waitForAnswer()); - // Except no answer record because the root does not have AAAA records. - callback.assertEmptyAnswer(); - } catch (InterruptedException e) { - fail(msg + " Waiting for DNS lookup was interrupted"); - } + + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + callback.waitForAnswer()); + // Except no answer record because the root does not have AAAA records. + callback.assertEmptyAnswer(); } } - public void testRawQueryNXDomain() { + public void testRawQueryNXDomain() throws InterruptedException { final String dname = "test1-nx.metric.gstatic.com"; final String msg = "RawQuery " + dname; for (Network network : getTestableNetworks()) { final VerifyCancelCallback callback = new VerifyCancelCallback(msg); mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); - try { - assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", - callback.waitForAnswer()); - callback.assertNXDomain(); - } catch (InterruptedException e) { - fail(msg + " Waiting for DNS lookup was interrupted"); - } + + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + callback.waitForAnswer()); + callback.assertNXDomain(); } } - public void testRawQueryCancel() throws ErrnoException { - final String dname = "www.google.com"; - final String msg = "Test cancel RawQuery " + dname; + public void testRawQueryCancel() throws InterruptedException { + final String msg = "Test cancel RawQuery " + TEST_DOMAIN; // Start a DNS query and the cancel it immediately. Use VerifyCancelCallback to expect // that the query is cancelled before it succeeds. If it is not cancelled before it // succeeds, retry the test until it is. @@ -319,39 +355,22 @@ public class DnsResolverTest extends AndroidTestCase { final CountDownLatch latch = new CountDownLatch(1); final CancellationSignal cancelSignal = new CancellationSignal(); final VerifyCancelCallback callback = new VerifyCancelCallback(msg, cancelSignal); - mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_EMPTY, + mDns.rawQuery(network, TEST_DOMAIN, CLASS_IN, TYPE_AAAA, FLAG_EMPTY, mExecutor, cancelSignal, callback); mExecutor.execute(() -> { cancelSignal.cancel(); latch.countDown(); }); - try { - retry = callback.needRetry(); - assertTrue(msg + " query was not cancelled", - latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - } catch (InterruptedException e) { - fail(msg + " Waiting for DNS lookup was interrupted"); - } + + retry = callback.needRetry(); + assertTrue(msg + " query was not cancelled", + latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); } while (retry); } } - public void testRawQueryBlobCancel() throws ErrnoException { - final byte[] blob = new byte[]{ - /* Header */ - 0x55, 0x66, /* Transaction ID */ - 0x01, 0x00, /* Flags */ - 0x00, 0x01, /* Questions */ - 0x00, 0x00, /* Answer RRs */ - 0x00, 0x00, /* Authority RRs */ - 0x00, 0x00, /* Additional RRs */ - /* Queries */ - 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65, - 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */ - 0x00, 0x01, /* Type */ - 0x00, 0x01 /* Class */ - }; - final String msg = "Test cancel RawQuery blob " + byteArrayToHexString(blob); + public void testRawQueryBlobCancel() throws InterruptedException { + final String msg = "Test cancel RawQuery blob " + byteArrayToHexString(TEST_BLOB); // Start a DNS query and the cancel it immediately. Use VerifyCancelCallback to expect // that the query is cancelled before it succeeds. If it is not cancelled before it // succeeds, retry the test until it is. @@ -365,37 +384,30 @@ public class DnsResolverTest extends AndroidTestCase { final CountDownLatch latch = new CountDownLatch(1); final CancellationSignal cancelSignal = new CancellationSignal(); final VerifyCancelCallback callback = new VerifyCancelCallback(msg, cancelSignal); - mDns.rawQuery(network, blob, FLAG_EMPTY, mExecutor, cancelSignal, callback); + mDns.rawQuery(network, TEST_BLOB, FLAG_EMPTY, mExecutor, cancelSignal, callback); mExecutor.execute(() -> { cancelSignal.cancel(); latch.countDown(); }); - try { - retry = callback.needRetry(); - assertTrue(msg + " cancel is not done", - latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - } catch (InterruptedException e) { - fail(msg + " Waiting for DNS lookup was interrupted"); - } + + retry = callback.needRetry(); + assertTrue(msg + " cancel is not done", + latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); } while (retry); } } - public void testCancelBeforeQuery() throws ErrnoException { - final String dname = "www.google.com"; - final String msg = "Test cancelled RawQuery " + dname; + public void testCancelBeforeQuery() throws InterruptedException { + final String msg = "Test cancelled RawQuery " + TEST_DOMAIN; for (Network network : getTestableNetworks()) { final VerifyCancelCallback callback = new VerifyCancelCallback(msg); final CancellationSignal cancelSignal = new CancellationSignal(); cancelSignal.cancel(); - mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_EMPTY, + mDns.rawQuery(network, TEST_DOMAIN, CLASS_IN, TYPE_AAAA, FLAG_EMPTY, mExecutor, cancelSignal, callback); - try { - assertTrue(msg + " should not return any answers", - !callback.waitForAnswer(CANCEL_TIMEOUT_MS)); - } catch (InterruptedException e) { - fail(msg + " Waiting for DNS lookup was interrupted"); - } + + assertTrue(msg + " should not return any answers", + !callback.waitForAnswer(CANCEL_TIMEOUT_MS)); } } @@ -462,27 +474,21 @@ public class DnsResolverTest extends AndroidTestCase { } } - public void testQueryForInetAddress() { - final String dname = "www.google.com"; - final String msg = "Test query for InetAddress " + dname; + public void testQueryForInetAddress() throws InterruptedException { + final String msg = "Test query for InetAddress " + TEST_DOMAIN; for (Network network : getTestableNetworks()) { final VerifyCancelInetAddressCallback callback = new VerifyCancelInetAddressCallback(msg, null); - mDns.query(network, dname, FLAG_NO_CACHE_LOOKUP, - mExecutor, null, callback); - try { - assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", - callback.waitForAnswer()); - assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty()); - } catch (InterruptedException e) { - fail(msg + " Waiting for DNS lookup was interrupted"); - } + mDns.query(network, TEST_DOMAIN, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); + + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + callback.waitForAnswer()); + assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty()); } } - public void testQueryCancelForInetAddress() throws ErrnoException { - final String dname = "www.google.com"; - final String msg = "Test cancel query for InetAddress " + dname; + public void testQueryCancelForInetAddress() throws InterruptedException { + final String msg = "Test cancel query for InetAddress " + TEST_DOMAIN; // Start a DNS query and the cancel it immediately. Use VerifyCancelInetAddressCallback to // expect that the query is cancelled before it succeeds. If it is not cancelled before it // succeeds, retry the test until it is. @@ -497,57 +503,131 @@ public class DnsResolverTest extends AndroidTestCase { final CancellationSignal cancelSignal = new CancellationSignal(); final VerifyCancelInetAddressCallback callback = new VerifyCancelInetAddressCallback(msg, cancelSignal); - mDns.query(network, dname, FLAG_EMPTY, mExecutor, cancelSignal, callback); + mDns.query(network, TEST_DOMAIN, FLAG_EMPTY, mExecutor, cancelSignal, callback); mExecutor.execute(() -> { cancelSignal.cancel(); latch.countDown(); }); - try { - retry = callback.needRetry(); - assertTrue(msg + " query was not cancelled", - latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - } catch (InterruptedException e) { - fail(msg + " Waiting for DNS lookup was interrupted"); - } + + retry = callback.needRetry(); + assertTrue(msg + " query was not cancelled", + latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); } while (retry); } } - public void testQueryForInetAddressIpv4() { - final String dname = "www.google.com"; - final String msg = "Test query for IPv4 InetAddress " + dname; + public void testQueryForInetAddressIpv4() throws InterruptedException { + final String msg = "Test query for IPv4 InetAddress " + TEST_DOMAIN; for (Network network : getTestableNetworks()) { final VerifyCancelInetAddressCallback callback = new VerifyCancelInetAddressCallback(msg, null); - mDns.query(network, dname, TYPE_A, FLAG_NO_CACHE_LOOKUP, + mDns.query(network, TEST_DOMAIN, TYPE_A, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); - try { - assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", - callback.waitForAnswer()); - assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty()); - assertTrue(msg + " returned Ipv6 results", !callback.hasIpv6Answer()); - } catch (InterruptedException e) { - fail(msg + " Waiting for DNS lookup was interrupted"); - } + + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + callback.waitForAnswer()); + assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty()); + assertTrue(msg + " returned Ipv6 results", !callback.hasIpv6Answer()); } } - public void testQueryForInetAddressIpv6() { - final String dname = "www.google.com"; - final String msg = "Test query for IPv6 InetAddress " + dname; + public void testQueryForInetAddressIpv6() throws InterruptedException { + final String msg = "Test query for IPv6 InetAddress " + TEST_DOMAIN; for (Network network : getTestableNetworks()) { final VerifyCancelInetAddressCallback callback = new VerifyCancelInetAddressCallback(msg, null); - mDns.query(network, dname, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, + mDns.query(network, TEST_DOMAIN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); - try { - assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", - callback.waitForAnswer()); - assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty()); - assertTrue(msg + " returned Ipv4 results", !callback.hasIpv4Answer()); - } catch (InterruptedException e) { - fail(msg + " Waiting for DNS lookup was interrupted"); + + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + callback.waitForAnswer()); + assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty()); + assertTrue(msg + " returned Ipv4 results", !callback.hasIpv4Answer()); + } + } + + private void awaitPrivateDnsSetting(@NonNull String msg, + @NonNull Network network, @NonNull String server) throws InterruptedException { + CountDownLatch latch = new CountDownLatch(1); + NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build(); + NetworkCallback callback = new NetworkCallback() { + @Override + public void onLinkPropertiesChanged(Network n, LinkProperties lp) { + if (network.equals(n) && server.equals(lp.getPrivateDnsServerName())) { + latch.countDown(); + } } + }; + mCM.registerNetworkCallback(request, callback); + assertTrue(msg, latch.await(PRIVATE_DNS_SETTING_TIMEOUT_MS, TimeUnit.MILLISECONDS)); + mCM.unregisterNetworkCallback(callback); + } + + public void testPrivateDnsBypass() throws InterruptedException { + 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); + + 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 + // private DNS bypassable network or bind one. + if (network == null) continue; + + // wait for private DNS setting propagating + awaitPrivateDnsSetting(msg + " wait private DNS setting timeout", + network, INVALID_PRIVATE_DNS_SERVER); + + final CountDownLatch latch = new CountDownLatch(1); + final DnsResolver.Callback> errorCallback = + new DnsResolver.Callback>() { + @Override + public void onAnswer(@NonNull List answerList, int rcode) { + fail(msg + " should not get valid answer"); + } + + @Override + public void onError(@NonNull DnsResolver.DnsException error) { + assertEquals(DnsResolver.ERROR_SYSTEM, error.code); + assertEquals(ETIMEDOUT, ((ErrnoException) error.getCause()).errno); + latch.countDown(); + } + }; + // Private DNS strict mode with invalid DNS server is set + // Expect no valid answer returned but ErrnoException with ETIMEDOUT + mDns.query(network, TEST_DOMAIN, FLAG_NO_CACHE_LOOKUP, mExecutor, null, errorCallback); + + assertTrue(msg + " invalid server round. No response after " + TIMEOUT_MS + "ms.", + latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); + + final VerifyCancelInetAddressCallback callback = + new VerifyCancelInetAddressCallback(msg, null); + // Bypass privateDns, expect query works fine + mDns.query(network.getPrivateDnsBypassingCopy(), + TEST_DOMAIN, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); + + assertTrue(msg + " bypass private DNS round. No answer after " + TIMEOUT_MS + "ms.", + callback.waitForAnswer()); + assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty()); + + // To ensure private DNS bypass still work even if passing null network. + // Bind process network with a private DNS bypassable network. + mCM.bindProcessToNetwork(network.getPrivateDnsBypassingCopy()); + final VerifyCancelInetAddressCallback callbackWithNullNetwork = + new VerifyCancelInetAddressCallback(msg + " with null network ", null); + mDns.query(null, + TEST_DOMAIN, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callbackWithNullNetwork); + + assertTrue(msg + " with null network bypass private DNS round. No answer after " + + TIMEOUT_MS + "ms.", callbackWithNullNetwork.waitForAnswer()); + assertTrue(msg + " with null network returned 0 results", + !callbackWithNullNetwork.isAnswerEmpty()); + + // Reset process network to default. + mCM.bindProcessToNetwork(null); } } } From a0279520f04a3c820ee554c78af8d67a92f8eb53 Mon Sep 17 00:00:00 2001 From: Benedict Wong Date: Fri, 31 May 2019 06:23:01 -0700 Subject: [PATCH 0644/1109] Cleanup IPsec CTS tests This commit addresses comments from aosp/963067 and aosp/959617. No behavioral/functional changes were made, only renames and minor style nits addressed. Bug: 72950854 Test: Ran on devices, working Merged-In: I1702b91e245412f0142e9e47b7fb373b9b4e8126 Change-Id: I1702b91e245412f0142e9e47b7fb373b9b4e8126 (cherry picked from commit 68237a11f9532ca6c59d579adb374fe40b0b3bee) --- .../src/android/net/cts/IpSecManagerTest.java | 6 ---- .../net/cts/IpSecManagerTunnelTest.java | 34 +++++++++---------- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java index 1241785a17..d6b8a968d2 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java @@ -73,12 +73,6 @@ public class IpSecManagerTest extends IpSecBaseTest { private static final byte[] AEAD_KEY = getKey(288); - @Before - @Override - public void setUp() throws Exception { - super.setUp(); - } - /* * Allocate a random SPI * Allocate a specific SPI using previous randomly created SPI value diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java index 93638ac3b5..828abccf58 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java @@ -127,15 +127,15 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { // right appop permissions. setAppop(OP_MANAGE_IPSEC_TUNNELS, true); - TestNetworkInterface testIntf = + TestNetworkInterface testIface = sTNM.createTunInterface( new LinkAddress[] { new LinkAddress(LOCAL_OUTER_4, IP4_PREFIX_LEN), new LinkAddress(LOCAL_OUTER_6, IP6_PREFIX_LEN) }); - sTunFd = testIntf.getFileDescriptor(); - sTunNetworkCallback = setupAndGetTestNetwork(testIntf.getInterfaceName()); + sTunFd = testIface.getFileDescriptor(); + sTunNetworkCallback = setupAndGetTestNetwork(testIface.getInterfaceName()); sTunNetwork = sTunNetworkCallback.getNetworkBlocking(); sTunUtils = new TunUtils(sTunFd); @@ -498,21 +498,20 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { mISM.allocateSecurityParameterIndex(localOuter, spi); IpSecManager.SecurityParameterIndex outSpi = mISM.allocateSecurityParameterIndex(remoteOuter, spi); - IpSecManager.IpSecTunnelInterface tunnelIntf = + IpSecManager.IpSecTunnelInterface tunnelIface = mISM.createIpSecTunnelInterface(localOuter, remoteOuter, sTunNetwork)) { // Build the test network - tunnelIntf.addAddress(localInner, innerPrefixLen); - testNetworkCb = setupAndGetTestNetwork(tunnelIntf.getInterfaceName()); + tunnelIface.addAddress(localInner, innerPrefixLen); + testNetworkCb = setupAndGetTestNetwork(tunnelIface.getInterfaceName()); Network testNetwork = testNetworkCb.getNetworkBlocking(); // Check interface was created - NetworkInterface netIntf = NetworkInterface.getByName(tunnelIntf.getInterfaceName()); - assertNotNull(netIntf); + assertNotNull(NetworkInterface.getByName(tunnelIface.getInterfaceName())); // Verify address was added - netIntf = NetworkInterface.getByInetAddress(localInner); - assertNotNull(netIntf); - assertEquals(tunnelIntf.getInterfaceName(), netIntf.getDisplayName()); + final NetworkInterface netIface = NetworkInterface.getByInetAddress(localInner); + assertNotNull(netIface); + assertEquals(tunnelIface.getInterfaceName(), netIface.getDisplayName()); // Configure Transform parameters IpSecTransform.Builder transformBuilder = new IpSecTransform.Builder(sContext); @@ -531,8 +530,9 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { transformBuilder.buildTunnelModeTransform(remoteOuter, inSpi); IpSecTransform outTransform = transformBuilder.buildTunnelModeTransform(localOuter, outSpi)) { - mISM.applyTunnelModeTransform(tunnelIntf, IpSecManager.DIRECTION_IN, inTransform); - mISM.applyTunnelModeTransform(tunnelIntf, IpSecManager.DIRECTION_OUT, outTransform); + mISM.applyTunnelModeTransform(tunnelIface, IpSecManager.DIRECTION_IN, inTransform); + mISM.applyTunnelModeTransform( + tunnelIface, IpSecManager.DIRECTION_OUT, outTransform); test.run(testNetwork); } @@ -541,13 +541,13 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { sTNM.teardownTestNetwork(testNetwork); // Remove addresses and check that interface is still present, but fails lookup-by-addr - tunnelIntf.removeAddress(localInner, innerPrefixLen); - assertNotNull(NetworkInterface.getByName(tunnelIntf.getInterfaceName())); + tunnelIface.removeAddress(localInner, innerPrefixLen); + assertNotNull(NetworkInterface.getByName(tunnelIface.getInterfaceName())); assertNull(NetworkInterface.getByInetAddress(localInner)); // Check interface was cleaned up - tunnelIntf.close(); - assertNull(NetworkInterface.getByName(tunnelIntf.getInterfaceName())); + tunnelIface.close(); + assertNull(NetworkInterface.getByName(tunnelIface.getInterfaceName())); } finally { if (testNetworkCb != null) { sCM.unregisterNetworkCallback(testNetworkCb); From 2cb7034baf20565153a6c7f2f830e69ff4bbf659 Mon Sep 17 00:00:00 2001 From: Benedict Wong Date: Mon, 8 Apr 2019 11:18:27 -0700 Subject: [PATCH 0645/1109] Add reflected-packet based data tests This commit adds tests that reflect outgoing packets, flipping the outer src/dst headers to avoid the need to tear down and rebuild the outer TUN. This allows us to at least test that our implementation can interoperate with itself. Bug: 72950854 Test: this, passing Merged-In: Ia969f78f4c1a0c0a017f5aad425a68852ff4433a Change-Id: Ia969f78f4c1a0c0a017f5aad425a68852ff4433a (cherry picked from commit 144937f3df37ee0b1d5484f10e8c86a8a70a9cb5) --- .../net/cts/IpSecManagerTunnelTest.java | 251 ++++++++++++++++-- 1 file changed, 229 insertions(+), 22 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java index 828abccf58..d1438ec56d 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java @@ -240,8 +240,16 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { } /* Test runnables for callbacks after IPsec tunnels are set up. */ - private interface TestRunnable { - void run(Network ipsecNetwork) throws Exception; + private abstract class IpSecTunnelTestRunnable { + /** + * Runs the test code, and returns the inner socket port, if any. + * + * @param ipsecNetwork The IPsec Interface based Network for binding sockets on + * @return the integer port of the inner socket if outbound, or 0 if inbound + * IpSecTunnelTestRunnable + * @throws Exception if any part of the test failed. + */ + public abstract int run(Network ipsecNetwork) throws Exception; } private static class TestNetworkCallback extends ConnectivityManager.NetworkCallback { @@ -288,8 +296,8 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { return expectedPacketSize; } - private interface TestRunnableFactory { - TestRunnable getTestRunnable( + private interface IpSecTunnelTestRunnableFactory { + IpSecTunnelTestRunnable getIpSecTunnelTestRunnable( boolean transportInTunnelMode, int spi, InetAddress localInner, @@ -299,12 +307,13 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { IpSecTransform inTransportTransform, IpSecTransform outTransportTransform, int encapPort, + int innerSocketPort, int expectedPacketSize) throws Exception; } - private class OutputTestRunnableFactory implements TestRunnableFactory { - public TestRunnable getTestRunnable( + private class OutputIpSecTunnelTestRunnableFactory implements IpSecTunnelTestRunnableFactory { + public IpSecTunnelTestRunnable getIpSecTunnelTestRunnable( boolean transportInTunnelMode, int spi, InetAddress localInner, @@ -314,13 +323,15 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { IpSecTransform inTransportTransform, IpSecTransform outTransportTransform, int encapPort, + int unusedInnerSocketPort, int expectedPacketSize) { - return new TestRunnable() { + return new IpSecTunnelTestRunnable() { @Override - public void run(Network ipsecNetwork) throws Exception { + public int run(Network ipsecNetwork) throws Exception { // Build a socket and send traffic JavaUdpSocket socket = new JavaUdpSocket(localInner); ipsecNetwork.bindSocket(socket.mSocket); + int innerSocketPort = socket.getPort(); // For Transport-In-Tunnel mode, apply transform to socket if (transportInTunnelMode) { @@ -333,19 +344,22 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { socket.sendTo(TEST_DATA, remoteInner, socket.getPort()); // Verify that an encrypted packet is sent. As of right now, checking encrypted - // body is not possible, due to our not knowing some of the fields of the + // body is not possible, due to the test not knowing some of the fields of the // inner IP header (flow label, flags, etc) sTunUtils.awaitEspPacketNoPlaintext( spi, TEST_DATA, encapPort != 0, expectedPacketSize); socket.close(); + + return innerSocketPort; } }; } } - private class InputPacketGeneratorTestRunnableFactory implements TestRunnableFactory { - public TestRunnable getTestRunnable( + private class InputReflectedIpSecTunnelTestRunnableFactory + implements IpSecTunnelTestRunnableFactory { + public IpSecTunnelTestRunnable getIpSecTunnelTestRunnable( boolean transportInTunnelMode, int spi, InetAddress localInner, @@ -355,14 +369,57 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { IpSecTransform inTransportTransform, IpSecTransform outTransportTransform, int encapPort, + int innerSocketPort, int expectedPacketSize) throws Exception { - return new TestRunnable() { + return new IpSecTunnelTestRunnable() { @Override - public void run(Network ipsecNetwork) throws Exception { + public int run(Network ipsecNetwork) throws Exception { + // Build a socket and receive traffic + JavaUdpSocket socket = new JavaUdpSocket(localInner, innerSocketPort); + ipsecNetwork.bindSocket(socket.mSocket); + + // For Transport-In-Tunnel mode, apply transform to socket + if (transportInTunnelMode) { + mISM.applyTransportModeTransform( + socket.mSocket, IpSecManager.DIRECTION_IN, outTransportTransform); + mISM.applyTransportModeTransform( + socket.mSocket, IpSecManager.DIRECTION_OUT, inTransportTransform); + } + + sTunUtils.reflectPackets(); + + // Receive packet from socket, and validate that the payload is correct + receiveAndValidatePacket(socket); + + socket.close(); + + return 0; + } + }; + } + } + + private class InputPacketGeneratorIpSecTunnelTestRunnableFactory + implements IpSecTunnelTestRunnableFactory { + public IpSecTunnelTestRunnable getIpSecTunnelTestRunnable( + boolean transportInTunnelMode, + int spi, + InetAddress localInner, + InetAddress remoteInner, + InetAddress localOuter, + InetAddress remoteOuter, + IpSecTransform inTransportTransform, + IpSecTransform outTransportTransform, + int encapPort, + int innerSocketPort, + int expectedPacketSize) + throws Exception { + return new IpSecTunnelTestRunnable() { + @Override + public int run(Network ipsecNetwork) throws Exception { // Build a socket and receive traffic JavaUdpSocket socket = new JavaUdpSocket(localInner); - // JavaUdpSocket socket = new JavaUdpSocket(localInner, socketPort.get()); ipsecNetwork.bindSocket(socket.mSocket); // For Transport-In-Tunnel mode, apply transform to socket @@ -402,6 +459,8 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { receiveAndValidatePacket(socket); socket.close(); + + return 0; } }; } @@ -415,7 +474,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { outerFamily, useEncap, transportInTunnelMode, - new OutputTestRunnableFactory()); + new OutputIpSecTunnelTestRunnableFactory()); } private void checkTunnelInput( @@ -426,7 +485,91 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { outerFamily, useEncap, transportInTunnelMode, - new InputPacketGeneratorTestRunnableFactory()); + new InputPacketGeneratorIpSecTunnelTestRunnableFactory()); + } + + /** + * Validates that the kernel can talk to itself. + * + *

    This test takes an outbound IPsec packet, reflects it (by flipping IP src/dst), and + * injects it back into the TUN. This test then verifies that a packet with the correct payload + * is found on the specified socket/port. + */ + public void checkTunnelReflected( + int innerFamily, int outerFamily, boolean useEncap, boolean transportInTunnelMode) + throws Exception { + if (!hasTunnelsFeature()) return; + + InetAddress localInner = innerFamily == AF_INET ? LOCAL_INNER_4 : LOCAL_INNER_6; + InetAddress remoteInner = innerFamily == AF_INET ? REMOTE_INNER_4 : REMOTE_INNER_6; + + InetAddress localOuter = outerFamily == AF_INET ? LOCAL_OUTER_4 : LOCAL_OUTER_6; + InetAddress remoteOuter = outerFamily == AF_INET ? REMOTE_OUTER_4 : REMOTE_OUTER_6; + + // Preselect both SPI and encap port, to be used for both inbound and outbound tunnels. + int spi = getRandomSpi(localOuter, remoteOuter); + int expectedPacketSize = + getPacketSize(innerFamily, outerFamily, useEncap, transportInTunnelMode); + + try (IpSecManager.SecurityParameterIndex inTransportSpi = + mISM.allocateSecurityParameterIndex(localInner, spi); + IpSecManager.SecurityParameterIndex outTransportSpi = + mISM.allocateSecurityParameterIndex(remoteInner, spi); + IpSecTransform inTransportTransform = + buildIpSecTransform(sContext, inTransportSpi, null, remoteInner); + IpSecTransform outTransportTransform = + buildIpSecTransform(sContext, outTransportSpi, null, localInner); + UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) { + + // Run output direction tests + IpSecTunnelTestRunnable outputIpSecTunnelTestRunnable = + new OutputIpSecTunnelTestRunnableFactory() + .getIpSecTunnelTestRunnable( + transportInTunnelMode, + spi, + localInner, + remoteInner, + localOuter, + remoteOuter, + inTransportTransform, + outTransportTransform, + useEncap ? encapSocket.getPort() : 0, + 0, + expectedPacketSize); + int innerSocketPort = + buildTunnelNetworkAndRunTests( + localInner, + remoteInner, + localOuter, + remoteOuter, + spi, + useEncap ? encapSocket : null, + outputIpSecTunnelTestRunnable); + + // Input direction tests, with matching inner socket ports. + IpSecTunnelTestRunnable inputIpSecTunnelTestRunnable = + new InputReflectedIpSecTunnelTestRunnableFactory() + .getIpSecTunnelTestRunnable( + transportInTunnelMode, + spi, + remoteInner, + localInner, + localOuter, + remoteOuter, + inTransportTransform, + outTransportTransform, + useEncap ? encapSocket.getPort() : 0, + innerSocketPort, + expectedPacketSize); + buildTunnelNetworkAndRunTests( + remoteInner, + localInner, + localOuter, + remoteOuter, + spi, + useEncap ? encapSocket : null, + inputIpSecTunnelTestRunnable); + } } public void checkTunnel( @@ -434,7 +577,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { int outerFamily, boolean useEncap, boolean transportInTunnelMode, - TestRunnableFactory factory) + IpSecTunnelTestRunnableFactory factory) throws Exception { if (!hasTunnelsFeature()) return; @@ -461,14 +604,14 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { buildIpSecTransform(sContext, outTransportSpi, null, localInner); UdpEncapsulationSocket encapSocket = mISM.openUdpEncapsulationSocket()) { - buildTunnelAndNetwork( + buildTunnelNetworkAndRunTests( localInner, remoteInner, localOuter, remoteOuter, spi, useEncap ? encapSocket : null, - factory.getTestRunnable( + factory.getIpSecTunnelTestRunnable( transportInTunnelMode, spi, localInner, @@ -478,21 +621,23 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { inTransportTransform, outTransportTransform, useEncap ? encapSocket.getPort() : 0, + 0, expectedPacketSize)); } } - private void buildTunnelAndNetwork( + private int buildTunnelNetworkAndRunTests( InetAddress localInner, InetAddress remoteInner, InetAddress localOuter, InetAddress remoteOuter, int spi, UdpEncapsulationSocket encapSocket, - TestRunnable test) + IpSecTunnelTestRunnable test) throws Exception { int innerPrefixLen = localInner instanceof Inet6Address ? IP6_PREFIX_LEN : IP4_PREFIX_LEN; TestNetworkCallback testNetworkCb = null; + int innerSocketPort; try (IpSecManager.SecurityParameterIndex inSpi = mISM.allocateSecurityParameterIndex(localOuter, spi); @@ -534,7 +679,7 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { mISM.applyTunnelModeTransform( tunnelIface, IpSecManager.DIRECTION_OUT, outTransform); - test.run(testNetwork); + innerSocketPort = test.run(testNetwork); } // Teardown the test network @@ -553,6 +698,8 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { sCM.unregisterNetworkCallback(testNetworkCb); } } + + return innerSocketPort; } private static void receiveAndValidatePacket(JavaUdpSocket socket) throws Exception { @@ -675,36 +822,66 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { checkTunnelInput(AF_INET, AF_INET, false, true); } + @Test + public void testTransportInTunnelModeV4InV4Reflected() throws Exception { + checkTunnelReflected(AF_INET, AF_INET, false, true); + } + @Test public void testTransportInTunnelModeV4InV4UdpEncap() throws Exception { checkTunnelOutput(AF_INET, AF_INET, true, true); checkTunnelInput(AF_INET, AF_INET, true, true); } + @Test + public void testTransportInTunnelModeV4InV4UdpEncapReflected() throws Exception { + checkTunnelReflected(AF_INET, AF_INET, false, true); + } + @Test public void testTransportInTunnelModeV4InV6() throws Exception { checkTunnelOutput(AF_INET, AF_INET6, false, true); checkTunnelInput(AF_INET, AF_INET6, false, true); } + @Test + public void testTransportInTunnelModeV4InV6Reflected() throws Exception { + checkTunnelReflected(AF_INET, AF_INET, false, true); + } + @Test public void testTransportInTunnelModeV6InV4() throws Exception { checkTunnelOutput(AF_INET6, AF_INET, false, true); checkTunnelInput(AF_INET6, AF_INET, false, true); } + @Test + public void testTransportInTunnelModeV6InV4Reflected() throws Exception { + checkTunnelReflected(AF_INET, AF_INET, false, true); + } + @Test public void testTransportInTunnelModeV6InV4UdpEncap() throws Exception { checkTunnelOutput(AF_INET6, AF_INET, true, true); checkTunnelInput(AF_INET6, AF_INET, true, true); } + @Test + public void testTransportInTunnelModeV6InV4UdpEncapReflected() throws Exception { + checkTunnelReflected(AF_INET, AF_INET, false, true); + } + @Test public void testTransportInTunnelModeV6InV6() throws Exception { checkTunnelOutput(AF_INET, AF_INET6, false, true); checkTunnelInput(AF_INET, AF_INET6, false, true); } + @Test + public void testTransportInTunnelModeV6InV6Reflected() throws Exception { + checkTunnelReflected(AF_INET, AF_INET, false, true); + } + // Tunnel mode tests @Test public void testTunnelV4InV4() throws Exception { @@ -712,33 +889,63 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { checkTunnelInput(AF_INET, AF_INET, false, false); } + @Test + public void testTunnelV4InV4Reflected() throws Exception { + checkTunnelReflected(AF_INET, AF_INET, false, false); + } + @Test public void testTunnelV4InV4UdpEncap() throws Exception { checkTunnelOutput(AF_INET, AF_INET, true, false); checkTunnelInput(AF_INET, AF_INET, true, false); } + @Test + public void testTunnelV4InV4UdpEncapReflected() throws Exception { + checkTunnelReflected(AF_INET, AF_INET, true, false); + } + @Test public void testTunnelV4InV6() throws Exception { checkTunnelOutput(AF_INET, AF_INET6, false, false); checkTunnelInput(AF_INET, AF_INET6, false, false); } + @Test + public void testTunnelV4InV6Reflected() throws Exception { + checkTunnelReflected(AF_INET, AF_INET6, false, false); + } + @Test public void testTunnelV6InV4() throws Exception { checkTunnelOutput(AF_INET6, AF_INET, false, false); checkTunnelInput(AF_INET6, AF_INET, false, false); } + @Test + public void testTunnelV6InV4Reflected() throws Exception { + checkTunnelReflected(AF_INET6, AF_INET, false, false); + } + @Test public void testTunnelV6InV4UdpEncap() throws Exception { checkTunnelOutput(AF_INET6, AF_INET, true, false); checkTunnelInput(AF_INET6, AF_INET, true, false); } + @Test + public void testTunnelV6InV4UdpEncapReflected() throws Exception { + checkTunnelReflected(AF_INET6, AF_INET, true, false); + } + @Test public void testTunnelV6InV6() throws Exception { checkTunnelOutput(AF_INET6, AF_INET6, false, false); checkTunnelInput(AF_INET6, AF_INET6, false, false); } + + @Test + public void testTunnelV6InV6Reflected() throws Exception { + checkTunnelReflected(AF_INET6, AF_INET6, false, false); + } } From d8a36dd745f358a242b4a494c1c8a1e7725af47a Mon Sep 17 00:00:00 2001 From: Benedict Wong Date: Mon, 20 May 2019 11:58:26 -0700 Subject: [PATCH 0646/1109] Remove mContext from IpSecBaseTest This commit removes the mContext from IpSecBaseTest, and replaces it with InstrumentationRegistry.getContext(). Bug: 72950854 Test: Ran on devices, passing. Merged-In: If6fa359825aa9d1f7d4c8d49aba7a34925c073ed Change-Id: If6fa359825aa9d1f7d4c8d49aba7a34925c073ed (cherry picked from commit 69760fb5b62ae0e36c2a88bb20502dead3d7589b) --- tests/cts/net/src/android/net/cts/IpSecBaseTest.java | 4 +--- tests/cts/net/src/android/net/cts/IpSecManagerTest.java | 8 +++++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java index 26049cc174..10e43e7b6a 100644 --- a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java @@ -76,11 +76,9 @@ public class IpSecBaseTest { protected ConnectivityManager mCM; protected IpSecManager mISM; - protected Context mContext; @Before public void setUp() throws Exception { - mContext = InstrumentationRegistry.getContext(); mISM = (IpSecManager) InstrumentationRegistry.getContext() @@ -475,7 +473,7 @@ public class IpSecBaseTest { private IpSecTransform buildDefaultTransform(InetAddress localAddr) throws Exception { try (IpSecManager.SecurityParameterIndex spi = mISM.allocateSecurityParameterIndex(localAddr)) { - return buildIpSecTransform(mContext, spi, null, localAddr); + return buildIpSecTransform(InstrumentationRegistry.getContext(), spi, null, localAddr); } } diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java index d6b8a968d2..355b496829 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java @@ -41,6 +41,7 @@ import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; +import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import java.io.FileDescriptor; @@ -238,7 +239,7 @@ public class IpSecManagerTest extends IpSecBaseTest { mISM.allocateSecurityParameterIndex(localAddr); IpSecTransform transform = - new IpSecTransform.Builder(mContext) + new IpSecTransform.Builder(InstrumentationRegistry.getContext()) .setEncryption(new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY)) .setAuthentication( new IpSecAlgorithm( @@ -456,7 +457,8 @@ public class IpSecManagerTest extends IpSecBaseTest { IpSecManager.SecurityParameterIndex spi = mISM.allocateSecurityParameterIndex(local)) { - IpSecTransform.Builder transformBuilder = new IpSecTransform.Builder(mContext); + IpSecTransform.Builder transformBuilder = + new IpSecTransform.Builder(InstrumentationRegistry.getContext()); if (crypt != null) { transformBuilder.setEncryption(crypt); } @@ -617,7 +619,7 @@ public class IpSecManagerTest extends IpSecBaseTest { try (IpSecManager.SecurityParameterIndex spi = mISM.allocateSecurityParameterIndex(local); IpSecTransform transform = - new IpSecTransform.Builder(mContext) + new IpSecTransform.Builder(InstrumentationRegistry.getContext()) .setEncryption(crypt) .setAuthentication(auth) .setIpv4Encapsulation(encapSocket, encapSocket.getPort()) From 66fe5244ad2916c4ec9c7eda977df234fb88d572 Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Fri, 31 May 2019 15:13:31 -0700 Subject: [PATCH 0647/1109] Fix testNetworkSettingsPermission for headless User 0 This test fails on devices with headless user 0 when it tries to verify apps with android:sharedUserId="android.uid.system" (and without explicit ask for NETWORK_SETTINGS). Such apps get this permission by default, but when running on user 1 they get UID 1001000, what doesn't match SYSTEM_UID=1000. By the chance of modifying this code, let's also add more verbose error message (with UID), simplify it and reduce indentation count. Bug: 120143468 Test: atest android.net.wifi.cts.WifiManagerTest#testNetworkSettingsPermission Change-Id: Ifc09320cf738a518003126fad1ce31f5e38a3aff --- tests/cts/net/AndroidManifest.xml | 1 + .../android/net/wifi/cts/WifiManagerTest.java | 30 +++++++++---------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index 44a00ef619..c2b3bf77ad 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -27,6 +27,7 @@ + diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 75764508c8..fbf1abd3b8 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -36,6 +36,7 @@ import android.net.wifi.hotspot2.pps.Credential; import android.net.wifi.hotspot2.pps.HomeSp; import android.os.Process; import android.os.SystemClock; +import android.os.UserHandle; import android.platform.test.annotations.AppModeFull; import android.provider.Settings; import android.support.test.uiautomator.UiDevice; @@ -770,21 +771,20 @@ public class WifiManagerTest extends AndroidTestCase { }, PackageManager.MATCH_UNINSTALLED_PACKAGES); for (PackageInfo pi : holding) { String packageName = pi.packageName; - if (allowedPackages.contains(packageName)) { - // this is an explicitly allowed package - } else { - // now check if the packages are from allowed UIDs - boolean allowed = false; - try { - if (allowedUIDs.contains(pm.getPackageUid(packageName, 0))) { - allowed = true; - Log.d(TAG, packageName + " is on an allowed UID"); - } - } catch (PackageManager.NameNotFoundException e) { } - if (!allowed) { - fail("The NETWORK_SETTINGS permission must not be held by " - + packageName + " and must be revoked for security reasons"); - } + + // this is an explicitly allowed package + if (allowedPackages.contains(packageName)) continue; + + // now check if the packages are from allowed UIDs + int uid = -1; + try { + uid = pm.getPackageUidAsUser(packageName, UserHandle.USER_SYSTEM); + } catch (PackageManager.NameNotFoundException e) { + continue; + } + if (!allowedUIDs.contains(uid)) { + fail("The NETWORK_SETTINGS permission must not be held by " + packageName + + ":" + uid + " and must be revoked for security reasons"); } } } From 802549c8de99517e1fa4a174abbf7c06078526dc Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Wed, 5 Jun 2019 18:27:40 -0700 Subject: [PATCH 0648/1109] Skip battery saver related tests on unsupported devices. Bug: 133761301 Test: atest com.android.cts.net.HostsideRestrictBackgroundNetworkTests Change-Id: Ifec84425febf38d732367fae6b43fa80c427c79f --- .../net/hostside/AbstractAppIdleTestCase.java | 5 ++++ .../AbstractBatterySaverModeTestCase.java | 18 +++++++++---- ...ractRestrictBackgroundNetworkTestCase.java | 8 ++++++ .../cts/net/hostside/MixedModesTest.java | 25 +++++++++++++++++++ 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java index 7bf7bd44f4..55bd406c64 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java @@ -150,6 +150,11 @@ abstract class AbstractAppIdleTestCase extends AbstractRestrictBackgroundNetwork } public void testAppIdleNetworkAccess_whenCharging() throws Exception { + if (!isBatterySaverSupported()) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Battery saver mode"); + return; + } if (!isSupported()) return; // Check that app is paroled when charging diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java index 28175b8784..931376b9fe 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java @@ -16,6 +16,7 @@ package com.android.cts.net.hostside; +import android.text.TextUtils; import android.util.Log; /** @@ -52,12 +53,19 @@ abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgrou @Override protected boolean isSupported() throws Exception { - boolean supported = isDozeModeEnabled(); - if (!supported) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Doze Mode"); + String unSupported = ""; + if (!isDozeModeEnabled()) { + unSupported += "Doze mode,"; } - return supported; + if (!isBatterySaverSupported()) { + unSupported += "Battery saver mode,"; + } + if (!TextUtils.isEmpty(unSupported)) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support " + unSupported); + return false; + } + return true; } /** diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 6dfa2f3aef..40d7e34fcc 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -34,6 +34,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.PackageManager; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; @@ -43,12 +44,15 @@ import android.os.BatteryManager; import android.os.Binder; import android.os.Bundle; import android.os.SystemClock; +import android.os.SystemProperties; import android.provider.Settings; import android.service.notification.NotificationListenerService; import android.test.InstrumentationTestCase; import android.text.TextUtils; import android.util.Log; +import com.android.compatibility.common.util.BatteryUtils; + import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; @@ -311,6 +315,10 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation return mSupported; } + protected boolean isBatterySaverSupported() { + return BatteryUtils.isBatterySaverSupported(); + } + /** * Asserts that an app always have access while on foreground or running a foreground service. * diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java index 74875cd2c9..b1a21867b3 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java @@ -71,6 +71,11 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { * Tests all DS ON and BS ON scenarios from network-policy-restrictions.md on metered networks. */ public void testDataAndBatterySaverModes_meteredNetwork() throws Exception { + if (!isBatterySaverSupported()) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Battery saver mode"); + return; + } if (!isSupported()) return; Log.i(TAG, "testDataAndBatterySaverModes_meteredNetwork() tests"); @@ -141,6 +146,11 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { * networks. */ public void testDataAndBatterySaverModes_nonMeteredNetwork() throws Exception { + if (!isBatterySaverSupported()) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Battery saver mode"); + return; + } if (!isSupported()) return; if (!setUnmeteredNetwork()) { @@ -206,6 +216,11 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { * are enabled. */ public void testDozeAndBatterySaverMode_powerSaveWhitelists() throws Exception { + if (!isBatterySaverSupported()) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Battery saver mode"); + return; + } if (!isSupported()) { return; } @@ -285,6 +300,11 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } public void testAppIdleAndBatterySaver_tempPowerSaveWhitelists() throws Exception { + if (!isBatterySaverSupported()) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Battery saver mode"); + return; + } if (!isSupported()) { return; } @@ -361,6 +381,11 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } public void testAppIdleAndBatterySaver_tempPowerSaveAndAppIdleWhitelists() throws Exception { + if (!isBatterySaverSupported()) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Battery saver mode"); + return; + } if (!isSupported()) { return; } From 8371c77499889e22437eafeece7ac022069e5d64 Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Wed, 5 Jun 2019 18:27:40 -0700 Subject: [PATCH 0649/1109] Skip battery saver related tests on unsupported devices. Bug: 133761301 Test: atest com.android.cts.net.HostsideRestrictBackgroundNetworkTests Change-Id: Ifec84425febf38d732367fae6b43fa80c427c79f Merged-In: Ifec84425febf38d732367fae6b43fa80c427c79f --- .../net/hostside/AbstractAppIdleTestCase.java | 5 +++++ .../AbstractBatterySaverModeTestCase.java | 18 ++++++++++++----- ...ractRestrictBackgroundNetworkTestCase.java | 7 +++++++ .../cts/net/hostside/MixedModesTest.java | 20 +++++++++++++++++++ 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java index 0e141c05ad..1f5984a704 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java @@ -150,6 +150,11 @@ abstract class AbstractAppIdleTestCase extends AbstractRestrictBackgroundNetwork } public void testAppIdleNetworkAccess_whenCharging() throws Exception { + if (!isBatterySaverSupported()) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Battery saver mode"); + return; + } if (!isSupported()) return; // Check that app is paroled when charging diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java index 28175b8784..931376b9fe 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java @@ -16,6 +16,7 @@ package com.android.cts.net.hostside; +import android.text.TextUtils; import android.util.Log; /** @@ -52,12 +53,19 @@ abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgrou @Override protected boolean isSupported() throws Exception { - boolean supported = isDozeModeEnabled(); - if (!supported) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Doze Mode"); + String unSupported = ""; + if (!isDozeModeEnabled()) { + unSupported += "Doze mode,"; } - return supported; + if (!isBatterySaverSupported()) { + unSupported += "Battery saver mode,"; + } + if (!TextUtils.isEmpty(unSupported)) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support " + unSupported); + return false; + } + return true; } /** diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 5232372047..1844878f64 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -38,6 +38,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.PackageManager; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; @@ -53,6 +54,8 @@ import android.test.InstrumentationTestCase; import android.text.TextUtils; import android.util.Log; +import com.android.compatibility.common.util.BatteryUtils; + /** * Superclass for tests related to background network restrictions. */ @@ -301,6 +304,10 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation return mSupported; } + protected boolean isBatterySaverSupported() throws Exception { + return BatteryUtils.isBatterySaverSupported(); + } + /** * Asserts that an app always have access while on foreground or running a foreground service. * diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java index 87f9d7738d..7f65b55b48 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java @@ -71,6 +71,11 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { * Tests all DS ON and BS ON scenarios from network-policy-restrictions.md on metered networks. */ public void testDataAndBatterySaverModes_meteredNetwork() throws Exception { + if (!isBatterySaverSupported()) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Battery saver mode"); + return; + } if (!isSupported()) return; Log.i(TAG, "testDataAndBatterySaverModes_meteredNetwork() tests"); @@ -141,6 +146,11 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { * networks. */ public void testDataAndBatterySaverModes_nonMeteredNetwork() throws Exception { + if (!isBatterySaverSupported()) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Battery saver mode"); + return; + } if (!isSupported()) return; if (!setUnmeteredNetwork()) { @@ -206,6 +216,11 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { * are enabled. */ public void testDozeAndBatterySaverMode_powerSaveWhitelists() throws Exception { + if (!isBatterySaverSupported()) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Battery saver mode"); + return; + } if (!isSupported()) { return; } @@ -285,6 +300,11 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } public void testAppIdleAndBatterySaver_tempPowerSaveWhitelists() throws Exception { + if (!isBatterySaverSupported()) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Battery saver mode"); + return; + } if (!isSupported()) { return; } From 8eeaa698c67596486d9635ac15aa0286ede3c153 Mon Sep 17 00:00:00 2001 From: Pete Bentley Date: Fri, 7 Jun 2019 18:41:48 +0100 Subject: [PATCH 0650/1109] Update test host used for TLS host verification. Temporary fix, this is still brittle to certificate changes on the test host. Bug: 134532880 Test: atest android.net.cts.SSLCertificateSocketFactoryTest Change-Id: I6e8c8757963ef46009767925bfa512127d9daba7 --- .../src/android/net/cts/SSLCertificateSocketFactoryTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java index 525045057b..01ac3fda08 100644 --- a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java +++ b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java @@ -92,7 +92,7 @@ public class SSLCertificateSocketFactoryTest extends AndroidTestCase { // a host and port that are expected to be available but have // a cert with a different CN, in this case CN=mail.google.com - private static String TEST_CREATE_SOCKET_HOST = "googlemail.com"; + private static String TEST_CREATE_SOCKET_HOST = "www3.l.google.com"; private static int TEST_CREATE_SOCKET_PORT = 443; /** From 50795d03cddf9ad6f8e3c7f5926b82c60ffe21d6 Mon Sep 17 00:00:00 2001 From: Pete Bentley Date: Fri, 7 Jun 2019 18:41:48 +0100 Subject: [PATCH 0651/1109] Update test host used for TLS host verification. Temporary fix, this is still brittle to certificate changes on the test host. Bug: 134532880 Test: atest android.net.cts.SSLCertificateSocketFactoryTest Change-Id: I6e8c8757963ef46009767925bfa512127d9daba7 Merged-In: I6e8c8757963ef46009767925bfa512127d9daba7 (cherry picked from commit 166e7121b173f2a4e3d6a9ded213e4c8679a9cfb) --- .../src/android/net/cts/SSLCertificateSocketFactoryTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java index 525045057b..01ac3fda08 100644 --- a/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java +++ b/tests/cts/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java @@ -92,7 +92,7 @@ public class SSLCertificateSocketFactoryTest extends AndroidTestCase { // a host and port that are expected to be available but have // a cert with a different CN, in this case CN=mail.google.com - private static String TEST_CREATE_SOCKET_HOST = "googlemail.com"; + private static String TEST_CREATE_SOCKET_HOST = "www3.l.google.com"; private static int TEST_CREATE_SOCKET_PORT = 443; /** From c80f04858ebffafd330448e4fead4b4ed340a603 Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Mon, 10 Jun 2019 14:16:41 +0800 Subject: [PATCH 0652/1109] Fix DnsResolverTest for instant mode add AppModeFull@ to DnsResolverTest since WRITE_SECURE_SETTINGS could not be ganted in instant mode. Bug: 134897744 Test: atest DnsResolverTest atest DnsResolverTest --instant Change-Id: I267c19af1a1c5544ca752a364335ec728a478bb2 --- tests/cts/net/src/android/net/cts/DnsResolverTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/DnsResolverTest.java b/tests/cts/net/src/android/net/cts/DnsResolverTest.java index e16fce09bf..1ff2090bc5 100644 --- a/tests/cts/net/src/android/net/cts/DnsResolverTest.java +++ b/tests/cts/net/src/android/net/cts/DnsResolverTest.java @@ -39,6 +39,7 @@ import android.net.ParseException; import android.os.CancellationSignal; import android.os.Handler; import android.os.Looper; +import android.platform.test.annotations.AppModeFull; import android.provider.Settings; import android.system.ErrnoException; import android.test.AndroidTestCase; @@ -53,6 +54,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; +@AppModeFull(reason = "WRITE_SECURE_SETTINGS permission can't be granted to instant apps") public class DnsResolverTest extends AndroidTestCase { private static final String TAG = "DnsResolverTest"; private static final char[] HEX_CHARS = { From 1053db1f82c989540704a2020971a7fefad5bda3 Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Tue, 11 Jun 2019 15:49:08 +0800 Subject: [PATCH 0653/1109] Add test with inline executor for DnsResolverTest Makes general query test cases also take inline executor. The new added test case testSequentialQuery with inline executor will only pass after aosp/980686. Bug: 134310704 Test: atest DnsResolverTest atest DnsResolverTest --instant Change-Id: I135358fe45652277ed795a2f359f44f4db787c08 --- .../src/android/net/cts/DnsResolverTest.java | 115 +++++++++++++++--- 1 file changed, 101 insertions(+), 14 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/DnsResolverTest.java b/tests/cts/net/src/android/net/cts/DnsResolverTest.java index 1ff2090bc5..ef8badd32a 100644 --- a/tests/cts/net/src/android/net/cts/DnsResolverTest.java +++ b/tests/cts/net/src/android/net/cts/DnsResolverTest.java @@ -80,12 +80,14 @@ public class DnsResolverTest extends AndroidTestCase { static final int TIMEOUT_MS = 12_000; static final int CANCEL_TIMEOUT_MS = 3_000; 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 = 2_000; private ContentResolver mCR; private ConnectivityManager mCM; private Executor mExecutor; + private Executor mExecutorInline; private DnsResolver mDns; private String mOldMode; @@ -97,6 +99,7 @@ public class DnsResolverTest extends AndroidTestCase { mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); mDns = DnsResolver.getInstance(); mExecutor = new Handler(Looper.getMainLooper())::post; + mExecutorInline = (Runnable r) -> r.run(); mCR = getContext().getContentResolver(); storePrivateDnsSetting(); } @@ -274,12 +277,44 @@ public class DnsResolverTest extends AndroidTestCase { } } - public void testRawQuery() throws InterruptedException { + public void testRawQuery() throws Exception { + doTestRawQuery(mExecutor); + } + + public void testRawQueryInline() throws Exception { + doTestRawQuery(mExecutorInline); + } + + public void testRawQueryBlob() throws Exception { + doTestRawQueryBlob(mExecutor); + } + + public void testRawQueryBlobInline() throws Exception { + doTestRawQueryBlob(mExecutorInline); + } + + public void testRawQueryRoot() throws Exception { + doTestRawQueryRoot(mExecutor); + } + + public void testRawQueryRootInline() throws Exception { + doTestRawQueryRoot(mExecutorInline); + } + + public void testRawQueryNXDomain() throws Exception { + doTestRawQueryNXDomain(mExecutor); + } + + public void testRawQueryNXDomainInline() throws Exception { + doTestRawQueryNXDomain(mExecutorInline); + } + + public void doTestRawQuery(Executor executor) throws InterruptedException { final String msg = "RawQuery " + TEST_DOMAIN; for (Network network : getTestableNetworks()) { final VerifyCancelCallback callback = new VerifyCancelCallback(msg); mDns.rawQuery(network, TEST_DOMAIN, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, - mExecutor, null, callback); + executor, null, callback); assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", callback.waitForAnswer()); @@ -287,7 +322,7 @@ public class DnsResolverTest extends AndroidTestCase { } } - public void testRawQueryBlob() throws InterruptedException { + public void doTestRawQueryBlob(Executor executor) throws InterruptedException { final byte[] blob = new byte[]{ /* Header */ 0x55, 0x66, /* Transaction ID */ @@ -305,7 +340,7 @@ public class DnsResolverTest extends AndroidTestCase { final String msg = "RawQuery blob " + byteArrayToHexString(blob); for (Network network : getTestableNetworks()) { final VerifyCancelCallback callback = new VerifyCancelCallback(msg); - mDns.rawQuery(network, blob, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); + mDns.rawQuery(network, blob, FLAG_NO_CACHE_LOOKUP, executor, null, callback); assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", callback.waitForAnswer()); @@ -313,13 +348,13 @@ public class DnsResolverTest extends AndroidTestCase { } } - public void testRawQueryRoot() throws InterruptedException { + public void doTestRawQueryRoot(Executor executor) throws InterruptedException { final String dname = ""; final String msg = "RawQuery empty dname(ROOT) "; for (Network network : getTestableNetworks()) { final VerifyCancelCallback callback = new VerifyCancelCallback(msg); mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, - mExecutor, null, callback); + executor, null, callback); assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", callback.waitForAnswer()); @@ -328,13 +363,13 @@ public class DnsResolverTest extends AndroidTestCase { } } - public void testRawQueryNXDomain() throws InterruptedException { + public void doTestRawQueryNXDomain(Executor executor) throws InterruptedException { final String dname = "test1-nx.metric.gstatic.com"; final String msg = "RawQuery " + dname; for (Network network : getTestableNetworks()) { final VerifyCancelCallback callback = new VerifyCancelCallback(msg); mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, - mExecutor, null, callback); + executor, null, callback); assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", callback.waitForAnswer()); @@ -476,12 +511,44 @@ public class DnsResolverTest extends AndroidTestCase { } } - public void testQueryForInetAddress() throws InterruptedException { + public void testQueryForInetAddress() throws Exception { + doTestQueryForInetAddress(mExecutor); + } + + public void testQueryForInetAddressInline() throws Exception { + doTestQueryForInetAddress(mExecutorInline); + } + + public void testQueryForInetAddressIpv4() throws Exception { + doTestQueryForInetAddressIpv4(mExecutor); + } + + public void testQueryForInetAddressIpv4Inline() throws Exception { + doTestQueryForInetAddressIpv4(mExecutorInline); + } + + public void testQueryForInetAddressIpv6() throws Exception { + doTestQueryForInetAddressIpv6(mExecutor); + } + + public void testQueryForInetAddressIpv6Inline() throws Exception { + doTestQueryForInetAddressIpv6(mExecutorInline); + } + + public void testContinuousQueries() throws Exception { + doTestContinuousQueries(mExecutor); + } + + public void testContinuousQueriesInline() throws Exception { + doTestContinuousQueries(mExecutorInline); + } + + public void doTestQueryForInetAddress(Executor executor) throws InterruptedException { final String msg = "Test query for InetAddress " + TEST_DOMAIN; for (Network network : getTestableNetworks()) { final VerifyCancelInetAddressCallback callback = new VerifyCancelInetAddressCallback(msg, null); - mDns.query(network, TEST_DOMAIN, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); + mDns.query(network, TEST_DOMAIN, FLAG_NO_CACHE_LOOKUP, executor, null, callback); assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", callback.waitForAnswer()); @@ -518,13 +585,13 @@ public class DnsResolverTest extends AndroidTestCase { } } - public void testQueryForInetAddressIpv4() throws InterruptedException { + public void doTestQueryForInetAddressIpv4(Executor executor) throws InterruptedException { final String msg = "Test query for IPv4 InetAddress " + TEST_DOMAIN; for (Network network : getTestableNetworks()) { final VerifyCancelInetAddressCallback callback = new VerifyCancelInetAddressCallback(msg, null); mDns.query(network, TEST_DOMAIN, TYPE_A, FLAG_NO_CACHE_LOOKUP, - mExecutor, null, callback); + executor, null, callback); assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", callback.waitForAnswer()); @@ -533,13 +600,13 @@ public class DnsResolverTest extends AndroidTestCase { } } - public void testQueryForInetAddressIpv6() throws InterruptedException { + public void doTestQueryForInetAddressIpv6(Executor executor) throws InterruptedException { final String msg = "Test query for IPv6 InetAddress " + TEST_DOMAIN; for (Network network : getTestableNetworks()) { final VerifyCancelInetAddressCallback callback = new VerifyCancelInetAddressCallback(msg, null); mDns.query(network, TEST_DOMAIN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, - mExecutor, null, callback); + executor, null, callback); assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", callback.waitForAnswer()); @@ -632,4 +699,24 @@ public class DnsResolverTest extends AndroidTestCase { mCM.bindProcessToNetwork(null); } } + + public void doTestContinuousQueries(Executor executor) throws InterruptedException { + final String msg = "Test continuous " + QUERY_TIMES + " queries " + TEST_DOMAIN; + for (Network network : getTestableNetworks()) { + for (int i = 0; i < QUERY_TIMES ; ++i) { + final VerifyCancelInetAddressCallback callback = + new VerifyCancelInetAddressCallback(msg, null); + // query v6/v4 in turn + boolean queryV6 = (i % 2 == 0); + mDns.query(network, TEST_DOMAIN, queryV6 ? TYPE_AAAA : TYPE_A, + FLAG_NO_CACHE_LOOKUP, executor, null, callback); + + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + callback.waitForAnswer()); + assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty()); + assertTrue(msg + " returned " + (queryV6 ? "Ipv4" : "Ipv6") + " results", + queryV6 ? !callback.hasIpv4Answer() : !callback.hasIpv6Answer()); + } + } + } } From d3b7dec47352efcd4342bbc1adf82687bb442efe Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Mon, 10 Jun 2019 14:16:41 +0800 Subject: [PATCH 0654/1109] Fix DnsResolverTest for instant mode add AppModeFull@ to DnsResolverTest since WRITE_SECURE_SETTINGS could not be ganted in instant mode. Bug: 134897744 Test: atest DnsResolverTest atest DnsResolverTest --instant Change-Id: I267c19af1a1c5544ca752a364335ec728a478bb2 (cherry picked from commit 2af244f4127883ed967089f550f2cfe07936416d) --- tests/cts/net/src/android/net/cts/DnsResolverTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/DnsResolverTest.java b/tests/cts/net/src/android/net/cts/DnsResolverTest.java index e16fce09bf..1ff2090bc5 100644 --- a/tests/cts/net/src/android/net/cts/DnsResolverTest.java +++ b/tests/cts/net/src/android/net/cts/DnsResolverTest.java @@ -39,6 +39,7 @@ import android.net.ParseException; import android.os.CancellationSignal; import android.os.Handler; import android.os.Looper; +import android.platform.test.annotations.AppModeFull; import android.provider.Settings; import android.system.ErrnoException; import android.test.AndroidTestCase; @@ -53,6 +54,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; +@AppModeFull(reason = "WRITE_SECURE_SETTINGS permission can't be granted to instant apps") public class DnsResolverTest extends AndroidTestCase { private static final String TAG = "DnsResolverTest"; private static final char[] HEX_CHARS = { From 5e43421294d03f6ae69527ee4de9c05dd0a8c877 Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Tue, 11 Jun 2019 15:49:08 +0800 Subject: [PATCH 0655/1109] Add test with inline executor for DnsResolverTest Makes general query test cases also take inline executor. The new added test case testSequentialQuery with inline executor will only pass after aosp/980686. Bug: 134310704 Test: atest DnsResolverTest atest DnsResolverTest --instant Change-Id: I135358fe45652277ed795a2f359f44f4db787c08 (cherry picked from commit 04596294eea3e5db4fd487cf6f8ef598daac606a) --- .../src/android/net/cts/DnsResolverTest.java | 115 +++++++++++++++--- 1 file changed, 101 insertions(+), 14 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/DnsResolverTest.java b/tests/cts/net/src/android/net/cts/DnsResolverTest.java index 1ff2090bc5..ef8badd32a 100644 --- a/tests/cts/net/src/android/net/cts/DnsResolverTest.java +++ b/tests/cts/net/src/android/net/cts/DnsResolverTest.java @@ -80,12 +80,14 @@ public class DnsResolverTest extends AndroidTestCase { static final int TIMEOUT_MS = 12_000; static final int CANCEL_TIMEOUT_MS = 3_000; 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 = 2_000; private ContentResolver mCR; private ConnectivityManager mCM; private Executor mExecutor; + private Executor mExecutorInline; private DnsResolver mDns; private String mOldMode; @@ -97,6 +99,7 @@ public class DnsResolverTest extends AndroidTestCase { mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); mDns = DnsResolver.getInstance(); mExecutor = new Handler(Looper.getMainLooper())::post; + mExecutorInline = (Runnable r) -> r.run(); mCR = getContext().getContentResolver(); storePrivateDnsSetting(); } @@ -274,12 +277,44 @@ public class DnsResolverTest extends AndroidTestCase { } } - public void testRawQuery() throws InterruptedException { + public void testRawQuery() throws Exception { + doTestRawQuery(mExecutor); + } + + public void testRawQueryInline() throws Exception { + doTestRawQuery(mExecutorInline); + } + + public void testRawQueryBlob() throws Exception { + doTestRawQueryBlob(mExecutor); + } + + public void testRawQueryBlobInline() throws Exception { + doTestRawQueryBlob(mExecutorInline); + } + + public void testRawQueryRoot() throws Exception { + doTestRawQueryRoot(mExecutor); + } + + public void testRawQueryRootInline() throws Exception { + doTestRawQueryRoot(mExecutorInline); + } + + public void testRawQueryNXDomain() throws Exception { + doTestRawQueryNXDomain(mExecutor); + } + + public void testRawQueryNXDomainInline() throws Exception { + doTestRawQueryNXDomain(mExecutorInline); + } + + public void doTestRawQuery(Executor executor) throws InterruptedException { final String msg = "RawQuery " + TEST_DOMAIN; for (Network network : getTestableNetworks()) { final VerifyCancelCallback callback = new VerifyCancelCallback(msg); mDns.rawQuery(network, TEST_DOMAIN, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, - mExecutor, null, callback); + executor, null, callback); assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", callback.waitForAnswer()); @@ -287,7 +322,7 @@ public class DnsResolverTest extends AndroidTestCase { } } - public void testRawQueryBlob() throws InterruptedException { + public void doTestRawQueryBlob(Executor executor) throws InterruptedException { final byte[] blob = new byte[]{ /* Header */ 0x55, 0x66, /* Transaction ID */ @@ -305,7 +340,7 @@ public class DnsResolverTest extends AndroidTestCase { final String msg = "RawQuery blob " + byteArrayToHexString(blob); for (Network network : getTestableNetworks()) { final VerifyCancelCallback callback = new VerifyCancelCallback(msg); - mDns.rawQuery(network, blob, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); + mDns.rawQuery(network, blob, FLAG_NO_CACHE_LOOKUP, executor, null, callback); assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", callback.waitForAnswer()); @@ -313,13 +348,13 @@ public class DnsResolverTest extends AndroidTestCase { } } - public void testRawQueryRoot() throws InterruptedException { + public void doTestRawQueryRoot(Executor executor) throws InterruptedException { final String dname = ""; final String msg = "RawQuery empty dname(ROOT) "; for (Network network : getTestableNetworks()) { final VerifyCancelCallback callback = new VerifyCancelCallback(msg); mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, - mExecutor, null, callback); + executor, null, callback); assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", callback.waitForAnswer()); @@ -328,13 +363,13 @@ public class DnsResolverTest extends AndroidTestCase { } } - public void testRawQueryNXDomain() throws InterruptedException { + public void doTestRawQueryNXDomain(Executor executor) throws InterruptedException { final String dname = "test1-nx.metric.gstatic.com"; final String msg = "RawQuery " + dname; for (Network network : getTestableNetworks()) { final VerifyCancelCallback callback = new VerifyCancelCallback(msg); mDns.rawQuery(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, - mExecutor, null, callback); + executor, null, callback); assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", callback.waitForAnswer()); @@ -476,12 +511,44 @@ public class DnsResolverTest extends AndroidTestCase { } } - public void testQueryForInetAddress() throws InterruptedException { + public void testQueryForInetAddress() throws Exception { + doTestQueryForInetAddress(mExecutor); + } + + public void testQueryForInetAddressInline() throws Exception { + doTestQueryForInetAddress(mExecutorInline); + } + + public void testQueryForInetAddressIpv4() throws Exception { + doTestQueryForInetAddressIpv4(mExecutor); + } + + public void testQueryForInetAddressIpv4Inline() throws Exception { + doTestQueryForInetAddressIpv4(mExecutorInline); + } + + public void testQueryForInetAddressIpv6() throws Exception { + doTestQueryForInetAddressIpv6(mExecutor); + } + + public void testQueryForInetAddressIpv6Inline() throws Exception { + doTestQueryForInetAddressIpv6(mExecutorInline); + } + + public void testContinuousQueries() throws Exception { + doTestContinuousQueries(mExecutor); + } + + public void testContinuousQueriesInline() throws Exception { + doTestContinuousQueries(mExecutorInline); + } + + public void doTestQueryForInetAddress(Executor executor) throws InterruptedException { final String msg = "Test query for InetAddress " + TEST_DOMAIN; for (Network network : getTestableNetworks()) { final VerifyCancelInetAddressCallback callback = new VerifyCancelInetAddressCallback(msg, null); - mDns.query(network, TEST_DOMAIN, FLAG_NO_CACHE_LOOKUP, mExecutor, null, callback); + mDns.query(network, TEST_DOMAIN, FLAG_NO_CACHE_LOOKUP, executor, null, callback); assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", callback.waitForAnswer()); @@ -518,13 +585,13 @@ public class DnsResolverTest extends AndroidTestCase { } } - public void testQueryForInetAddressIpv4() throws InterruptedException { + public void doTestQueryForInetAddressIpv4(Executor executor) throws InterruptedException { final String msg = "Test query for IPv4 InetAddress " + TEST_DOMAIN; for (Network network : getTestableNetworks()) { final VerifyCancelInetAddressCallback callback = new VerifyCancelInetAddressCallback(msg, null); mDns.query(network, TEST_DOMAIN, TYPE_A, FLAG_NO_CACHE_LOOKUP, - mExecutor, null, callback); + executor, null, callback); assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", callback.waitForAnswer()); @@ -533,13 +600,13 @@ public class DnsResolverTest extends AndroidTestCase { } } - public void testQueryForInetAddressIpv6() throws InterruptedException { + public void doTestQueryForInetAddressIpv6(Executor executor) throws InterruptedException { final String msg = "Test query for IPv6 InetAddress " + TEST_DOMAIN; for (Network network : getTestableNetworks()) { final VerifyCancelInetAddressCallback callback = new VerifyCancelInetAddressCallback(msg, null); mDns.query(network, TEST_DOMAIN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, - mExecutor, null, callback); + executor, null, callback); assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", callback.waitForAnswer()); @@ -632,4 +699,24 @@ public class DnsResolverTest extends AndroidTestCase { mCM.bindProcessToNetwork(null); } } + + public void doTestContinuousQueries(Executor executor) throws InterruptedException { + final String msg = "Test continuous " + QUERY_TIMES + " queries " + TEST_DOMAIN; + for (Network network : getTestableNetworks()) { + for (int i = 0; i < QUERY_TIMES ; ++i) { + final VerifyCancelInetAddressCallback callback = + new VerifyCancelInetAddressCallback(msg, null); + // query v6/v4 in turn + boolean queryV6 = (i % 2 == 0); + mDns.query(network, TEST_DOMAIN, queryV6 ? TYPE_AAAA : TYPE_A, + FLAG_NO_CACHE_LOOKUP, executor, null, callback); + + assertTrue(msg + " but no answer after " + TIMEOUT_MS + "ms.", + callback.waitForAnswer()); + assertTrue(msg + " returned 0 results", !callback.isAnswerEmpty()); + assertTrue(msg + " returned " + (queryV6 ? "Ipv4" : "Ipv6") + " results", + queryV6 ? !callback.hasIpv4Answer() : !callback.hasIpv6Answer()); + } + } + } } From 487b0401c0e3cb9bd27a5d26a0bffbc4dc06aec8 Mon Sep 17 00:00:00 2001 From: junyulai Date: Mon, 3 Jun 2019 10:26:08 +0800 Subject: [PATCH 0656/1109] Add CTS for creating keepalive offloads on cellular Bug: 134352656 Test: atest android.net.cts.ConnectivityManagerTest (--instant) Change-Id: Ia7b1111abe687efad032a8c9205990c97a769fcd --- .../net/cts/ConnectivityManagerTest.java | 245 ++++++++++++------ 1 file changed, 168 insertions(+), 77 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 8c9bf6ee21..e9deec9f1e 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -35,6 +35,7 @@ import static android.system.OsConstants.AF_UNSPEC; import static com.android.compatibility.common.util.SystemUtil.runShellCommand; +import android.annotation.NonNull; import android.app.Instrumentation; import android.app.PendingIntent; import android.app.UiAutomation; @@ -59,6 +60,7 @@ import android.net.SocketKeepalive; import android.net.cts.util.CtsNetUtils; import android.net.util.KeepaliveUtils; import android.net.wifi.WifiManager; +import android.os.Build; import android.os.Looper; import android.os.MessageQueue; import android.os.SystemClock; @@ -99,6 +101,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -113,6 +116,8 @@ public class ConnectivityManagerTest extends AndroidTestCase { private static final int CONNECT_TIMEOUT_MS = 2000; private static final int KEEPALIVE_CALLBACK_TIMEOUT_MS = 2000; private static final int KEEPALIVE_SOCKET_TIMEOUT_MS = 5000; + private static final int INTERVAL_KEEPALIVE_RETRY_MS = 500; + private static final int MAX_KEEPALIVE_RETRY_COUNT = 3; private static final int MIN_KEEPALIVE_INTERVAL = 10; private static final int NETWORK_CHANGE_METEREDNESS_TIMEOUT = 5000; private static final int NUM_TRIES_MULTIPATH_PREF_CHECK = 20; @@ -120,6 +125,10 @@ public class ConnectivityManagerTest extends AndroidTestCase { // device could have only one interface: data, wifi. private static final int MIN_NUM_NETWORK_TYPES = 1; + // Minimum supported keepalive counts for wifi and cellular. + public static final int MIN_SUPPORTED_CELLULAR_KEEPALIVE_COUNT = 1; + public static final int MIN_SUPPORTED_WIFI_KEEPALIVE_COUNT = 3; + private Context mContext; private Instrumentation mInstrumentation; private ConnectivityManager mCm; @@ -839,8 +848,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { return s; } - private int getSupportedKeepalivesFromRes() throws Exception { - final Network network = ensureWifiConnected(); + private int getSupportedKeepalivesForNet(@NonNull Network network) throws Exception { final NetworkCapabilities nc = mCm.getNetworkCapabilities(network); // Get number of supported concurrent keepalives for testing network. @@ -914,34 +922,46 @@ public class ConnectivityManagerTest extends AndroidTestCase { * keepalives is set to 0. */ @AppModeFull(reason = "Cannot get WifiManager in instant app mode") - public void testKeepaliveUnsupported() throws Exception { - if (getSupportedKeepalivesFromRes() != 0) return; + public void testKeepaliveWifiUnsupported() throws Exception { + if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) { + Log.i(TAG, "testKeepaliveUnsupported cannot execute unless device" + + " supports WiFi"); + return; + } + + final Network network = ensureWifiConnected(); + if (getSupportedKeepalivesForNet(network) != 0) return; adoptShellPermissionIdentity(); - assertEquals(0, createConcurrentSocketKeepalives(1, 0)); - assertEquals(0, createConcurrentSocketKeepalives(0, 1)); + assertEquals(0, createConcurrentSocketKeepalives(network, 1, 0)); + assertEquals(0, createConcurrentSocketKeepalives(network, 0, 1)); dropShellPermissionIdentity(); } @AppModeFull(reason = "Cannot get WifiManager in instant app mode") public void testCreateTcpKeepalive() throws Exception { + if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) { + Log.i(TAG, "testCreateTcpKeepalive cannot execute unless device supports WiFi"); + return; + } + adoptShellPermissionIdentity(); - if (getSupportedKeepalivesFromRes() == 0) return; + final Network network = ensureWifiConnected(); + if (getSupportedKeepalivesForNet(network) == 0) return; // If kernel < 4.8 then it doesn't support TCP keepalive, but it might still support // NAT-T keepalive. If keepalive limits from resource overlay is not zero, TCP keepalive // needs to be supported except if the kernel doesn't support it. if (!isTcpKeepaliveSupportedByKernel()) { // Sanity check to ensure the callback result is expected. - assertEquals(0, createConcurrentSocketKeepalives(0, 1)); + assertEquals(0, createConcurrentSocketKeepalives(network, 0, 1)); Log.i(TAG, "testCreateTcpKeepalive is skipped for kernel " + VintfRuntimeInfo.getKernelVersion()); return; } - final Network network = ensureWifiConnected(); final byte[] requestBytes = CtsNetUtils.HTTP_REQUEST.getBytes("UTF-8"); // So far only ipv4 tcp keepalive offload is supported. // TODO: add test case for ipv6 tcp keepalive offload when it is supported. @@ -1007,80 +1027,102 @@ public class ConnectivityManagerTest extends AndroidTestCase { } } - /** - * Creates concurrent keepalives until the specified counts of each type of keepalives are - * reached or the expected error callbacks are received for each type of keepalives. - * - * @return the total number of keepalives created. - */ - private int createConcurrentSocketKeepalives(int nattCount, int tcpCount) throws Exception { - final Network network = ensureWifiConnected(); - + private ArrayList createConcurrentKeepalivesOfType( + int requestCount, @NonNull TestSocketKeepaliveCallback callback, + Supplier kaFactory) { final ArrayList kalist = new ArrayList<>(); - final TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(); - final Executor executor = mContext.getMainExecutor(); - // Create concurrent TCP keepalives. - for (int i = 0; i < tcpCount; i++) { - // Assert that TCP connections can be established on wifi. The file descriptor of tcp - // sockets will be duplicated and kept valid in service side if the keepalives are - // successfully started. - try (Socket tcpSocket = getConnectedSocket(network, TEST_HOST, HTTP_PORT, - 0 /* Unused */, AF_INET)) { - final SocketKeepalive ka = mCm.createSocketKeepalive(network, tcpSocket, executor, - callback); - ka.start(MIN_KEEPALIVE_INTERVAL); - TestSocketKeepaliveCallback.CallbackValue cv = callback.pollCallback(); - assertNotNull(cv); - if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_ERROR) { - if (i == 0 && cv.error == SocketKeepalive.ERROR_UNSUPPORTED) { - // Unsupported. - break; - } else if (i != 0 && cv.error == SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES) { - // Limit reached. - break; - } - } - if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_STARTED) { - kalist.add(ka); - } else { - fail("Unexpected error when creating " + (i + 1) + " TCP keepalives: " + cv); - } - } - } + int remainingRetries = MAX_KEEPALIVE_RETRY_COUNT; - // Assert that a Nat-T socket can be created. - final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE); - final UdpEncapsulationSocket nattSocket = mIpSec.openUdpEncapsulationSocket(); - - final InetAddress srcAddr = getFirstV4Address(network); - final InetAddress dstAddr = getAddrByName(TEST_HOST, AF_INET); - assertNotNull(srcAddr); - assertNotNull(dstAddr); - - // Test concurrent Nat-T keepalives. - for (int i = 0; i < nattCount; i++) { - final SocketKeepalive ka = mCm.createSocketKeepalive(network, nattSocket, - srcAddr, dstAddr, executor, callback); + // Test concurrent keepalives with the given supplier. + while (kalist.size() < requestCount) { + final SocketKeepalive ka = kaFactory.get(); ka.start(MIN_KEEPALIVE_INTERVAL); TestSocketKeepaliveCallback.CallbackValue cv = callback.pollCallback(); assertNotNull(cv); if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_ERROR) { - if (i == 0 && cv.error == SocketKeepalive.ERROR_UNSUPPORTED) { + if (kalist.size() == 0 && cv.error == SocketKeepalive.ERROR_UNSUPPORTED) { // Unsupported. break; - } else if (i != 0 && cv.error == SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES) { - // Limit reached. + } else if (cv.error == SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES) { + // Limit reached or temporary unavailable due to stopped slot is not yet + // released. + if (remainingRetries > 0) { + SystemClock.sleep(INTERVAL_KEEPALIVE_RETRY_MS); + remainingRetries--; + continue; + } break; } } if (cv.callbackType == TestSocketKeepaliveCallback.CallbackType.ON_STARTED) { kalist.add(ka); } else { - fail("Unexpected error when creating " + (i + 1) + " Nat-T keepalives: " + cv); + fail("Unexpected error when creating " + (kalist.size() + 1) + " " + + ka.getClass().getSimpleName() + ": " + cv); } } + return kalist; + } + + private @NonNull ArrayList createConcurrentNattSocketKeepalives( + @NonNull Network network, int requestCount, + @NonNull TestSocketKeepaliveCallback callback) throws Exception { + + final Executor executor = mContext.getMainExecutor(); + + // Initialize a real NaT-T socket. + final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE); + final UdpEncapsulationSocket nattSocket = mIpSec.openUdpEncapsulationSocket(); + final InetAddress srcAddr = getFirstV4Address(network); + final InetAddress dstAddr = getAddrByName(TEST_HOST, AF_INET); + assertNotNull(srcAddr); + assertNotNull(dstAddr); + + // Test concurrent Nat-T keepalives. + final ArrayList result = createConcurrentKeepalivesOfType(requestCount, + callback, () -> mCm.createSocketKeepalive(network, nattSocket, + srcAddr, dstAddr, executor, callback)); + + nattSocket.close(); + return result; + } + + private @NonNull ArrayList createConcurrentTcpSocketKeepalives( + @NonNull Network network, int requestCount, + @NonNull TestSocketKeepaliveCallback callback) { + final Executor executor = mContext.getMainExecutor(); + + // Create concurrent TCP keepalives. + return createConcurrentKeepalivesOfType(requestCount, callback, () -> { + // Assert that TCP connections can be established. The file descriptor of tcp + // sockets will be duplicated and kept valid in service side if the keepalives are + // successfully started. + try (Socket tcpSocket = getConnectedSocket(network, TEST_HOST, HTTP_PORT, + 0 /* Unused */, AF_INET)) { + return mCm.createSocketKeepalive(network, tcpSocket, executor, callback); + } catch (Exception e) { + fail("Unexpected error when creating TCP socket: " + e); + } + return null; + }); + } + + /** + * Creates concurrent keepalives until the specified counts of each type of keepalives are + * reached or the expected error callbacks are received for each type of keepalives. + * + * @return the total number of keepalives created. + */ + private int createConcurrentSocketKeepalives( + @NonNull Network network, int nattCount, int tcpCount) throws Exception { + final ArrayList kalist = new ArrayList<>(); + final TestSocketKeepaliveCallback callback = new TestSocketKeepaliveCallback(); + + kalist.addAll(createConcurrentNattSocketKeepalives(network, nattCount, callback)); + kalist.addAll(createConcurrentTcpSocketKeepalives(network, tcpCount, callback)); + final int ret = kalist.size(); // Clean up. @@ -1089,7 +1131,6 @@ public class ConnectivityManagerTest extends AndroidTestCase { callback.expectStopped(); } kalist.clear(); - nattSocket.close(); return ret; } @@ -1099,8 +1140,15 @@ public class ConnectivityManagerTest extends AndroidTestCase { * get leaked after iterations. */ @AppModeFull(reason = "Cannot get WifiManager in instant app mode") - public void testSocketKeepaliveLimit() throws Exception { - final int supported = getSupportedKeepalivesFromRes(); + public void testSocketKeepaliveLimitWifi() throws Exception { + if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) { + Log.i(TAG, "testSocketKeepaliveLimitWifi cannot execute unless device" + + " supports WiFi"); + return; + } + + final Network network = ensureWifiConnected(); + final int supported = getSupportedKeepalivesForNet(network); if (supported == 0) { return; } @@ -1108,37 +1156,79 @@ public class ConnectivityManagerTest extends AndroidTestCase { adoptShellPermissionIdentity(); // Verifies that the supported keepalive slots meet MIN_SUPPORTED_KEEPALIVE_COUNT. - assertGreaterOrEqual(supported, KeepaliveUtils.MIN_SUPPORTED_KEEPALIVE_COUNT); + assertGreaterOrEqual(supported, MIN_SUPPORTED_WIFI_KEEPALIVE_COUNT); // Verifies that Nat-T keepalives can be established. - assertEquals(supported, createConcurrentSocketKeepalives(supported + 1, 0)); + assertEquals(supported, createConcurrentSocketKeepalives(network, supported + 1, 0)); // Verifies that keepalives don't get leaked in second round. - assertEquals(supported, createConcurrentSocketKeepalives(supported + 1, 0)); + assertEquals(supported, createConcurrentSocketKeepalives(network, supported, 0)); // If kernel < 4.8 then it doesn't support TCP keepalive, but it might still support // NAT-T keepalive. Test below cases only if TCP keepalive is supported by kernel. if (isTcpKeepaliveSupportedByKernel()) { - assertEquals(supported, createConcurrentSocketKeepalives(0, supported + 1)); + assertEquals(supported, createConcurrentSocketKeepalives(network, 0, supported + 1)); // Verifies that different types can be established at the same time. - assertEquals(supported, createConcurrentSocketKeepalives( + assertEquals(supported, createConcurrentSocketKeepalives(network, supported / 2, supported - supported / 2)); // Verifies that keepalives don't get leaked in second round. - assertEquals(supported, createConcurrentSocketKeepalives(0, supported + 1)); - assertEquals(supported, createConcurrentSocketKeepalives( + assertEquals(supported, createConcurrentSocketKeepalives(network, 0, supported)); + assertEquals(supported, createConcurrentSocketKeepalives(network, supported / 2, supported - supported / 2)); } dropShellPermissionIdentity(); } + /** + * Verifies that the concurrent keepalive slots meet the minimum telephony requirement, and + * don't get leaked after iterations. + */ + @AppModeFull(reason = "Cannot request network in instant app mode") + public void testSocketKeepaliveLimitTelephony() throws Exception { + if (!mPackageManager.hasSystemFeature(FEATURE_TELEPHONY)) { + Log.i(TAG, "testSocketKeepaliveLimitTelephony cannot execute unless device" + + " supports telephony"); + return; + } + + final int firstSdk = Build.VERSION.FIRST_SDK_INT; + if (firstSdk < Build.VERSION_CODES.Q) { + Log.i(TAG, "testSocketKeepaliveLimitTelephony: skip test for devices launching" + + " before Q: " + firstSdk); + return; + } + + final Network network = mCtsNetUtils.connectToCell(); + final int supported = getSupportedKeepalivesForNet(network); + + adoptShellPermissionIdentity(); + + // Verifies that the supported keepalive slots meet minimum requirement. + assertGreaterOrEqual(supported, MIN_SUPPORTED_CELLULAR_KEEPALIVE_COUNT); + + // Verifies that Nat-T keepalives can be established. + assertEquals(supported, createConcurrentSocketKeepalives(network, supported + 1, 0)); + // Verifies that keepalives don't get leaked in second round. + assertEquals(supported, createConcurrentSocketKeepalives(network, supported, 0)); + + dropShellPermissionIdentity(); + } + /** * Verifies that the keepalive slots are limited as customized for unprivileged requests. */ @AppModeFull(reason = "Cannot get WifiManager in instant app mode") public void testSocketKeepaliveUnprivileged() throws Exception { - final int supported = getSupportedKeepalivesFromRes(); + if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) { + Log.i(TAG, "testSocketKeepaliveUnprivileged cannot execute unless device" + + " supports WiFi"); + return; + } + + final Network network = ensureWifiConnected(); + final int supported = getSupportedKeepalivesForNet(network); if (supported == 0) { return; } @@ -1154,7 +1244,8 @@ public class ConnectivityManagerTest extends AndroidTestCase { assertGreaterOrEqual(supported, allowedUnprivilegedPerUid); final int expectedUnprivileged = Math.min(allowedUnprivilegedPerUid, supported - reservedPrivilegedSlots); - assertEquals(expectedUnprivileged, createConcurrentSocketKeepalives(supported + 1, 0)); + assertEquals(expectedUnprivileged, + createConcurrentSocketKeepalives(network, supported + 1, 0)); } private static void assertGreaterOrEqual(long greater, long lesser) { From d51ae5760d7850d28911557e08e5110559d78bed Mon Sep 17 00:00:00 2001 From: markchien Date: Wed, 21 Nov 2018 22:56:31 +0800 Subject: [PATCH 0657/1109] Exempt adb socket for hostside VpnTest Vpn test would destroy socket. If adb run over network, adb socket would be killed during Vpn test. Then, test stop due to adb disconnect. Bug: 119382723 Bug: 135225500 Test: - build pass Change-Id: I91b4ab018a9e7fc73dcb7969e4a6520d6b27d629 Merged-In: I91b4ab018a9e7fc73dcb7969e4a6520d6b27d629 Merged-In: Id6f986aacc3cadf713ebbc8305ca535b861390fc (cherry picked from commit de0f268f789222dd17d3c28c0f07656f2c168d81) --- tests/cts/hostside/app/Android.mk | 5 ++++- .../com/android/cts/net/hostside/VpnTest.java | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/tests/cts/hostside/app/Android.mk b/tests/cts/hostside/app/Android.mk index 1c1a798fab..b1a4494d25 100644 --- a/tests/cts/hostside/app/Android.mk +++ b/tests/cts/hostside/app/Android.mk @@ -19,10 +19,13 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests -LOCAL_SDK_VERSION := current +#LOCAL_SDK_VERSION := current +LOCAL_PRIVATE_PLATFORM_APIS := true LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util ctstestrunner ub-uiautomator \ CtsHostsideNetworkTestsAidl +LOCAL_JAVA_LIBRARIES := android.test.runner + LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := CtsHostsideNetworkTestsApp diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java index bc982cec78..b3f61c486d 100755 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java @@ -29,6 +29,7 @@ import android.net.NetworkRequest; import android.net.VpnService; import android.os.ParcelFileDescriptor; import android.os.Process; +import android.os.SystemProperties; import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiObject; import android.support.test.uiautomator.UiObjectNotFoundException; @@ -537,6 +538,14 @@ public class VpnTest extends InstrumentationTestCase { public void testDefault() throws Exception { if (!supportedHardware()) return; + // If adb TCP port opened, this test may running by adb over network. + // All of socket would be destroyed in this test. So this test don't + // support adb over network, see b/119382723. + if (SystemProperties.getInt("persist.adb.tcp.port", -1) > -1 + || SystemProperties.getInt("service.adb.tcp.port", -1) > -1) { + Log.i(TAG, "adb is running over the network, so skip this test"); + return; + } FileDescriptor fd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS); @@ -554,6 +563,7 @@ public class VpnTest extends InstrumentationTestCase { FileDescriptor fd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS); + // Shell app must not be put in here or it would kill the ADB-over-network use case String allowedApps = mRemoteSocketFactoryClient.getPackageName() + "," + mPackageName; startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"}, new String[] {"192.0.2.0/24", "2001:db8::/32"}, @@ -571,6 +581,12 @@ public class VpnTest extends InstrumentationTestCase { FileDescriptor remoteFd = openSocketFdInOtherApp(TEST_HOST, 80, TIMEOUT_MS); String disallowedApps = mRemoteSocketFactoryClient.getPackageName() + "," + mPackageName; + // If adb TCP port opened, this test may running by adb over TCP. + // Add com.android.shell appllication into blacklist to exclude adb socket for VPN test, + // see b/119382723. + // Note: The test don't support running adb over network for root device + disallowedApps = disallowedApps + ",com.android.shell"; + Log.i(TAG, "Append shell app to disallowedApps: " + disallowedApps); startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"}, new String[] {"192.0.2.0/24", "2001:db8::/32"}, "", disallowedApps); From bd43e6d4fbe4e97f7dc6a0d475d45d3586f1361c Mon Sep 17 00:00:00 2001 From: Julien Desprez Date: Wed, 19 Jun 2019 15:25:08 -0700 Subject: [PATCH 0658/1109] Mark module as "secondary_user" since it uncovered bug before This will allow running this module against a secondary user in continuous infra to uncover bugs. Test: run cts-unit-tests Bug: 130892086 Change-Id: Ic8af2e3e77e24db340b2894c2d36e3501962952c --- tests/cts/hostside/AndroidTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/cts/hostside/AndroidTest.xml b/tests/cts/hostside/AndroidTest.xml index c7cab7b0ba..dbff1794e9 100644 --- a/tests/cts/hostside/AndroidTest.xml +++ b/tests/cts/hostside/AndroidTest.xml @@ -18,6 +18,7 @@

    This method should return a socket which is fully connected (i.e. TLS handshake complete) + * and whose peer TLS certificate has been verified to have the correct hostname. + * + *

    {@link SSLCertificateSocketFactory} is documented to verify hostnames using + * the {@link HostnameVerifier} returned by + * {@link HttpsURLConnection#getDefaultHostnameVerifier}, so this test connects twice, + * once with the system default {@link HostnameVerifier} which is expected to succeed, + * and once after installing a {@link NegativeHostnameVerifier} which will cause + * {@link SSLCertificateSocketFactory#verifyHostname} to throw a + * {@link SSLPeerUnverifiedException}. + * + *

    These tests only test the hostname verification logic in SSLCertificateSocketFactory, + * other TLS failure modes and the default HostnameVerifier are tested elsewhere, see + * {@link com.squareup.okhttp.internal.tls.HostnameVerifierTest} and + * https://android.googlesource.com/platform/external/boringssl/+/refs/heads/master/src/ssl/test + * + *

    Tests the following behaviour:- + *

      + *
    • TEST_SERVER is available and has a valid TLS certificate + *
    • {@code createSocket()} verifies the remote hostname is correct using + * {@link HttpsURLConnection#getDefaultHostnameVerifier} + *
    • {@link SSLPeerUnverifiedException} is thrown when the remote hostname is invalid + *
    + * + *

    See also http://b/2807618. + */ + @Test + public void createSocket_simple_with_hostname_verification() throws Exception { + Socket socket = mSocketFactory.createSocket(TEST_HOST, HTTPS_PORT); + assertConnectedSocket(socket); + socket.close(); + + HttpsURLConnection.setDefaultHostnameVerifier(new NegativeHostnameVerifier()); + try { + mSocketFactory.createSocket(TEST_HOST, HTTPS_PORT); + fail(); + } catch (SSLPeerUnverifiedException expected) { + // expected + } + } + + /** + * Tests hostname verification for + * {@link SSLCertificateSocketFactory#createSocket(Socket, String, int, boolean)}. + * + *

    This method should return a socket which is fully connected (i.e. TLS handshake complete) + * and whose peer TLS certificate has been verified to have the correct hostname. + * + *

    The TLS socket returned is wrapped around the plain socket passed into + * {@code createSocket()}. + * + *

    See {@link #createSocket_simple_with_hostname_verification()} for test methodology. + */ + @Test + public void createSocket_wrapped_with_hostname_verification() throws Exception { + Socket underlying = new Socket(TEST_HOST, HTTPS_PORT); + Socket socket = mSocketFactory.createSocket(underlying, TEST_HOST, HTTPS_PORT, true); + assertConnectedSocket(socket); + socket.close(); + + HttpsURLConnection.setDefaultHostnameVerifier(new NegativeHostnameVerifier()); + try { + underlying = new Socket(TEST_HOST, HTTPS_PORT); + mSocketFactory.createSocket(underlying, TEST_HOST, HTTPS_PORT, true); + fail(); + } catch (SSLPeerUnverifiedException expected) { + // expected + } + } + + /** + * Tests hostname verification for + * {@link SSLCertificateSocketFactory#createSocket(String, int, InetAddress, int)}. + * + *

    This method should return a socket which is fully connected (i.e. TLS handshake complete) + * and whose peer TLS certificate has been verified to have the correct hostname. + * + *

    The TLS socket returned is also bound to the local address determined in {@link #setUp} to + * be used for connections to TEST_HOST, and a wildcard port. + * + *

    See {@link #createSocket_simple_with_hostname_verification()} for test methodology. + */ + @Test + @AppModeFull(reason = "Socket cannot bind in instant app mode") + public void createSocket_bound_with_hostname_verification() throws Exception { + Socket socket = mSocketFactory.createSocket(TEST_HOST, HTTPS_PORT, mLocalAddress, 0); + assertConnectedSocket(socket); + socket.close(); + + HttpsURLConnection.setDefaultHostnameVerifier(new NegativeHostnameVerifier()); + try { + mSocketFactory.createSocket(TEST_HOST, HTTPS_PORT, mLocalAddress, 0); + fail(); + } catch (SSLPeerUnverifiedException expected) { + // expected + } + } + + /** + * Tests hostname verification for + * {@link SSLCertificateSocketFactory#createSocket(InetAddress, int)}. + * + *

    This method should return a socket which the documentation describes as "unconnected", + * which actually means that the socket is fully connected at the TCP layer but TLS handshaking + * and hostname verification have not yet taken place. + * + *

    Behaviour is tested by installing a {@link NegativeHostnameVerifier} and by calling + * {@link #assertConnectedSocket} to ensure TLS handshaking but no hostname verification takes + * place. Next, {@link SSLCertificateSocketFactory#verifyHostname} is called to ensure + * that hostname verification is using the {@link HostnameVerifier} returned by + * {@link HttpsURLConnection#getDefaultHostnameVerifier} as documented. + * + *

    Tests the following behaviour:- + *

      + *
    • TEST_SERVER is available and has a valid TLS certificate + *
    • {@code createSocket()} does not verify the remote hostname + *
    • Calling {@link SSLCertificateSocketFactory#verifyHostname} on the returned socket + * throws {@link SSLPeerUnverifiedException} if the remote hostname is invalid + *
    + */ + @Test + public void createSocket_simple_no_hostname_verification() throws Exception{ + HttpsURLConnection.setDefaultHostnameVerifier(new NegativeHostnameVerifier()); + Socket socket = mSocketFactory.createSocket(mTestHostAddress, HTTPS_PORT); + // Need to provide the expected hostname here or the TLS handshake will + // be unable to supply SNI to the remote host. + mSocketFactory.setHostname(socket, TEST_HOST); + assertConnectedSocket(socket); + try { + SSLCertificateSocketFactory.verifyHostname(socket, TEST_HOST); + fail(); + } catch (SSLPeerUnverifiedException expected) { + // expected + } + HttpsURLConnection.setDefaultHostnameVerifier(mDefaultVerifier); + SSLCertificateSocketFactory.verifyHostname(socket, TEST_HOST); + socket.close(); + } + + /** + * Tests hostname verification for + * {@link SSLCertificateSocketFactory#createSocket(InetAddress, int, InetAddress, int)}. + * + *

    This method should return a socket which the documentation describes as "unconnected", + * which actually means that the socket is fully connected at the TCP layer but TLS handshaking + * and hostname verification have not yet taken place. + * + *

    The TLS socket returned is also bound to the local address determined in {@link #setUp} to + * be used for connections to TEST_HOST, and a wildcard port. + * + *

    See {@link #createSocket_simple_no_hostname_verification()} for test methodology. + */ + @Test + @AppModeFull(reason = "Socket cannot bind in instant app mode") + public void createSocket_bound_no_hostname_verification() throws Exception{ + HttpsURLConnection.setDefaultHostnameVerifier(new NegativeHostnameVerifier()); + Socket socket = + mSocketFactory.createSocket(mTestHostAddress, HTTPS_PORT, mLocalAddress, 0); + // Need to provide the expected hostname here or the TLS handshake will + // be unable to supply SNI to the peer. + mSocketFactory.setHostname(socket, TEST_HOST); + assertConnectedSocket(socket); + try { + SSLCertificateSocketFactory.verifyHostname(socket, TEST_HOST); + fail(); + } catch (SSLPeerUnverifiedException expected) { + // expected + } + HttpsURLConnection.setDefaultHostnameVerifier(mDefaultVerifier); + SSLCertificateSocketFactory.verifyHostname(socket, TEST_HOST); + socket.close(); + } + + /** + * Asserts a socket is fully connected to the expected peer. + * + *

    For the variants of createSocket which verify the remote hostname, + * {@code socket} should already be fully connected. + * + *

    For the non-verifying variants, retrieving the input stream will trigger a TLS handshake + * and so may throw an exception, for example if the peer's certificate is invalid. + * + *

    Does no hostname verification. + */ + private void assertConnectedSocket(Socket socket) throws Exception { assertNotNull(socket); - assertNotNull(socket.getOutputStream()); + assertTrue(socket.isConnected()); assertNotNull(socket.getInputStream()); - - // it throw exception when calling createSocket(String, int, InetAddress, int) - // The socket level is invalid. - } - - // a host and port that are expected to be available but have - // a cert with a different CN, in this case CN=mail.google.com - private static String TEST_CREATE_SOCKET_HOST = "www3.l.google.com"; - private static int TEST_CREATE_SOCKET_PORT = 443; - - /** - * b/2807618 Make sure that hostname verifcation in cases were it - * is documented to be included by various - * SSLCertificateSocketFactory.createSocket messages. - * - * NOTE: Test will fail if external server is not available. - */ - @AppModeFull(reason = "Socket cannot bind in instant app mode") - public void test_createSocket_simple() throws Exception { - try { - mFactory.createSocket(TEST_CREATE_SOCKET_HOST, TEST_CREATE_SOCKET_PORT); - fail(); - } catch (SSLPeerUnverifiedException expected) { - // expected - } + assertNotNull(socket.getOutputStream()); + assertTrue(mTestSocketAddresses.contains(socket.getRemoteSocketAddress())); } /** - * b/2807618 Make sure that hostname verifcation in cases were it - * is documented to be included by various - * SSLCertificateSocketFactory.createSocket messages. - * - * NOTE: Test will fail if external server is not available. + * A HostnameVerifier which always returns false to simulate a server returning a + * certificate which does not match the expected hostname. */ - @AppModeFull(reason = "Socket cannot bind in instant app mode") - public void test_createSocket_wrapping() throws Exception { - try { - Socket underlying = new Socket(TEST_CREATE_SOCKET_HOST, TEST_CREATE_SOCKET_PORT); - mFactory.createSocket( - underlying, TEST_CREATE_SOCKET_HOST, TEST_CREATE_SOCKET_PORT, true); - fail(); - } catch (SSLPeerUnverifiedException expected) { - // expected - } - } - - /** - * b/2807618 Make sure that hostname verifcation in cases were it - * is documented to be included by various - * SSLCertificateSocketFactory.createSocket messages. - * - * NOTE: Test will fail if external server is not available. - */ - @AppModeFull(reason = "Socket cannot bind in instant app mode") - public void test_createSocket_bind() throws Exception { - try { - mFactory.createSocket(TEST_CREATE_SOCKET_HOST, TEST_CREATE_SOCKET_PORT, null, 0); - fail(); - } catch (SSLPeerUnverifiedException expected) { - // expected + private static class NegativeHostnameVerifier implements HostnameVerifier { + @Override + public boolean verify(String hostname, SSLSession sslSession) { + return false; } } } From 14fae15d0a8e6a7fec551437be49fb0a18260d3c Mon Sep 17 00:00:00 2001 From: Julien Desprez Date: Mon, 24 Jun 2019 09:15:51 -0700 Subject: [PATCH 0661/1109] [Cherry pick] Mark module as "secondary_user" since it uncovered bug before This will allow running this module against a secondary user in continuous infra to uncover bugs. Test: run cts-unit-tests Bug: 130892086 Change-Id: I063a0d29163567ec2cf97d2e4469e88e7203e852 Merged-In: Ic8af2e3e77e24db340b2894c2d36e3501962952c --- tests/cts/hostside/AndroidTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/cts/hostside/AndroidTest.xml b/tests/cts/hostside/AndroidTest.xml index c7cab7b0ba..dbff1794e9 100644 --- a/tests/cts/hostside/AndroidTest.xml +++ b/tests/cts/hostside/AndroidTest.xml @@ -18,6 +18,7 @@

    By default is empty - it's up to subclasses to override. - */ - protected void setUpMeteredNetwork() throws Exception { - } - - /** - * Resets the (non) metered network state. - * - *

    By default is empty - it's up to subclasses to override. - */ - protected void tearDownMeteredNetwork() throws Exception { + setBatterySaverMode(false); } + @Test public void testBackgroundNetworkAccess_enabled() throws Exception { - if (!isSupported()) return; - setBatterySaverMode(true); assertBackgroundNetworkAccess(false); @@ -118,9 +80,8 @@ abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgrou assertBackgroundNetworkAccess(false); } + @Test public void testBackgroundNetworkAccess_whitelisted() throws Exception { - if (!isSupported()) return; - setBatterySaverMode(true); assertBackgroundNetworkAccess(false); @@ -140,9 +101,8 @@ abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgrou assertBackgroundNetworkAccess(false); } + @Test public void testBackgroundNetworkAccess_disabled() throws Exception { - if (!isSupported()) return; - assertBackgroundNetworkAccess(true); assertsForegroundAlwaysHasNetworkAccess(); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java index f20f1d1c4d..6f32c563c1 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java @@ -16,20 +16,25 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.Property.DOZE_MODE; +import static com.android.cts.net.hostside.Property.NOT_LOW_RAM_DEVICE; + import android.os.SystemClock; -import android.util.Log; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; /** * Base class for metered and non-metered Doze Mode tests. */ +@RequiredProperties({DOZE_MODE}) abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetworkTestCase { - @Override - protected final void setUp() throws Exception { + @Before + public final void setUp() throws Exception { super.setUp(); - if (!isSupported()) return; - // Set initial state. removePowerSaveModeWhitelist(TEST_APP2_PKG); removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG); @@ -38,48 +43,15 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor registerBroadcastReceiver(); } - @Override - protected final void tearDown() throws Exception { + @After + public final void tearDown() throws Exception { super.tearDown(); - if (!isSupported()) return; - - try { - tearDownMeteredNetwork(); - } finally { - setDozeMode(false); - } - } - - @Override - protected boolean isSupported() throws Exception { - boolean supported = isDozeModeEnabled(); - if (!supported) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Doze Mode"); - } - return supported; - } - - /** - * Sets the initial (non) metered network state. - * - *

    By default is empty - it's up to subclasses to override. - */ - protected void setUpMeteredNetwork() throws Exception { - } - - /** - * Resets the (non) metered network state. - * - *

    By default is empty - it's up to subclasses to override. - */ - protected void tearDownMeteredNetwork() throws Exception { + setDozeMode(false); } + @Test public void testBackgroundNetworkAccess_enabled() throws Exception { - if (!isSupported()) return; - setDozeMode(true); assertBackgroundNetworkAccess(false); @@ -96,9 +68,8 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor assertBackgroundNetworkAccess(false); } + @Test public void testBackgroundNetworkAccess_whitelisted() throws Exception { - if (!isSupported()) return; - setDozeMode(true); assertBackgroundNetworkAccess(false); @@ -118,19 +89,18 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor assertBackgroundNetworkAccess(false); } + @Test public void testBackgroundNetworkAccess_disabled() throws Exception { - if (!isSupported()) return; - assertBackgroundNetworkAccess(true); assertsForegroundAlwaysHasNetworkAccess(); assertBackgroundNetworkAccess(true); } + @RequiredProperties({NOT_LOW_RAM_DEVICE}) + @Test public void testBackgroundNetworkAccess_enabledButWhitelistedOnNotificationAction() throws Exception { - if (!isSupported() || isLowRamDevice()) return; - setPendingIntentWhitelistDuration(NETWORK_TIMEOUT_MS); try { registerNotificationListenerService(); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 40d7e34fcc..57b7bb4f8d 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -17,14 +17,22 @@ package com.android.cts.net.hostside; import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; -import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; -import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; -import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; import static android.os.BatteryManager.BATTERY_PLUGGED_AC; import static android.os.BatteryManager.BATTERY_PLUGGED_USB; import static android.os.BatteryManager.BATTERY_PLUGGED_WIRELESS; -import static com.android.compatibility.common.util.SystemUtil.runShellCommand; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.executeShellCommand; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getConnectivityManager; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getContext; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getInstrumentation; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getWifiManager; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isDozeModeSupported; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.restrictBackgroundValueToString; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import android.app.ActivityManager; import android.app.Instrumentation; @@ -34,9 +42,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.pm.PackageManager; import android.net.ConnectivityManager; -import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; import android.net.wifi.WifiManager; @@ -44,24 +50,27 @@ import android.os.BatteryManager; import android.os.Binder; import android.os.Bundle; import android.os.SystemClock; -import android.os.SystemProperties; import android.provider.Settings; import android.service.notification.NotificationListenerService; -import android.test.InstrumentationTestCase; -import android.text.TextUtils; import android.util.Log; -import com.android.compatibility.common.util.BatteryUtils; +import org.junit.Rule; +import org.junit.rules.RuleChain; +import org.junit.runner.RunWith; import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + /** * Superclass for tests related to background network restrictions. */ -abstract class AbstractRestrictBackgroundNetworkTestCase extends InstrumentationTestCase { - protected static final String TAG = "RestrictBackgroundNetworkTests"; +@RunWith(AndroidJUnit4.class) +public abstract class AbstractRestrictBackgroundNetworkTestCase { + public static final String TAG = "RestrictBackgroundNetworkTests"; protected static final String TEST_PKG = "com.android.cts.net.hostside"; protected static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2"; @@ -98,8 +107,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation static final int NETWORK_TIMEOUT_MS = 15 * SECOND_IN_MS; private static int PROCESS_STATE_FOREGROUND_SERVICE; - private static final int PROCESS_STATE_TOP = 2; - private static final String KEY_NETWORK_STATE_OBSERVER = TEST_PKG + ".observer"; protected static final int TYPE_COMPONENT_ACTIVTIY = 0; @@ -126,22 +133,23 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected WifiManager mWfm; protected int mUid; private int mMyUid; - private String mMeteredWifi; private MyServiceClient mServiceClient; private String mDeviceIdleConstantsSetting; - private boolean mSupported; private boolean mIsLocationOn; - @Override + @Rule + public final RuleChain mRuleChain = RuleChain.outerRule(new DumpOnFailureRule()) + .around(new RequiredPropertiesRule()) + .around(new MeterednessConfigurationRule()); + protected void setUp() throws Exception { - super.setUp(); PROCESS_STATE_FOREGROUND_SERVICE = (Integer) ActivityManager.class .getDeclaredField("PROCESS_STATE_FOREGROUND_SERVICE").get(null); mInstrumentation = getInstrumentation(); - mContext = mInstrumentation.getContext(); - mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); - mWfm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); + mContext = getContext(); + mCm = getConnectivityManager(); + mWfm = getWifiManager(); mUid = getUid(TEST_APP2_PKG); mMyUid = getUid(mContext.getPackageName()); mServiceClient = new MyServiceClient(mContext); @@ -151,10 +159,9 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation if (!mIsLocationOn) { enableLocation(); } - mSupported = setUpActiveNetworkMeteringState(); setAppIdle(false); - Log.i(TAG, "Apps status on " + getName() + ":\n" + Log.i(TAG, "Apps status:\n" + "\ttest app: uid=" + mMyUid + ", state=" + getProcessStateByUid(mMyUid) + "\n" + "\tapp2: uid=" + mUid + ", state=" + getProcessStateByUid(mUid)); @@ -165,16 +172,13 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation final String currentConstants = executeShellCommand("settings get global app_idle_constants"); assertEquals(appIdleConstants, currentConstants); - } + } - @Override protected void tearDown() throws Exception { if (!mIsLocationOn) { disableLocation(); } mServiceClient.unbind(); - - super.tearDown(); } private void enableLocation() throws Exception { @@ -259,23 +263,8 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected void assertRestrictBackgroundStatus(int expectedStatus) throws Exception { final String status = mServiceClient.getRestrictBackgroundStatus(); assertNotNull("didn't get API status from app2", status); - final String actualStatus = toString(Integer.parseInt(status)); - assertEquals("wrong status", toString(expectedStatus), actualStatus); - } - - protected void assertMyRestrictBackgroundStatus(int expectedStatus) throws Exception { - final int actualStatus = mCm.getRestrictBackgroundStatus(); - assertEquals("Wrong status", toString(expectedStatus), toString(actualStatus)); - } - - protected boolean isMyRestrictBackgroundStatus(int expectedStatus) throws Exception { - final int actualStatus = mCm.getRestrictBackgroundStatus(); - if (expectedStatus != actualStatus) { - Log.d(TAG, "Expected: " + toString(expectedStatus) - + " but actual: " + toString(actualStatus)); - return false; - } - return true; + assertEquals(restrictBackgroundValueToString(expectedStatus), + restrictBackgroundValueToString(Integer.parseInt(status))); } protected void assertBackgroundNetworkAccess(boolean expectAllowed) throws Exception { @@ -297,28 +286,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation assertNetworkAccess(true /* expectAvailable */, false /* needScreenOn */); } - /** - * Whether this device suport this type of test. - * - *

    Should be overridden when necessary (but always calling - * {@code super.isSupported()} first), and explicitly used before each test - * Example: - * - *

    
    -     * public void testSomething() {
    -     *    if (!isSupported()) return;
    -     * 
    - * - * @return {@code true} by default. - */ - protected boolean isSupported() throws Exception { - return mSupported; - } - - protected boolean isBatterySaverSupported() { - return BatteryUtils.isBatterySaverSupported(); - } - /** * Asserts that an app always have access while on foreground or running a foreground service. * @@ -387,23 +354,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation fail("App2 is not on foreground service state after " + maxTries + " attempts: " + state ); } - /** - * As per CDD requirements, if the device doesn't support data saver mode then - * ConnectivityManager.getRestrictBackgroundStatus() will always return - * RESTRICT_BACKGROUND_STATUS_DISABLED. So, enable the data saver mode and check if - * ConnectivityManager.getRestrictBackgroundStatus() for an app in background returns - * RESTRICT_BACKGROUND_STATUS_DISABLED or not. - */ - protected boolean isDataSaverSupported() throws Exception { - assertMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); - try { - setRestrictBackground(true); - return !isMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); - } finally { - setRestrictBackground(false); - } - } - /** * Returns whether an app state should be considered "background" for restriction purposes. */ @@ -443,40 +393,10 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation // Exponential back-off. timeoutMs = Math.min(timeoutMs*2, NETWORK_TIMEOUT_MS); } - dumpOnFailure(); fail("Invalid state for expectAvailable=" + expectAvailable + " after " + maxTries + " attempts.\nLast error: " + error); } - private void dumpOnFailure() throws Exception { - dumpAllNetworkRules(); - Log.d(TAG, "Usagestats dump: " + getUsageStatsDump()); - executeShellCommand("settings get global app_idle_constants"); - } - - private void dumpAllNetworkRules() throws Exception { - final String networkManagementDump = runShellCommand(mInstrumentation, - "dumpsys network_management").trim(); - final String networkPolicyDump = runShellCommand(mInstrumentation, - "dumpsys netpolicy").trim(); - TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter('\n'); - splitter.setString(networkManagementDump); - String next; - Log.d(TAG, ">>> Begin network_management dump"); - while (splitter.hasNext()) { - next = splitter.next(); - Log.d(TAG, next); - } - Log.d(TAG, "<<< End network_management dump"); - splitter.setString(networkPolicyDump); - Log.d(TAG, ">>> Begin netpolicy dump"); - while (splitter.hasNext()) { - next = splitter.next(); - Log.d(TAG, next); - } - Log.d(TAG, "<<< End netpolicy dump"); - } - /** * Checks whether the network is available as expected. * @@ -528,22 +448,10 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation return errors.toString(); } - protected boolean isLowRamDevice() { - final ActivityManager am = (ActivityManager) mContext.getSystemService( - Context.ACTIVITY_SERVICE); - return am.isLowRamDevice(); - } - - protected String executeShellCommand(String command) throws Exception { - final String result = runShellCommand(mInstrumentation, command).trim(); - if (DEBUG) Log.d(TAG, "Command '" + command + "' returned '" + result + "'"); - return result; - } - /** * Runs a Shell command which is not expected to generate output. */ - protected void executeSilentShellCommand(String command) throws Exception { + protected void executeSilentShellCommand(String command) { final String result = executeShellCommand(command); assertTrue("Command '" + command + "' failed: " + result, result.trim().isEmpty()); } @@ -572,10 +480,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation }); } - protected void assertDelayedShellCommand(String command, ExpectResultChecker checker) - throws Exception { - assertDelayedShellCommand(command, 5, 1, checker); - } protected void assertDelayedShellCommand(String command, int maxTries, int napTimeSeconds, ExpectResultChecker checker) throws Exception { String result = ""; @@ -592,159 +496,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation + " attempts. Last result: '" + result + "'"); } - /** - * Sets the initial metering state for the active network. - * - *

    It's called on setup and by default does nothing - it's up to the - * subclasses to override. - * - * @return whether the tests in the subclass are supported on this device. - */ - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return true; - } - - /** - * Makes sure the active network is not metered. - * - *

    If the device does not supoprt un-metered networks (for example if it - * only has cellular data but not wi-fi), it should return {@code false}; - * otherwise, it should return {@code true} (or fail if the un-metered - * network could not be set). - * - * @return {@code true} if the network is now unmetered. - */ - protected boolean setUnmeteredNetwork() throws Exception { - final NetworkInfo info = mCm.getActiveNetworkInfo(); - assertNotNull("Could not get active network", info); - if (!mCm.isActiveNetworkMetered()) { - Log.d(TAG, "Active network is not metered: " + info); - } else if (info.getType() == ConnectivityManager.TYPE_WIFI) { - Log.i(TAG, "Setting active WI-FI network as not metered: " + info ); - setWifiMeteredStatus(false); - } else { - Log.d(TAG, "Active network cannot be set to un-metered: " + info); - return false; - } - assertActiveNetworkMetered(false); // Sanity check. - return true; - } - - /** - * Enables metering on the active network if supported. - * - *

    If the device does not support metered networks it should return - * {@code false}; otherwise, it should return {@code true} (or fail if the - * metered network could not be set). - * - * @return {@code true} if the network is now metered. - */ - protected boolean setMeteredNetwork() throws Exception { - final NetworkInfo info = mCm.getActiveNetworkInfo(); - final boolean metered = mCm.isActiveNetworkMetered(); - if (metered) { - Log.d(TAG, "Active network already metered: " + info); - return true; - } else if (info.getType() != ConnectivityManager.TYPE_WIFI) { - Log.w(TAG, "Active network does not support metering: " + info); - return false; - } else { - Log.w(TAG, "Active network not metered: " + info); - } - final String netId = setWifiMeteredStatus(true); - - // Set flag so status is reverted on resetMeteredNetwork(); - mMeteredWifi = netId; - // Sanity check. - assertWifiMeteredStatus(netId, true); - assertActiveNetworkMetered(true); - return true; - } - - /** - * Resets the device metering state to what it was before the test started. - * - *

    This reverts any metering changes made by {@code setMeteredNetwork}. - */ - protected void resetMeteredNetwork() throws Exception { - if (mMeteredWifi != null) { - Log.i(TAG, "resetMeteredNetwork(): SID '" + mMeteredWifi - + "' was set as metered by test case; resetting it"); - setWifiMeteredStatus(mMeteredWifi, false); - assertActiveNetworkMetered(false); // Sanity check. - } - } - - private void assertActiveNetworkMetered(boolean expected) throws Exception { - final int maxTries = 5; - NetworkInfo info = null; - for (int i = 1; i <= maxTries; i++) { - info = mCm.getActiveNetworkInfo(); - if (info == null) { - Log.v(TAG, "No active network info on attempt #" + i - + "; sleeping 1s before polling again"); - } else if (mCm.isActiveNetworkMetered() != expected) { - Log.v(TAG, "Wrong metered status for active network " + info + "; expected=" - + expected + "; sleeping 1s before polling again"); - } else { - break; - } - Thread.sleep(SECOND_IN_MS); - } - assertNotNull("No active network after " + maxTries + " attempts", info); - assertEquals("Wrong metered status for active network " + info, expected, - mCm.isActiveNetworkMetered()); - } - - private String setWifiMeteredStatus(boolean metered) throws Exception { - // We could call setWifiEnabled() here, but it might take sometime to be in a consistent - // state (for example, if one of the saved network is not properly authenticated), so it's - // better to let the hostside test take care of that. - assertTrue("wi-fi is disabled", mWfm.isWifiEnabled()); - // TODO: if it's not guaranteed the device has wi-fi, we need to change the tests - // to make the actual verification of restrictions optional. - final String ssid = mWfm.getConnectionInfo().getSSID(); - return setWifiMeteredStatus(ssid, metered); - } - - private String setWifiMeteredStatus(String ssid, boolean metered) throws Exception { - assertNotNull("null SSID", ssid); - final String netId = ssid.trim().replaceAll("\"", ""); // remove quotes, if any. - assertFalse("empty SSID", ssid.isEmpty()); - - Log.i(TAG, "Setting wi-fi network " + netId + " metered status to " + metered); - final String setCommand = "cmd netpolicy set metered-network " + netId + " " + metered; - assertDelayedShellCommand(setCommand, ""); - - return netId; - } - - private void assertWifiMeteredStatus(String netId, boolean status) throws Exception { - final String command = "cmd netpolicy list wifi-networks"; - final String expectedLine = netId + ";" + status; - assertDelayedShellCommand(command, new ExpectResultChecker() { - - @Override - public boolean isExpected(String result) { - return result.contains(expectedLine); - } - - @Override - public String getExpected() { - return "line containing " + expectedLine; - } - }); - } - - protected void setRestrictBackground(boolean enabled) throws Exception { - executeShellCommand("cmd netpolicy set restrict-background " + enabled); - final String output = executeShellCommand("cmd netpolicy get restrict-background "); - final String expectedSuffix = enabled ? "enabled" : "disabled"; - // TODO: use MoreAsserts? - assertTrue("output '" + output + "' should end with '" + expectedSuffix + "'", - output.endsWith(expectedSuffix)); - } - protected void addRestrictBackgroundWhitelist(int uid) throws Exception { executeShellCommand("cmd netpolicy add restrict-background-whitelist " + uid); assertRestrictBackgroundWhitelist(uid, true); @@ -924,7 +675,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected void setDozeMode(boolean enabled) throws Exception { // Sanity check, since tests should check beforehand.... - assertTrue("Device does not support Doze Mode", isDozeModeEnabled()); + assertTrue("Device does not support Doze Mode", isDozeModeSupported()); Log.i(TAG, "Setting Doze Mode to " + enabled); if (enabled) { @@ -944,43 +695,16 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation assertDelayedShellCommand("dumpsys deviceidle get deep", enabled ? "IDLE" : "ACTIVE"); } - protected boolean isDozeModeEnabled() throws Exception { - final String result = executeShellCommand("cmd deviceidle enabled deep").trim(); - return result.equals("1"); - } - protected void setAppIdle(boolean enabled) throws Exception { Log.i(TAG, "Setting app idle to " + enabled); executeSilentShellCommand("am set-inactive " + TEST_APP2_PKG + " " + enabled ); assertAppIdle(enabled); // Sanity check } - private String getUsageStatsDump() throws Exception { - final String output = runShellCommand(mInstrumentation, "dumpsys usagestats").trim(); - final StringBuilder sb = new StringBuilder(); - final TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter('\n'); - splitter.setString(output); - String str; - while (splitter.hasNext()) { - str = splitter.next(); - if (str.contains("package=") - && !str.contains(TEST_PKG) && !str.contains(TEST_APP2_PKG)) { - continue; - } - if (str.trim().startsWith("config=") || str.trim().startsWith("time=")) { - continue; - } - sb.append(str).append('\n'); - } - return sb.toString(); - } - protected void assertAppIdle(boolean enabled) throws Exception { try { assertDelayedShellCommand("am get-inactive " + TEST_APP2_PKG, 15, 2, "Idle=" + enabled); } catch (Throwable e) { - Log.d(TAG, "UsageStats dump:\n" + getUsageStatsDump()); - executeShellCommand("settings get global app_idle_constants"); throw e; } } @@ -1061,12 +785,10 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation // App didn't come to foreground when the activity is started, so try again. assertForegroundNetworkAccess(); } else { - dumpOnFailure(); fail("Network is not available for app2 (" + mUid + "): " + errors[0]); } } } else { - dumpOnFailure(); fail("Timed out waiting for network availability status from app2 (" + mUid + ")"); } } else { @@ -1150,19 +872,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation } } - private String toString(int status) { - switch (status) { - case RESTRICT_BACKGROUND_STATUS_DISABLED: - return "DISABLED"; - case RESTRICT_BACKGROUND_STATUS_WHITELISTED: - return "WHITELISTED"; - case RESTRICT_BACKGROUND_STATUS_ENABLED: - return "ENABLED"; - default: - return "UNKNOWN_STATUS_" + status; - } - } - private ProcessState getProcessStateByUid(int uid) throws Exception { return new ProcessState(executeShellCommand("cmd activity get-uid-state " + uid)); } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java index 622d99361f..f1858d65a5 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java @@ -16,15 +16,8 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; + +@RequiredProperties({METERED_NETWORK}) public class AppIdleMeteredTest extends AbstractAppIdleTestCase { - - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setMeteredNetwork(); - } - - @Override - protected void tearDownMeteredNetwork() throws Exception { - resetMeteredNetwork(); - } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java index bde71f9100..e737a6dabe 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java @@ -16,9 +16,8 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; + +@RequiredProperties({NON_METERED_NETWORK}) public class AppIdleNonMeteredTest extends AbstractAppIdleTestCase { - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setUnmeteredNetwork(); - } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java index 3071cfe3f1..c78ca2ec77 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java @@ -16,15 +16,8 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; + +@RequiredProperties({METERED_NETWORK}) public class BatterySaverModeMeteredTest extends AbstractBatterySaverModeTestCase { - - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setMeteredNetwork(); - } - - @Override - protected void tearDownMeteredNetwork() throws Exception { - resetMeteredNetwork(); - } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java index 6d3076fe0e..fb52a540d8 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java @@ -16,10 +16,9 @@ package com.android.cts.net.hostside; -public class BatterySaverModeNonMeteredTest extends AbstractBatterySaverModeTestCase { - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setUnmeteredNetwork(); - } +import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; + +@RequiredProperties({NON_METERED_NETWORK}) +public class BatterySaverModeNonMeteredTest extends AbstractBatterySaverModeTestCase { } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index cfe6a73a0f..aa2c914e02 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -20,24 +20,33 @@ import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLE import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; -import android.util.Log; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground; +import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; +import static com.android.cts.net.hostside.Property.NO_DATA_SAVER_MODE; + +import static org.junit.Assert.fail; import com.android.compatibility.common.util.CddTest; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import androidx.test.filters.LargeTest; + +@RequiredProperties({DATA_SAVER_MODE, METERED_NETWORK}) +@LargeTest public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase { private static final String[] REQUIRED_WHITELISTED_PACKAGES = { "com.android.providers.downloads" }; - private boolean mIsDataSaverSupported; - - @Override + @Before public void setUp() throws Exception { super.setUp(); - mIsDataSaverSupported = isDataSaverSupported(); - // Set initial state. setRestrictBackground(false); removeRestrictBackgroundWhitelist(mUid); @@ -47,36 +56,15 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertRestrictBackgroundChangedReceived(0); } - @Override - protected void tearDown() throws Exception { + @After + public void tearDown() throws Exception { super.tearDown(); - if (!isSupported()) return; - - try { - resetMeteredNetwork(); - } finally { - setRestrictBackground(false); - } - } - - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setMeteredNetwork(); - } - - @Override - protected boolean isSupported() throws Exception { - if (!mIsDataSaverSupported) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Data Saver Mode"); - } - return mIsDataSaverSupported && super.isSupported(); + setRestrictBackground(false); } + @Test public void testGetRestrictBackgroundStatus_disabled() throws Exception { - if (!isSupported()) return; - assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED); // Sanity check: make sure status is always disabled, never whitelisted @@ -88,9 +76,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED); } + @Test public void testGetRestrictBackgroundStatus_whitelisted() throws Exception { - if (!isSupported()) return; - setRestrictBackground(true); assertRestrictBackgroundChangedReceived(1); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); @@ -107,9 +94,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); } + @Test public void testGetRestrictBackgroundStatus_enabled() throws Exception { - if (!isSupported()) return; - setRestrictBackground(true); assertRestrictBackgroundChangedReceived(1); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); @@ -142,9 +128,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertBackgroundNetworkAccess(false); } + @Test public void testGetRestrictBackgroundStatus_blacklisted() throws Exception { - if (!isSupported()) return; - addRestrictBackgroundBlacklist(mUid); assertRestrictBackgroundChangedReceived(1); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); @@ -180,9 +165,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertsForegroundAlwaysHasNetworkAccess(); } + @Test public void testGetRestrictBackgroundStatus_requiredWhitelistedPackages() throws Exception { - if (!isSupported()) return; - final StringBuilder error = new StringBuilder(); for (String packageName : REQUIRED_WHITELISTED_PACKAGES) { int uid = -1; @@ -202,10 +186,10 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase } } + @RequiredProperties({NO_DATA_SAVER_MODE}) @CddTest(requirement="7.4.7/C-2-2") + @Test public void testBroadcastNotSentOnUnsupportedDevices() throws Exception { - if (isSupported()) return; - setRestrictBackground(true); assertRestrictBackgroundChangedReceived(0); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java index e4189af587..4306c991c2 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java @@ -16,15 +16,8 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; + +@RequiredProperties({METERED_NETWORK}) public class DozeModeMeteredTest extends AbstractDozeModeTestCase { - - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setMeteredNetwork(); - } - - @Override - protected void tearDownMeteredNetwork() throws Exception { - resetMeteredNetwork(); - } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java index edbbb9e1ce..1e89f158a3 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java @@ -16,10 +16,8 @@ package com.android.cts.net.hostside; -public class DozeModeNonMeteredTest extends AbstractDozeModeTestCase { +import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setUnmeteredNetwork(); - } +@RequiredProperties({NON_METERED_NETWORK}) +public class DozeModeNonMeteredTest extends AbstractDozeModeTestCase { } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java new file mode 100644 index 0000000000..cedd62a0bc --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TAG; +import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TEST_PKG; + +import android.os.Environment; +import android.os.FileUtils; +import android.os.ParcelFileDescriptor; +import android.util.Log; + +import com.android.compatibility.common.util.OnFailureRule; + +import org.junit.AssumptionViolatedException; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import androidx.test.platform.app.InstrumentationRegistry; + +public class DumpOnFailureRule extends OnFailureRule { + private File mDumpDir = new File(Environment.getExternalStorageDirectory(), + "CtsHostsideNetworkTests"); + + @Override + public void onTestFailure(Statement base, Description description, Throwable throwable) { + final String testName = description.getClassName() + "_" + description.getMethodName(); + + if (throwable instanceof AssumptionViolatedException) { + Log.d(TAG, "Skipping test " + testName + ": " + throwable); + return; + } + + prepareDumpRootDir(); + final File dumpFile = new File(mDumpDir, "dump-" + testName); + Log.i(TAG, "Dumping debug info for " + description + ": " + dumpFile.getPath()); + try (FileOutputStream out = new FileOutputStream(dumpFile)) { + for (String cmd : new String[] { + "dumpsys netpolicy", + "dumpsys network_management", + "dumpsys usagestats " + TEST_PKG, + "dumpsys usagestats appstandby", + }) { + dumpCommandOutput(out, cmd); + } + } catch (FileNotFoundException e) { + Log.e(TAG, "Error opening file: " + dumpFile, e); + } catch (IOException e) { + Log.e(TAG, "Error closing file: " + dumpFile, e); + } + } + + void dumpCommandOutput(FileOutputStream out, String cmd) { + final ParcelFileDescriptor pfd = InstrumentationRegistry.getInstrumentation() + .getUiAutomation().executeShellCommand(cmd); + try (FileInputStream in = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) { + out.write(("Output of '" + cmd + "':\n").getBytes(StandardCharsets.UTF_8)); + FileUtils.copy(in, out); + out.write("\n\n=================================================================\n\n" + .getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + Log.e(TAG, "Error dumping '" + cmd + "'", e); + } + } + + void prepareDumpRootDir() { + if (!mDumpDir.exists() && !mDumpDir.mkdir()) { + Log.e(TAG, "Error creating " + mDumpDir); + } + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java new file mode 100644 index 0000000000..8fadf9e295 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.resetMeteredNetwork; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setupMeteredNetwork; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; +import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; + +import android.util.ArraySet; +import android.util.Pair; + +import com.android.compatibility.common.util.BeforeAfterRule; + +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +public class MeterednessConfigurationRule extends BeforeAfterRule { + private Pair mSsidAndInitialMeteredness; + + @Override + public void onBefore(Statement base, Description description) throws Throwable { + final ArraySet requiredProperties + = RequiredPropertiesRule.getRequiredProperties(); + if (requiredProperties.contains(METERED_NETWORK)) { + configureNetworkMeteredness(true); + } else if (requiredProperties.contains(NON_METERED_NETWORK)) { + configureNetworkMeteredness(false); + } + } + + @Override + public void onAfter(Statement base, Description description) throws Throwable { + resetNetworkMeteredness(); + } + + public void configureNetworkMeteredness(boolean metered) throws Exception { + mSsidAndInitialMeteredness = setupMeteredNetwork(metered); + } + + public void resetNetworkMeteredness() throws Exception { + if (mSsidAndInitialMeteredness != null) { + resetMeteredNetwork(mSsidAndInitialMeteredness.first, + mSsidAndInitialMeteredness.second); + } + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java index b1a21867b3..c9edda6e0b 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java @@ -15,9 +15,21 @@ */ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground; +import static com.android.cts.net.hostside.Property.APP_STANDBY_MODE; +import static com.android.cts.net.hostside.Property.BATTERY_SAVER_MODE; +import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE; +import static com.android.cts.net.hostside.Property.DOZE_MODE; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; +import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; + import android.os.SystemClock; import android.util.Log; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + /** * Test cases for the more complex scenarios where multiple restrictions (like Battery Saver Mode * and Data Saver Mode) are applied simultaneously. @@ -29,12 +41,10 @@ import android.util.Log; public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { private static final String TAG = "MixedModesTest"; - @Override + @Before public void setUp() throws Exception { super.setUp(); - if (!isSupported()) return; - // Set initial state. removeRestrictBackgroundWhitelist(mUid); removeRestrictBackgroundBlacklist(mUid); @@ -44,12 +54,10 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { registerBroadcastReceiver(); } - @Override - protected void tearDown() throws Exception { + @After + public void tearDown() throws Exception { super.tearDown(); - if (!isSupported()) return; - try { setRestrictBackground(false); } finally { @@ -57,34 +65,15 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } - @Override - public boolean isSupported() throws Exception { - if (!isDozeModeEnabled()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Doze Mode"); - return false; - } - return true; - } - /** * Tests all DS ON and BS ON scenarios from network-policy-restrictions.md on metered networks. */ + @RequiredProperties({DATA_SAVER_MODE, BATTERY_SAVER_MODE, METERED_NETWORK}) + @Test public void testDataAndBatterySaverModes_meteredNetwork() throws Exception { - if (!isBatterySaverSupported()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Battery saver mode"); - return; - } - if (!isSupported()) return; - - Log.i(TAG, "testDataAndBatterySaverModes_meteredNetwork() tests"); - if (!setMeteredNetwork()) { - Log.w(TAG, "testDataAndBatterySaverModes_meteredNetwork() skipped because " - + "device cannot use a metered network"); - return; - } - + final MeterednessConfigurationRule meterednessConfiguration + = new MeterednessConfigurationRule(); + meterednessConfiguration.configureNetworkMeteredness(true); try { setRestrictBackground(true); setBatterySaverMode(true); @@ -137,7 +126,7 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { removeRestrictBackgroundBlacklist(mUid); removePowerSaveModeWhitelist(TEST_APP2_PKG); } finally { - resetMeteredNetwork(); + meterednessConfiguration.resetNetworkMeteredness(); } } @@ -145,86 +134,75 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { * Tests all DS ON and BS ON scenarios from network-policy-restrictions.md on non-metered * networks. */ + @RequiredProperties({DATA_SAVER_MODE, BATTERY_SAVER_MODE, NON_METERED_NETWORK}) + @Test public void testDataAndBatterySaverModes_nonMeteredNetwork() throws Exception { - if (!isBatterySaverSupported()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Battery saver mode"); - return; + final MeterednessConfigurationRule meterednessConfiguration + = new MeterednessConfigurationRule(); + meterednessConfiguration.configureNetworkMeteredness(false); + try { + setRestrictBackground(true); + setBatterySaverMode(true); + + Log.v(TAG, "Not whitelisted for any."); + assertBackgroundNetworkAccess(false); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + + Log.v(TAG, "Whitelisted for Data Saver but not for Battery Saver."); + addRestrictBackgroundWhitelist(mUid); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + removeRestrictBackgroundWhitelist(mUid); + + Log.v(TAG, "Whitelisted for Battery Saver but not for Data Saver."); + addPowerSaveModeWhitelist(TEST_APP2_PKG); + removeRestrictBackgroundWhitelist(mUid); + assertBackgroundNetworkAccess(true); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(true); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + + Log.v(TAG, "Whitelisted for both."); + addRestrictBackgroundWhitelist(mUid); + addPowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(true); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(true); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + removeRestrictBackgroundWhitelist(mUid); + + Log.v(TAG, "Blacklisted for Data Saver, not whitelisted for Battery Saver."); + addRestrictBackgroundBlacklist(mUid); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + removeRestrictBackgroundBlacklist(mUid); + + Log.v(TAG, "Blacklisted for Data Saver, whitelisted for Battery Saver."); + addRestrictBackgroundBlacklist(mUid); + addPowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(true); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(true); + removeRestrictBackgroundBlacklist(mUid); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + } finally { + meterednessConfiguration.resetNetworkMeteredness(); } - if (!isSupported()) return; - - if (!setUnmeteredNetwork()) { - Log.w(TAG, "testDataAndBatterySaverModes_nonMeteredNetwork() skipped because network" - + " is metered"); - return; - } - Log.i(TAG, "testDataAndBatterySaverModes_nonMeteredNetwork() tests"); - setRestrictBackground(true); - setBatterySaverMode(true); - - Log.v(TAG, "Not whitelisted for any."); - assertBackgroundNetworkAccess(false); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(false); - - Log.v(TAG, "Whitelisted for Data Saver but not for Battery Saver."); - addRestrictBackgroundWhitelist(mUid); - removePowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(false); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(false); - removeRestrictBackgroundWhitelist(mUid); - - Log.v(TAG, "Whitelisted for Battery Saver but not for Data Saver."); - addPowerSaveModeWhitelist(TEST_APP2_PKG); - removeRestrictBackgroundWhitelist(mUid); - assertBackgroundNetworkAccess(true); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(true); - removePowerSaveModeWhitelist(TEST_APP2_PKG); - - Log.v(TAG, "Whitelisted for both."); - addRestrictBackgroundWhitelist(mUid); - addPowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(true); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(true); - removePowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(false); - removeRestrictBackgroundWhitelist(mUid); - - Log.v(TAG, "Blacklisted for Data Saver, not whitelisted for Battery Saver."); - addRestrictBackgroundBlacklist(mUid); - removePowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(false); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(false); - removeRestrictBackgroundBlacklist(mUid); - - Log.v(TAG, "Blacklisted for Data Saver, whitelisted for Battery Saver."); - addRestrictBackgroundBlacklist(mUid); - addPowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(true); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(true); - removeRestrictBackgroundBlacklist(mUid); - removePowerSaveModeWhitelist(TEST_APP2_PKG); } /** * Tests that powersave whitelists works as expected when doze and battery saver modes * are enabled. */ + @RequiredProperties({DOZE_MODE, BATTERY_SAVER_MODE}) + @Test public void testDozeAndBatterySaverMode_powerSaveWhitelists() throws Exception { - if (!isBatterySaverSupported()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Battery saver mode"); - return; - } - if (!isSupported()) { - return; - } - setBatterySaverMode(true); setDozeMode(true); @@ -250,11 +228,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { * Tests that powersave whitelists works as expected when doze and appIdle modes * are enabled. */ + @RequiredProperties({DOZE_MODE, APP_STANDBY_MODE}) + @Test public void testDozeAndAppIdle_powerSaveWhitelists() throws Exception { - if (!isSupported()) { - return; - } - setDozeMode(true); setAppIdle(true); @@ -276,11 +252,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } + @RequiredProperties({APP_STANDBY_MODE, DOZE_MODE}) + @Test public void testAppIdleAndDoze_tempPowerSaveWhitelists() throws Exception { - if (!isSupported()) { - return; - } - setDozeMode(true); setAppIdle(true); @@ -299,16 +273,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } + @RequiredProperties({APP_STANDBY_MODE, BATTERY_SAVER_MODE}) + @Test public void testAppIdleAndBatterySaver_tempPowerSaveWhitelists() throws Exception { - if (!isBatterySaverSupported()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Battery saver mode"); - return; - } - if (!isSupported()) { - return; - } - setBatterySaverMode(true); setAppIdle(true); @@ -330,11 +297,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { /** * Tests that the app idle whitelist works as expected when doze and appIdle mode are enabled. */ + @RequiredProperties({DOZE_MODE, APP_STANDBY_MODE}) + @Test public void testDozeAndAppIdle_appIdleWhitelist() throws Exception { - if (!isSupported()) { - return; - } - setDozeMode(true); setAppIdle(true); @@ -353,11 +318,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } + @RequiredProperties({APP_STANDBY_MODE, DOZE_MODE}) + @Test public void testAppIdleAndDoze_tempPowerSaveAndAppIdleWhitelists() throws Exception { - if (!isSupported()) { - return; - } - setDozeMode(true); setAppIdle(true); @@ -380,16 +343,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } + @RequiredProperties({APP_STANDBY_MODE, BATTERY_SAVER_MODE}) + @Test public void testAppIdleAndBatterySaver_tempPowerSaveAndAppIdleWhitelists() throws Exception { - if (!isBatterySaverSupported()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Battery saver mode"); - return; - } - if (!isSupported()) { - return; - } - setBatterySaverMode(true); setAppIdle(true); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java index 24dde9d356..ed397b91fc 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java @@ -16,15 +16,26 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground; +import static com.android.cts.net.hostside.Property.BATTERY_SAVER_MODE; +import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + import android.net.Network; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + import java.util.Objects; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCase { - private boolean mIsDataSaverSupported; private Network mNetwork; private final TestNetworkCallback mTestNetworkCallback = new TestNetworkCallback(); @@ -132,108 +143,122 @@ public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCa } } - @Override + @Before public void setUp() throws Exception { super.setUp(); - mIsDataSaverSupported = isDataSaverSupported(); - mNetwork = mCm.getActiveNetwork(); - // Set initial state. - setBatterySaverMode(false); registerBroadcastReceiver(); - if (!mIsDataSaverSupported) return; - setRestrictBackground(false); removeRestrictBackgroundWhitelist(mUid); removeRestrictBackgroundBlacklist(mUid); assertRestrictBackgroundChangedReceived(0); } - @Override - protected void tearDown() throws Exception { + @After + public void tearDown() throws Exception { super.tearDown(); - if (!mIsDataSaverSupported) return; + setRestrictBackground(false); + setBatterySaverMode(false); + } + @RequiredProperties({DATA_SAVER_MODE}) + @Test + public void testOnBlockedStatusChanged_dataSaver() throws Exception { + // Initial state + setBatterySaverMode(false); + setRestrictBackground(false); + + final MeterednessConfigurationRule meterednessConfiguration + = new MeterednessConfigurationRule(); + meterednessConfiguration.configureNetworkMeteredness(true); try { - resetMeteredNetwork(); + // Register callback + registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); + mTestNetworkCallback.expectAvailableCallback(mNetwork); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Enable restrict background + setRestrictBackground(true); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); + + // Add to whitelist + addRestrictBackgroundWhitelist(mUid); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Remove from whitelist + removeRestrictBackgroundWhitelist(mUid); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); } finally { + meterednessConfiguration.resetNetworkMeteredness(); + } + + // Set to non-metered network + meterednessConfiguration.configureNetworkMeteredness(false); + try { + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Disable restrict background, should not trigger callback setRestrictBackground(false); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.assertNoCallback(); + } finally { + meterednessConfiguration.resetNetworkMeteredness(); } } - public void testOnBlockedStatusChanged_data_saver() throws Exception { - if (!mIsDataSaverSupported) return; - - // Prepare metered wifi - if (!setMeteredNetwork()) return; - - // Register callback - registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); - mTestNetworkCallback.expectAvailableCallback(mNetwork); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - - // Enable restrict background - setRestrictBackground(true); - assertBackgroundNetworkAccess(false); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); - - // Add to whitelist - addRestrictBackgroundWhitelist(mUid); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - - // Remove from whitelist - removeRestrictBackgroundWhitelist(mUid); - assertBackgroundNetworkAccess(false); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); - - // Set to non-metered network - setUnmeteredNetwork(); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - - // Disable restrict background, should not trigger callback + @RequiredProperties({BATTERY_SAVER_MODE}) + @Test + public void testOnBlockedStatusChanged_powerSaver() throws Exception { + // Set initial state. + setBatterySaverMode(false); setRestrictBackground(false); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.assertNoCallback(); - } + final MeterednessConfigurationRule meterednessConfiguration + = new MeterednessConfigurationRule(); + meterednessConfiguration.configureNetworkMeteredness(true); + try { + // Register callback + registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); + mTestNetworkCallback.expectAvailableCallback(mNetwork); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - public void testOnBlockedStatusChanged_power_saver() throws Exception { - // Prepare metered wifi - if (!setMeteredNetwork()) return; + // Enable Power Saver + setBatterySaverMode(true); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); - // Register callback - registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); - mTestNetworkCallback.expectAvailableCallback(mNetwork); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - - // Enable Power Saver - setBatterySaverMode(true); - assertBackgroundNetworkAccess(false); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); - - // Disable Power Saver - setBatterySaverMode(false); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + // Disable Power Saver + setBatterySaverMode(false); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + } finally { + meterednessConfiguration.resetNetworkMeteredness(); + } // Set to non-metered network - setUnmeteredNetwork(); - mTestNetworkCallback.assertNoCallback(); + meterednessConfiguration.configureNetworkMeteredness(false); + try { + mTestNetworkCallback.assertNoCallback(); - // Enable Power Saver - setBatterySaverMode(true); - assertBackgroundNetworkAccess(false); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); + // Enable Power Saver + setBatterySaverMode(true); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); - // Disable Power Saver - setBatterySaverMode(false); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + // Disable Power Saver + setBatterySaverMode(false); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + } finally { + meterednessConfiguration.resetNetworkMeteredness(); + } } // TODO: 1. test against VPN lockdown. diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java new file mode 100644 index 0000000000..ca2864c0b8 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; +import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; +import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; +import static android.net.NetworkCapabilities.TRANSPORT_WIFI; + +import static com.android.compatibility.common.util.SystemUtil.runShellCommand; +import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TAG; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import android.app.ActivityManager; +import android.app.Instrumentation; +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.ConnectivityManager.NetworkCallback; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.wifi.WifiManager; +import android.text.TextUtils; +import android.util.Log; +import android.util.Pair; + +import com.android.compatibility.common.util.AppStandbyUtils; +import com.android.compatibility.common.util.BatteryUtils; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import androidx.test.platform.app.InstrumentationRegistry; + +public class NetworkPolicyTestUtils { + + private static final int TIMEOUT_CHANGE_METEREDNESS_MS = 5000; + + private static ConnectivityManager mCm; + private static WifiManager mWm; + + private static Boolean mBatterySaverSupported; + private static Boolean mDataSaverSupported; + private static Boolean mDozeModeSupported; + private static Boolean mAppStandbySupported; + + private NetworkPolicyTestUtils() {} + + public static boolean isBatterySaverSupported() { + if (mBatterySaverSupported == null) { + mBatterySaverSupported = BatteryUtils.isBatterySaverSupported(); + } + return mBatterySaverSupported; + } + + /** + * As per CDD requirements, if the device doesn't support data saver mode then + * ConnectivityManager.getRestrictBackgroundStatus() will always return + * RESTRICT_BACKGROUND_STATUS_DISABLED. So, enable the data saver mode and check if + * ConnectivityManager.getRestrictBackgroundStatus() for an app in background returns + * RESTRICT_BACKGROUND_STATUS_DISABLED or not. + */ + public static boolean isDataSaverSupported() { + if (mDataSaverSupported == null) { + assertMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + try { + setRestrictBackground(true); + mDataSaverSupported = !isMyRestrictBackgroundStatus( + RESTRICT_BACKGROUND_STATUS_DISABLED); + } finally { + setRestrictBackground(false); + } + } + return mDataSaverSupported; + } + + public static boolean isDozeModeSupported() { + if (mDozeModeSupported == null) { + final String result = executeShellCommand("cmd deviceidle enabled deep"); + mDozeModeSupported = result.equals("1"); + } + return mDozeModeSupported; + } + + public static boolean isAppStandbySupported() { + if (mAppStandbySupported == null) { + mAppStandbySupported = AppStandbyUtils.isAppStandbyEnabled(); + } + return mAppStandbySupported; + } + + public static boolean isLowRamDevice() { + final ActivityManager am = (ActivityManager) getContext().getSystemService( + Context.ACTIVITY_SERVICE); + return am.isLowRamDevice(); + } + + public static boolean isActiveNetworkMetered(boolean metered) { + return getConnectivityManager().isActiveNetworkMetered() == metered; + } + + public static boolean canChangeActiveNetworkMeteredness() { + final Network activeNetwork = getConnectivityManager().getActiveNetwork(); + final NetworkCapabilities networkCapabilities + = getConnectivityManager().getNetworkCapabilities(activeNetwork); + return networkCapabilities.hasTransport(TRANSPORT_WIFI); + } + + public static Pair setupMeteredNetwork(boolean metered) throws Exception { + if (isActiveNetworkMetered(metered)) { + return null; + } + final String ssid = unquoteSSID(getWifiManager().getConnectionInfo().getSSID()); + setWifiMeteredStatus(ssid, metered); + return Pair.create(ssid, !metered); + } + + public static void resetMeteredNetwork(String ssid, boolean metered) throws Exception { + setWifiMeteredStatus(ssid, metered); + } + + public static void setWifiMeteredStatus(String ssid, boolean metered) throws Exception { + assertFalse("SSID should not be empty", TextUtils.isEmpty(ssid)); + final String cmd = "cmd netpolicy set metered-network " + ssid + " " + metered; + executeShellCommand(cmd); + assertWifiMeteredStatus(ssid, metered); + assertActiveNetworkMetered(metered); + } + + public static void assertWifiMeteredStatus(String ssid, boolean expectedMeteredStatus) { + final String result = executeShellCommand("cmd netpolicy list wifi-networks"); + final String expectedLine = ssid + ";" + expectedMeteredStatus; + assertTrue("Expected line: " + expectedLine + "; Actual result: " + result, + result.contains(expectedLine)); + } + + // Copied from cts/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java + public static void assertActiveNetworkMetered(boolean expectedMeteredStatus) throws Exception { + final CountDownLatch latch = new CountDownLatch(1); + final NetworkCallback networkCallback = new NetworkCallback() { + @Override + public void onCapabilitiesChanged(Network network, NetworkCapabilities nc) { + final boolean metered = !nc.hasCapability(NET_CAPABILITY_NOT_METERED); + if (metered == expectedMeteredStatus) { + latch.countDown(); + } + } + }; + // Registering a callback here guarantees onCapabilitiesChanged is called immediately + // with the current setting. Therefore, if the setting has already been changed, + // this method will return right away, and if not it will wait for the setting to change. + getConnectivityManager().registerDefaultNetworkCallback(networkCallback); + if (!latch.await(TIMEOUT_CHANGE_METEREDNESS_MS, TimeUnit.MILLISECONDS)) { + fail("Timed out waiting for active network metered status to change to " + + expectedMeteredStatus + " ; network = " + + getConnectivityManager().getActiveNetwork()); + } + getConnectivityManager().unregisterNetworkCallback(networkCallback); + } + + public static void setRestrictBackground(boolean enabled) { + executeShellCommand("cmd netpolicy set restrict-background " + enabled); + final String output = executeShellCommand("cmd netpolicy get restrict-background"); + final String expectedSuffix = enabled ? "enabled" : "disabled"; + assertTrue("output '" + output + "' should end with '" + expectedSuffix + "'", + output.endsWith(expectedSuffix)); + } + + public static boolean isMyRestrictBackgroundStatus(int expectedStatus) { + final int actualStatus = getConnectivityManager().getRestrictBackgroundStatus(); + if (expectedStatus != actualStatus) { + Log.d(TAG, "MyRestrictBackgroundStatus: " + + "Expected: " + restrictBackgroundValueToString(expectedStatus) + + "; Actual: " + restrictBackgroundValueToString(actualStatus)); + return false; + } + return true; + } + + // Copied from cts/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java + private static String unquoteSSID(String ssid) { + // SSID is returned surrounded by quotes if it can be decoded as UTF-8. + // Otherwise it's guaranteed not to start with a quote. + if (ssid.charAt(0) == '"') { + return ssid.substring(1, ssid.length() - 1); + } else { + return ssid; + } + } + + public static String restrictBackgroundValueToString(int status) { + switch (status) { + case RESTRICT_BACKGROUND_STATUS_DISABLED: + return "DISABLED"; + case RESTRICT_BACKGROUND_STATUS_WHITELISTED: + return "WHITELISTED"; + case RESTRICT_BACKGROUND_STATUS_ENABLED: + return "ENABLED"; + default: + return "UNKNOWN_STATUS_" + status; + } + } + + public static String executeShellCommand(String command) { + final String result = runShellCommand(command).trim(); + Log.d(TAG, "Output of '" + command + "': '" + result + "'"); + return result; + } + + public static void assertMyRestrictBackgroundStatus(int expectedStatus) { + final int actualStatus = getConnectivityManager().getRestrictBackgroundStatus(); + assertEquals(restrictBackgroundValueToString(expectedStatus), + restrictBackgroundValueToString(actualStatus)); + } + + public static ConnectivityManager getConnectivityManager() { + if (mCm == null) { + mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); + } + return mCm; + } + + public static WifiManager getWifiManager() { + if (mWm == null) { + mWm = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); + } + return mWm; + } + + public static Context getContext() { + return getInstrumentation().getContext(); + } + + public static Instrumentation getInstrumentation() { + return InstrumentationRegistry.getInstrumentation(); + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/Property.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/Property.java new file mode 100644 index 0000000000..18805f9613 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/Property.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.canChangeActiveNetworkMeteredness; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isActiveNetworkMetered; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isAppStandbySupported; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isBatterySaverSupported; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isDataSaverSupported; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isDozeModeSupported; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isLowRamDevice; + +public enum Property { + BATTERY_SAVER_MODE(1 << 0) { + public boolean isSupported() { return isBatterySaverSupported(); } + }, + + DATA_SAVER_MODE(1 << 1) { + public boolean isSupported() { return isDataSaverSupported(); } + }, + + NO_DATA_SAVER_MODE(~DATA_SAVER_MODE.getValue()) { + public boolean isSupported() { return !isDataSaverSupported(); } + }, + + DOZE_MODE(1 << 2) { + public boolean isSupported() { return isDozeModeSupported(); } + }, + + APP_STANDBY_MODE(1 << 3) { + public boolean isSupported() { return isAppStandbySupported(); } + }, + + NOT_LOW_RAM_DEVICE(1 << 4) { + public boolean isSupported() { return !isLowRamDevice(); } + }, + + METERED_NETWORK(1 << 5) { + public boolean isSupported() { + return isActiveNetworkMetered(true) || canChangeActiveNetworkMeteredness(); + } + }, + + NON_METERED_NETWORK(~METERED_NETWORK.getValue()) { + public boolean isSupported() { + return isActiveNetworkMetered(false) || canChangeActiveNetworkMeteredness(); + } + }; + + private int mValue; + + Property(int value) { mValue = value; } + + public int getValue() { return mValue; } + + abstract boolean isSupported(); +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredProperties.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredProperties.java new file mode 100644 index 0000000000..96838bba0a --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredProperties.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(RUNTIME) +@Target({METHOD, TYPE}) +@Inherited +public @interface RequiredProperties { + Property[] value(); +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java new file mode 100644 index 0000000000..1e333200db --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TAG; + +import android.text.TextUtils; +import android.util.ArraySet; +import android.util.Log; + +import com.android.compatibility.common.util.BeforeAfterRule; + +import org.junit.Assume; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import java.util.ArrayList; +import java.util.Collections; + +public class RequiredPropertiesRule extends BeforeAfterRule { + + private static ArraySet mRequiredProperties; + + @Override + public void onBefore(Statement base, Description description) { + mRequiredProperties = getAllRequiredProperties(description); + + final String testName = description.getClassName() + "#" + description.getMethodName(); + assertTestIsValid(testName, mRequiredProperties); + Log.i(TAG, "Running test " + testName + " with required properties: " + + propertiesToString(mRequiredProperties)); + } + + private ArraySet getAllRequiredProperties(Description description) { + final ArraySet allRequiredProperties = new ArraySet<>(); + RequiredProperties requiredProperties = description.getAnnotation(RequiredProperties.class); + if (requiredProperties != null) { + Collections.addAll(allRequiredProperties, requiredProperties.value()); + } + + for (Class clazz = description.getTestClass(); + clazz != null; clazz = clazz.getSuperclass()) { + requiredProperties = clazz.getDeclaredAnnotation(RequiredProperties.class); + if (requiredProperties == null) { + continue; + } + for (Property requiredProperty : requiredProperties.value()) { + if (!allRequiredProperties.contains(~requiredProperty.getValue())) { + allRequiredProperties.add(requiredProperty); + } + } + } + return allRequiredProperties; + } + + private void assertTestIsValid(String testName, ArraySet requiredProperies) { + if (requiredProperies == null) { + return; + } + final ArrayList unsupportedProperties = new ArrayList<>(); + for (Property property : requiredProperies) { + if (!property.isSupported()) { + unsupportedProperties.add(property); + } + } + Assume.assumeTrue("Unsupported properties: " + + propertiesToString(unsupportedProperties), unsupportedProperties.isEmpty()); + } + + public static ArraySet getRequiredProperties() { + return mRequiredProperties; + } + + private static String propertiesToString(Iterable properties) { + return "[" + TextUtils.join(",", properties) + "]"; + } +} diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java index 8d6c4acd7d..1312085478 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java @@ -29,14 +29,14 @@ public class HostsideNetworkCallbackTests extends HostsideNetworkTestCase { uninstallPackage(TEST_APP2_PKG, true); } - public void testOnBlockedStatusChanged_data_saver() throws Exception { + public void testOnBlockedStatusChanged_dataSaver() throws Exception { runDeviceTests(TEST_PKG, - TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_data_saver"); + TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_dataSaver"); } - public void testOnBlockedStatusChanged_power_saver() throws Exception { + public void testOnBlockedStatusChanged_powerSaver() throws Exception { runDeviceTests(TEST_PKG, - TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_power_saver"); + TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_powerSaver"); } } diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java index a2443b391a..ce203795f9 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java @@ -79,7 +79,8 @@ abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiRec protected void installPackage(String apk) throws FileNotFoundException, DeviceNotAvailableException { CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild); - assertNull(getDevice().installPackage(buildHelper.getTestFile(apk), false)); + assertNull(getDevice().installPackage(buildHelper.getTestFile(apk), + false /* reinstall */, true /* grantPermissions */)); } protected void uninstallPackage(String packageName, boolean shouldSucceed) From 6ee1049428b80f8813d31f5453200f379691d58d Mon Sep 17 00:00:00 2001 From: Erik Kline Date: Fri, 16 Aug 2019 19:51:54 -0700 Subject: [PATCH 0675/1109] Attempt "fix" the broken QUIC packet to be slightly less broken Bug: 139403355 Merged-In: I372c0730c9bd5329761b5a74b38e0f743bfd8230 (cherry picked from commit d6af2b5225249b178ee69dc5bac9b40c46f08d76) Change-Id: I2955a3f9e733a5e39813a26e4cd630f79ae144a0 --- tests/cts/net/jni/NativeMultinetworkJni.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/tests/cts/net/jni/NativeMultinetworkJni.cpp b/tests/cts/net/jni/NativeMultinetworkJni.cpp index a6b5e90b1d..5bd3013819 100644 --- a/tests/cts/net/jni/NativeMultinetworkJni.cpp +++ b/tests/cts/net/jni/NativeMultinetworkJni.cpp @@ -455,13 +455,17 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeo, sizeof(timeo)); // For reference see: - // https://tools.ietf.org/html/draft-tsvwg-quic-protocol-01#section-6.1 - uint8_t quic_packet[] = { - 0x0c, // public flags: 64bit conn ID, 8bit sequence number + // https://tools.ietf.org/html/draft-tsvwg-quic-protocol#section-6.1 + uint8_t quic_packet[1200] = { + 0x0d, // public flags: + // - version present (0x01), + // - 64bit connection ID (0x0c), + // - 1 byte packet number (0x00) 0, 0, 0, 0, 0, 0, 0, 0, // 64bit connection ID - 0x01, // sequence number + 0xaa, 0xda, 0xca, 0xaa, // reserved-space version number + 1, // 1 byte packet number 0x00, // private flags - 0x07, // type: regular frame type "PING" + 0x07, // PING frame (cuz why not) }; arc4random_buf(quic_packet + 1, 8); // random connection ID @@ -489,7 +493,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( i + 1, MAX_RETRIES, rcvd, errnum); } } - if (rcvd < sent) { + if (rcvd < 9) { ALOGD("QUIC UDP %s: sent=%zd but rcvd=%zd, errno=%d", kPort, sent, rcvd, errnum); if (rcvd <= 0) { ALOGD("Does this network block UDP port %s?", kPort); @@ -505,8 +509,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( return -EPROTO; } - // TODO: log, and compare to the IP address encoded in the - // response, since this should be a public reset packet. + // TODO: Replace this quick 'n' dirty test with proper QUIC-capable code. close(fd); return 0; From 2bf54f7c79110e2c063b9eb454749bf5d1ffdce3 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Tue, 20 Aug 2019 19:09:35 +0900 Subject: [PATCH 0676/1109] Attempt "fix" the broken QUIC packet to be slightly less broken Bug: 139403355 Signed-off-by: Erik Kline Merged-In: I9c938998b5e30f7d3994b410878b2af6a75f9b5a Test: in I9c938998b5e30f7d3994b410878b2af6a75f9b5a (cherry picked from commit 8ce68f1310fbd968b922d3faa5e64df702458178) Change-Id: If544089eb79801cad7660f3f419fa304387fc402 --- tests/cts/net/jni/NativeMultinetworkJni.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/tests/cts/net/jni/NativeMultinetworkJni.c b/tests/cts/net/jni/NativeMultinetworkJni.c index ad56b510c3..4531f822eb 100644 --- a/tests/cts/net/jni/NativeMultinetworkJni.c +++ b/tests/cts/net/jni/NativeMultinetworkJni.c @@ -177,13 +177,17 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeo, sizeof(timeo)); // For reference see: - // https://tools.ietf.org/html/draft-tsvwg-quic-protocol-01#section-6.1 - uint8_t quic_packet[] = { - 0x0c, // public flags: 64bit conn ID, 8bit sequence number + // https://tools.ietf.org/html/draft-tsvwg-quic-protocol#section-6.1 + uint8_t quic_packet[1200] = { + 0x0d, // public flags: + // - version present (0x01), + // - 64bit connection ID (0x0c), + // - 1 byte packet number (0x00) 0, 0, 0, 0, 0, 0, 0, 0, // 64bit connection ID - 0x01, // sequence number + 0xaa, 0xda, 0xca, 0xaa, // reserved-space version number + 1, // 1 byte packet number 0x00, // private flags - 0x07, // type: regular frame type "PING" + 0x07, // PING frame (cuz why not) }; arc4random_buf(quic_packet + 1, 8); // random connection ID @@ -211,7 +215,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( i + 1, MAX_RETRIES, rcvd, errnum); } } - if (rcvd < sent) { + if (rcvd < 9) { ALOGD("QUIC UDP %s: sent=%zd but rcvd=%zd, errno=%d", kPort, sent, rcvd, errnum); if (rcvd <= 0) { ALOGD("Does this network block UDP port %s?", kPort); @@ -227,8 +231,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( return -EPROTO; } - // TODO: log, and compare to the IP address encoded in the - // response, since this should be a public reset packet. + // TODO: Replace this quick 'n' dirty test with proper QUIC-capable code. close(fd); return 0; From d6f08f48e04caf9292dfbddce0ed3edd171df01a Mon Sep 17 00:00:00 2001 From: Remi NGUYEN VAN Date: Tue, 6 Aug 2019 13:02:28 +0900 Subject: [PATCH 0677/1109] Add test for WifiInfo#getFrequency() Add getFrequency() to WifiInfoTest (along with other missing getters), and test that it is consistent with ScanResult in ScanResultTest. Test: atest android.net.wifi.cts.ScanResultTest Fixes: b/138929469 Merged-In: I070b16661bc72a5c5035b0b227821b680d7d71ba Merged-In: Ie99011acbbe66e9088f73964fd0c39d640594011 (cherry picked from commit 9c97c58656a168568e2a7dd784bb9919ac4997c5) Change-Id: I83416c24c20c6774b2a66bf822419616f8cc5ab2 --- .../android/net/wifi/cts/ScanResultTest.java | 30 +++++++++++++++++++ .../android/net/wifi/cts/WifiInfoTest.java | 3 ++ 2 files changed, 33 insertions(+) diff --git a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java index ccf5fe2241..9bd1226f52 100644 --- a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java @@ -23,6 +23,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.wifi.ScanResult; +import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.WifiLock; import android.platform.test.annotations.AppModeFull; @@ -54,6 +55,8 @@ public class ScanResultTest extends AndroidTestCase { private static final int ENABLE_WAIT_MSEC = 10000; private static final int SCAN_WAIT_MSEC = 10000; private static final int SCAN_MAX_RETRY_COUNT = 6; + private static final int SCAN_FIND_BSSID_MAX_RETRY_COUNT = 5; + private static final long SCAN_FIND_BSSID_WAIT_MSEC = 5_000L; private IntentFilter mIntentFilter; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override @@ -200,4 +203,31 @@ public class ScanResultTest extends AndroidTestCase { } + public void testScanResultMatchesWifiInfo() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + + // This test case should run while connected to Wifi + final WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); + assertNotNull(wifiInfo); + + ScanResult currentNetwork = null; + for (int i = 0; i < SCAN_FIND_BSSID_MAX_RETRY_COUNT; i++) { + scanAndWait(); + final List scanResults = mWifiManager.getScanResults(); + currentNetwork = scanResults.stream().filter(r -> r.BSSID.equals(wifiInfo.getBSSID())) + .findAny().orElse(null); + + if (currentNetwork != null) { + break; + } + Thread.sleep(SCAN_FIND_BSSID_WAIT_MSEC); + } + assertNotNull("Current network not found in scan results", currentNetwork); + + assertEquals(wifiInfo.getWifiSsid(), currentNetwork.wifiSsid); + assertEquals(wifiInfo.getFrequency(), currentNetwork.frequency); + } } diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java index 5367722b36..9d9b2a3902 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java @@ -139,8 +139,11 @@ public class WifiInfoTest extends AndroidTestCase { } wifiInfo.getBSSID(); + wifiInfo.getFrequency(); wifiInfo.getIpAddress(); wifiInfo.getLinkSpeed(); + wifiInfo.getPasspointFqdn(); + wifiInfo.getPasspointProviderFriendlyName(); wifiInfo.getTxLinkSpeedMbps(); wifiInfo.getRxLinkSpeedMbps(); wifiInfo.getRssi(); From 22d49c06442c65759a8d9fc3409f40b14b0c293b Mon Sep 17 00:00:00 2001 From: Xin Li Date: Fri, 6 Sep 2019 10:33:42 -0700 Subject: [PATCH 0678/1109] Prepare for Android 10 Test Suite R2. --- tests/cts/net/Android.bp | 1 + tests/cts/net/jni/NativeMultinetworkJni.cpp | 19 +++++++----- tests/cts/net/native/dns/Android.bp | 3 +- .../android/net/wifi/cts/ScanResultTest.java | 30 +++++++++++++++++++ .../android/net/wifi/cts/WifiInfoTest.java | 3 ++ 5 files changed, 47 insertions(+), 9 deletions(-) diff --git a/tests/cts/net/Android.bp b/tests/cts/net/Android.bp index b6ea4afe80..b00455d9ef 100644 --- a/tests/cts/net/Android.bp +++ b/tests/cts/net/Android.bp @@ -60,6 +60,7 @@ android_test { "cts", "vts", "general-tests", + "mts", ], } diff --git a/tests/cts/net/jni/NativeMultinetworkJni.cpp b/tests/cts/net/jni/NativeMultinetworkJni.cpp index a6b5e90b1d..5bd3013819 100644 --- a/tests/cts/net/jni/NativeMultinetworkJni.cpp +++ b/tests/cts/net/jni/NativeMultinetworkJni.cpp @@ -455,13 +455,17 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeo, sizeof(timeo)); // For reference see: - // https://tools.ietf.org/html/draft-tsvwg-quic-protocol-01#section-6.1 - uint8_t quic_packet[] = { - 0x0c, // public flags: 64bit conn ID, 8bit sequence number + // https://tools.ietf.org/html/draft-tsvwg-quic-protocol#section-6.1 + uint8_t quic_packet[1200] = { + 0x0d, // public flags: + // - version present (0x01), + // - 64bit connection ID (0x0c), + // - 1 byte packet number (0x00) 0, 0, 0, 0, 0, 0, 0, 0, // 64bit connection ID - 0x01, // sequence number + 0xaa, 0xda, 0xca, 0xaa, // reserved-space version number + 1, // 1 byte packet number 0x00, // private flags - 0x07, // type: regular frame type "PING" + 0x07, // PING frame (cuz why not) }; arc4random_buf(quic_packet + 1, 8); // random connection ID @@ -489,7 +493,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( i + 1, MAX_RETRIES, rcvd, errnum); } } - if (rcvd < sent) { + if (rcvd < 9) { ALOGD("QUIC UDP %s: sent=%zd but rcvd=%zd, errno=%d", kPort, sent, rcvd, errnum); if (rcvd <= 0) { ALOGD("Does this network block UDP port %s?", kPort); @@ -505,8 +509,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( return -EPROTO; } - // TODO: log, and compare to the IP address encoded in the - // response, since this should be a public reset packet. + // TODO: Replace this quick 'n' dirty test with proper QUIC-capable code. close(fd); return 0; diff --git a/tests/cts/net/native/dns/Android.bp b/tests/cts/net/native/dns/Android.bp index 9fbc3fc83d..1704a2b8f4 100644 --- a/tests/cts/net/native/dns/Android.bp +++ b/tests/cts/net/native/dns/Android.bp @@ -35,5 +35,6 @@ cc_test { }, test_suites: [ "cts", + "mts", ], -} \ No newline at end of file +} diff --git a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java index ccf5fe2241..9bd1226f52 100644 --- a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java @@ -23,6 +23,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.wifi.ScanResult; +import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.WifiLock; import android.platform.test.annotations.AppModeFull; @@ -54,6 +55,8 @@ public class ScanResultTest extends AndroidTestCase { private static final int ENABLE_WAIT_MSEC = 10000; private static final int SCAN_WAIT_MSEC = 10000; private static final int SCAN_MAX_RETRY_COUNT = 6; + private static final int SCAN_FIND_BSSID_MAX_RETRY_COUNT = 5; + private static final long SCAN_FIND_BSSID_WAIT_MSEC = 5_000L; private IntentFilter mIntentFilter; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override @@ -200,4 +203,31 @@ public class ScanResultTest extends AndroidTestCase { } + public void testScanResultMatchesWifiInfo() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + + // This test case should run while connected to Wifi + final WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); + assertNotNull(wifiInfo); + + ScanResult currentNetwork = null; + for (int i = 0; i < SCAN_FIND_BSSID_MAX_RETRY_COUNT; i++) { + scanAndWait(); + final List scanResults = mWifiManager.getScanResults(); + currentNetwork = scanResults.stream().filter(r -> r.BSSID.equals(wifiInfo.getBSSID())) + .findAny().orElse(null); + + if (currentNetwork != null) { + break; + } + Thread.sleep(SCAN_FIND_BSSID_WAIT_MSEC); + } + assertNotNull("Current network not found in scan results", currentNetwork); + + assertEquals(wifiInfo.getWifiSsid(), currentNetwork.wifiSsid); + assertEquals(wifiInfo.getFrequency(), currentNetwork.frequency); + } } diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java index 5367722b36..9d9b2a3902 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java @@ -139,8 +139,11 @@ public class WifiInfoTest extends AndroidTestCase { } wifiInfo.getBSSID(); + wifiInfo.getFrequency(); wifiInfo.getIpAddress(); wifiInfo.getLinkSpeed(); + wifiInfo.getPasspointFqdn(); + wifiInfo.getPasspointProviderFriendlyName(); wifiInfo.getTxLinkSpeedMbps(); wifiInfo.getRxLinkSpeedMbps(); wifiInfo.getRssi(); From a261dcd8cd8c0aaaa8e5604e95bca8b4d85ecb02 Mon Sep 17 00:00:00 2001 From: Amit Mahajan Date: Thu, 12 Sep 2019 12:32:37 -0700 Subject: [PATCH 0679/1109] Use update constructor for AudioGroup. Test: basic sanity Bug: 140872785 Change-Id: Ie5bdca10cd80b4b7d0241f9b1b4afdebca8aeb04 --- tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java b/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java index 1bd7fadc8e..fee8621c70 100644 --- a/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java +++ b/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java @@ -62,7 +62,7 @@ public class AudioGroupTest extends AndroidTestCase { mSocketB.connect(mStreamB.getLocalAddress(), mStreamB.getLocalPort()); mStreamB.associate(mSocketB.getLocalAddress(), mSocketB.getLocalPort()); - mGroup = new AudioGroup(); + mGroup = new AudioGroup(mContext); } @Override From c9068f1b87d206acb91a28d94bfba5229809b330 Mon Sep 17 00:00:00 2001 From: Jeff Vander Stoep Date: Tue, 1 Oct 2019 15:49:42 +0200 Subject: [PATCH 0680/1109] getConnectionOwnerUid: add test for b/141603906 Test: on Marlin and Blueline run cts-tradefed run cts -m CtsHostsideNetworkTests \ -t com.android.cts.net.HostsideVpnTests#testB141603906 Bug: 141603906 Change-Id: I759bc2295b2060e4575d61718c551d201a6455be --- .../com/android/cts/net/hostside/VpnTest.java | 26 +++++++++++++++++++ .../com/android/cts/net/HostsideVpnTests.java | 4 +++ 2 files changed, 30 insertions(+) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java index 2fc85f6e3e..c43d4210ec 100755 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java @@ -897,6 +897,32 @@ public class VpnTest extends InstrumentationTestCase { assertTrue(mCM.isActiveNetworkMetered()); } + public void testB141603906() throws Exception { + final InetSocketAddress src = new InetSocketAddress(0); + final InetSocketAddress dst = new InetSocketAddress(0); + final int NUM_THREADS = 8; + final int NUM_SOCKETS = 5000; + final Thread[] threads = new Thread[NUM_THREADS]; + startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"}, + new String[] {"0.0.0.0/0", "::/0"}, + "", "", null, null /* underlyingNetworks */, false /* isAlwaysMetered */); + + for (int i = 0; i < NUM_THREADS; i++) { + threads[i] = new Thread(() -> { + for (int j = 0; j < NUM_SOCKETS; j++) { + mCM.getConnectionOwnerUid(IPPROTO_TCP, src, dst); + } + }); + } + for (Thread thread : threads) { + thread.start(); + } + for (Thread thread : threads) { + thread.join(); + } + stopVpn(); + } + private boolean isNetworkMetered(Network network) { NetworkCapabilities nc = mCM.getNetworkCapabilities(network); return !nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java index 6e37a24c68..62925ad6ab 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java @@ -91,4 +91,8 @@ public class HostsideVpnTests extends HostsideNetworkTestCase { TEST_PKG + ".VpnTest", "testAlwaysMeteredVpnWithNonNullUnderlyingNetwork"); } + + public void testB141603906() throws Exception { + runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testB141603906"); + } } From 1881bc644fe252d3b4c78fff9d7f8dd958e44f14 Mon Sep 17 00:00:00 2001 From: Kweku Adams Date: Tue, 8 Oct 2019 14:55:49 -0700 Subject: [PATCH 0681/1109] Change network parole while charging tests. The periodic parole window is the 10 minute window that occurs every 24 hours to let RARE apps run. Now that we have the quota system in place, there's no need to have the periodic parole window. Alarms and jobs will still be allowed to run when charging. Network will continue to be restricted for RARE apps even when charging. JobScheduler requests an exception for RARE jobs in quota, so they will still be able to run. With this change, idle apps should still not get network when charging unless JobScheduler requests it, so we have to update the tests. Bug: 136184981 Test: atest AppStandbyControllerTests Test: atest CtsAlarmManagerTestCases Test: atest com.android.cts.net.HostsideRestrictBackgroundNetworkTests Test: atest com.android.server.AlarmManagerServiceTest Test: atest com.android.server.AppStateTrackerTest Test: atest com.android.server.job.controllers.QuotaControllerTest Change-Id: Icd7b6eff8777f9b53a10eca521b73988f58f2d84 --- tests/cts/hostside/AndroidTest.xml | 2 - .../net/hostside/AbstractAppIdleTestCase.java | 4 +- ...ractRestrictBackgroundNetworkTestCase.java | 8 --- .../cts/net/NetPolicyTestsPreparer.java | 63 ------------------- 4 files changed, 2 insertions(+), 75 deletions(-) delete mode 100644 tests/cts/hostside/src/com/android/cts/net/NetPolicyTestsPreparer.java diff --git a/tests/cts/hostside/AndroidTest.xml b/tests/cts/hostside/AndroidTest.xml index 5479c51a4c..6ba6f42409 100644 --- a/tests/cts/hostside/AndroidTest.xml +++ b/tests/cts/hostside/AndroidTest.xml @@ -20,8 +20,6 @@

    * Test default value */ public void testGetMeteredOverride() throws Exception { @@ -58,7 +65,7 @@ public class WifiHotspot2Test extends AndroidTestCase { /** * Tests {@link PasspointConfiguration#getSubscriptionExpirationTimeMillis()} method. - * + *

    * Test default value */ public void testGetSubscriptionExpirationTimeMillis() throws Exception { @@ -73,7 +80,7 @@ public class WifiHotspot2Test extends AndroidTestCase { /** * Tests {@link PasspointConfiguration#getUniqueId()} method. - * + *

    * Test unique identifier is not null */ public void testGetUniqueId() throws Exception { @@ -81,13 +88,32 @@ public class WifiHotspot2Test extends AndroidTestCase { // skip the test if WiFi is not supported return; } - PasspointConfiguration passpointConfiguration = createConfig(); - assertNotNull(passpointConfiguration.getUniqueId()); + + // Create a configuration and make sure the unique ID is not null + PasspointConfiguration passpointConfiguration1 = createConfig(SIM_CREDENTIAL, "123456*", + 18 /* EAP_SIM */); + String uniqueId1 = passpointConfiguration1.getUniqueId(); + assertNotNull(uniqueId1); + + // Create another configuration and make sure the unique ID is not null + PasspointConfiguration passpointConfiguration2 = createConfig(SIM_CREDENTIAL, "567890*", + 23 /* EAP_AKA */); + String uniqueId2 = passpointConfiguration2.getUniqueId(); + assertNotNull(uniqueId2); + + // Make sure the IDs are not equal + assertFalse(uniqueId1.equals(uniqueId2)); + + passpointConfiguration2 = createConfig(USER_CREDENTIAL); + assertFalse(uniqueId1.equals(passpointConfiguration2.getUniqueId())); + + passpointConfiguration2 = createConfig(CERT_CREDENTIAL); + assertFalse(uniqueId1.equals(passpointConfiguration2.getUniqueId())); } /** * Tests {@link PasspointConfiguration#isAutojoinEnabled()} method. - * + *

    * Test default value */ public void testIsAutojoinEnabled() throws Exception { @@ -101,7 +127,7 @@ public class WifiHotspot2Test extends AndroidTestCase { /** * Tests {@link PasspointConfiguration#isMacRandomizationEnabled()} method. - * + *

    * Test default value */ public void testIsMacRandomizationEnabled() throws Exception { @@ -115,7 +141,7 @@ public class WifiHotspot2Test extends AndroidTestCase { /** * Tests {@link PasspointConfiguration#isOsuProvisioned()} method. - * + *

    * Test default value */ public void testIsOsuProvisioned() throws Exception { @@ -123,13 +149,13 @@ public class WifiHotspot2Test extends AndroidTestCase { // skip the test if WiFi is not supported return; } - PasspointConfiguration passpointConfiguration = createConfig(); + PasspointConfiguration passpointConfiguration = createConfig(USER_CREDENTIAL); assertFalse(passpointConfiguration.isOsuProvisioned()); } /** * Tests {@link PasspointConfiguration#PasspointConfiguration(PasspointConfiguration)} method. - * + *

    * Test the PasspointConfiguration copy constructor */ public void testPasspointConfigurationCopyConstructor() throws Exception { @@ -137,7 +163,7 @@ public class WifiHotspot2Test extends AndroidTestCase { // skip the test if WiFi is not supported return; } - PasspointConfiguration passpointConfiguration = createConfig(); + PasspointConfiguration passpointConfiguration = createConfig(USER_CREDENTIAL); PasspointConfiguration copyOfPasspointConfiguration = new PasspointConfiguration(passpointConfiguration); assertEquals(passpointConfiguration, copyOfPasspointConfiguration); @@ -145,7 +171,7 @@ public class WifiHotspot2Test extends AndroidTestCase { /** * Tests {@link HomeSp#HomeSp(HomeSp)} method. - * + *

    * Test the HomeSp copy constructor */ public void testHomeSpCopyConstructor() throws Exception { @@ -160,7 +186,7 @@ public class WifiHotspot2Test extends AndroidTestCase { /** * Tests {@link Credential#Credential(Credential)} method. - * + *

    * Test the Credential copy constructor */ public void testCredentialCopyConstructor() throws Exception { @@ -168,14 +194,14 @@ public class WifiHotspot2Test extends AndroidTestCase { // skip the test if WiFi is not supported return; } - Credential credential = createCredential(); + Credential credential = createCredentialWithSimCredential("123456*", 18 /* EAP_SIM */); Credential copyOfCredential = new Credential(credential); assertEquals(copyOfCredential, credential); } /** * Tests {@link Credential.UserCredential#UserCredential(Credential.UserCredential)} method. - * + *

    * Test the Credential.UserCredential copy constructor */ public void testUserCredentialCopyConstructor() throws Exception { @@ -195,9 +221,10 @@ public class WifiHotspot2Test extends AndroidTestCase { } /** - * Tests {@link Credential.CertificateCredential#CertificateCredential(Credential.CertificateCredential)} + * Tests + * {@link Credential.CertificateCredential#CertificateCredential(Credential.CertificateCredential)} * method. - * + *

    * Test the Credential.CertificateCredential copy constructor */ public void testCertCredentialCopyConstructor() throws Exception { @@ -214,9 +241,8 @@ public class WifiHotspot2Test extends AndroidTestCase { } /** - * Tests {@link Credential.SimCredential#SimCredential(Credential.SimCredential)} - * method. - * + * Tests {@link Credential.SimCredential#SimCredential(Credential.SimCredential)} method. + *

    * Test the Credential.SimCredential copy constructor */ public void testSimCredentialCopyConstructor() throws Exception { @@ -234,7 +260,7 @@ public class WifiHotspot2Test extends AndroidTestCase { /** * Tests {@link Credential#getCaCertificate()} method. - * + *

    * Test that getting a set certificate produces the same value */ public void testCredentialGetCertificate() throws Exception { @@ -249,9 +275,9 @@ public class WifiHotspot2Test extends AndroidTestCase { } /** - * Tests {@link Credential#getClientCertificateChain()} and - * {@link Credential#setCaCertificates(X509Certificate[])} methods. - * + * Tests {@link Credential#getClientCertificateChain()} and {@link + * Credential#setCaCertificates(X509Certificate[])} methods. + *

    * Test that getting a set client certificate chain produces the same value */ public void testCredentialClientCertificateChain() throws Exception { @@ -260,7 +286,7 @@ public class WifiHotspot2Test extends AndroidTestCase { return; } Credential credential = new Credential(); - X509Certificate[] certificates = new X509Certificate[] {FakeKeys.CLIENT_CERT}; + X509Certificate[] certificates = new X509Certificate[]{FakeKeys.CLIENT_CERT}; credential.setClientCertificateChain(certificates); assertTrue(Arrays.equals(certificates, credential.getClientCertificateChain())); @@ -268,8 +294,9 @@ public class WifiHotspot2Test extends AndroidTestCase { /** * Tests {@link Credential#getClientPrivateKey()} and - * {@link Credential#setClientPrivateKey(PrivateKey)} methods. - * + * {@link Credential#setClientPrivateKey(PrivateKey)} + * methods. + *

    * Test that getting a set client private key produces the same value */ public void testCredentialSetGetClientPrivateKey() throws Exception { @@ -285,8 +312,9 @@ public class WifiHotspot2Test extends AndroidTestCase { /** * Tests {@link Credential#getClientPrivateKey()} and - * {@link Credential#setClientPrivateKey(PrivateKey)} methods. - * + * {@link Credential#setClientPrivateKey(PrivateKey)} + * methods. + *

    * Test that getting a set client private key produces the same value */ public void testCredentialGetClientPrivateKey() throws Exception { @@ -300,32 +328,110 @@ public class WifiHotspot2Test extends AndroidTestCase { assertEquals(FakeKeys.RSA_KEY1, credential.getClientPrivateKey()); } - private static PasspointConfiguration createConfig() { + private static PasspointConfiguration createConfig(int type) throws Exception { + return createConfig(type, "123456*", 18 /* EAP_SIM */); + } + + private static PasspointConfiguration createConfig(int type, String imsi, int eapType) + throws Exception { PasspointConfiguration config = new PasspointConfiguration(); config.setHomeSp(createHomeSp()); - config.setCredential(createCredential()); + switch (type) { + default: + case SIM_CREDENTIAL: + config.setCredential( + createCredentialWithSimCredential(imsi, eapType)); + break; + case USER_CREDENTIAL: + config.setCredential(createCredentialWithUserCredential()); + break; + case CERT_CREDENTIAL: + config.setCredential(createCredentialWithCertificateCredential()); + break; + } + return config; } + /** + * Helper function for generating HomeSp for testing. + * + * @return {@link HomeSp} + */ private static HomeSp createHomeSp() { HomeSp homeSp = new HomeSp(); homeSp.setFqdn("test.com"); homeSp.setFriendlyName("friendly name"); - homeSp.setRoamingConsortiumOis(new long[] {0x55, 0x66}); + homeSp.setRoamingConsortiumOis(new long[]{0x55, 0x66}); return homeSp; } - private static Credential createCredential() { + /** + * Helper function for generating Credential for testing. + * + * @param userCred Instance of UserCredential + * @param certCred Instance of CertificateCredential + * @param simCred Instance of SimCredential + * @param clientCertificateChain Chain of client certificates + * @param clientPrivateKey Client private key + * @param caCerts CA certificates + * @return {@link Credential} + */ + private static Credential createCredential(Credential.UserCredential userCred, + Credential.CertificateCredential certCred, + Credential.SimCredential simCred, + X509Certificate[] clientCertificateChain, PrivateKey clientPrivateKey, + X509Certificate... caCerts) { Credential cred = new Credential(); cred.setRealm("realm"); - cred.setUserCredential(null); - cred.setCertCredential(null); - cred.setSimCredential(new Credential.SimCredential()); - cred.getSimCredential().setImsi("1234*"); - cred.getSimCredential().setEapType(18/* EAP_SIM */); - cred.setCaCertificate(null); - cred.setClientCertificateChain(null); - cred.setClientPrivateKey(null); + cred.setUserCredential(userCred); + cred.setCertCredential(certCred); + cred.setSimCredential(simCred); return cred; } + + /** + * Helper function for generating certificate credential for testing. + * + * @return {@link Credential} + */ + private static Credential createCredentialWithCertificateCredential() + throws NoSuchAlgorithmException, CertificateEncodingException { + Credential.CertificateCredential certCred = new Credential.CertificateCredential(); + certCred.setCertType("x509v3"); + certCred.setCertSha256Fingerprint( + MessageDigest.getInstance("SHA-256").digest( + FakeKeys.CLIENT_CERT.getEncoded())); + return createCredential(null, certCred, null, new X509Certificate[]{ + FakeKeys.CLIENT_CERT}, + FakeKeys.RSA_KEY1, FakeKeys.CA_CERT0, + FakeKeys.CA_CERT1); + } + + /** + * Helper function for generating SIM credential for testing. + * + * @return {@link Credential} + */ + private static Credential createCredentialWithSimCredential(String imsi, int eapType) { + Credential.SimCredential simCred = new Credential.SimCredential(); + simCred.setImsi(imsi); + simCred.setEapType(eapType); + return createCredential(null, null, simCred, null, null, (X509Certificate[]) null); + } + + /** + * Helper function for generating user credential for testing. + * + * @return {@link Credential} + */ + private static Credential createCredentialWithUserCredential() { + Credential.UserCredential userCred = new Credential.UserCredential(); + userCred.setUsername("username"); + userCred.setPassword("password"); + userCred.setEapType(21 /* EAP_TTLS */); + userCred.setNonEapInnerMethod("MS-CHAP"); + return createCredential(userCred, null, null, null, null, + FakeKeys.CA_CERT0); + } } From 7c4a11141d66990225026a4e4a41d26461bd1791 Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 13 Mar 2020 18:43:14 -0700 Subject: [PATCH 0777/1109] CTS: Test PnoSettings Bug: 150978920 Test: atest android.net.wifi.nl80211.cts Change-Id: Id8ec63178e67dac8ab3d5e90689c0a4139c17fc0 --- .../net/wifi/nl80211/cts/PnoSettingsTest.java | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 tests/cts/net/src/android/net/wifi/nl80211/cts/PnoSettingsTest.java diff --git a/tests/cts/net/src/android/net/wifi/nl80211/cts/PnoSettingsTest.java b/tests/cts/net/src/android/net/wifi/nl80211/cts/PnoSettingsTest.java new file mode 100644 index 0000000000..59f5d993a3 --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/nl80211/cts/PnoSettingsTest.java @@ -0,0 +1,124 @@ +/* + * 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.wifi.nl80211.cts; + +import static com.google.common.truth.Truth.assertThat; + +import static org.junit.Assume.assumeTrue; + +import android.content.Context; +import android.net.wifi.cts.WifiFeature; +import android.net.wifi.nl80211.PnoNetwork; +import android.net.wifi.nl80211.PnoSettings; +import android.os.Parcel; + +import androidx.test.filters.SmallTest; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Arrays; +import java.util.List; + +/** CTS tests for {@link PnoSettings}. */ +@SmallTest +@RunWith(AndroidJUnit4.class) +public class PnoSettingsTest { + + private static List createTestNetworks() { + PnoNetwork network1 = new PnoNetwork(); + network1.setSsid(new byte[] { 's', 's', 'i', 'd' }); + network1.setFrequenciesMhz(new int[] { 2412, 2417, 5035 }); + network1.setHidden(true); + + PnoNetwork network2 = new PnoNetwork(); + network2.setSsid(new byte[] { 'a', 's', 'd', 'f' }); + network2.setFrequenciesMhz(new int[] { 2422, 2427, 5040 }); + network2.setHidden(false); + + return Arrays.asList(network1, network2); + } + + @Before + public void setUp() { + Context context = InstrumentationRegistry.getInstrumentation().getContext(); + // skip tests if Wifi is not supported + assumeTrue(WifiFeature.isWifiSupported(context)); + } + + @Test + public void testGetters() { + PnoSettings settings = new PnoSettings(); + settings.setIntervalMillis(1000); + settings.setMin2gRssiDbm(-70); + settings.setMin5gRssiDbm(-60); + settings.setMin6gRssiDbm(-50); + settings.setPnoNetworks(createTestNetworks()); + + assertThat(settings.getIntervalMillis()).isEqualTo(1000); + assertThat(settings.getMin2gRssiDbm()).isEqualTo(-70); + assertThat(settings.getMin5gRssiDbm()).isEqualTo(-60); + assertThat(settings.getMin6gRssiDbm()).isEqualTo(-50); + assertThat(settings.getPnoNetworks()).isEqualTo(createTestNetworks()); + } + + @Test + public void canSerializeAndDeserialize() { + PnoSettings settings = new PnoSettings(); + settings.setIntervalMillis(1000); + settings.setMin2gRssiDbm(-70); + settings.setMin5gRssiDbm(-60); + settings.setMin6gRssiDbm(-50); + settings.setPnoNetworks(createTestNetworks()); + + Parcel parcel = Parcel.obtain(); + settings.writeToParcel(parcel, 0); + // Rewind the pointer to the head of the parcel. + parcel.setDataPosition(0); + PnoSettings settingsDeserialized = PnoSettings.CREATOR.createFromParcel(parcel); + + assertThat(settingsDeserialized.getIntervalMillis()).isEqualTo(1000); + assertThat(settingsDeserialized.getMin2gRssiDbm()).isEqualTo(-70); + assertThat(settingsDeserialized.getMin5gRssiDbm()).isEqualTo(-60); + assertThat(settingsDeserialized.getMin6gRssiDbm()).isEqualTo(-50); + assertThat(settingsDeserialized.getPnoNetworks()).isEqualTo(createTestNetworks()); + assertThat(settingsDeserialized).isEqualTo(settings); + assertThat(settingsDeserialized.hashCode()).isEqualTo(settings.hashCode()); + } + + @Test + public void testEquals() { + PnoSettings settings = new PnoSettings(); + settings.setIntervalMillis(1000); + settings.setMin2gRssiDbm(-70); + settings.setMin5gRssiDbm(-60); + settings.setMin6gRssiDbm(-50); + settings.setPnoNetworks(createTestNetworks()); + + PnoSettings settings2 = new PnoSettings(); + settings.setIntervalMillis(2000); + settings.setMin2gRssiDbm(-70); + settings.setMin5gRssiDbm(-60); + settings.setMin6gRssiDbm(-50); + settings.setPnoNetworks(createTestNetworks()); + + assertThat(settings2).isNotEqualTo(settings); + } +} From 205d45f2df300e4b5f3106d9cecc1ef9b47bfc47 Mon Sep 17 00:00:00 2001 From: David Su Date: Fri, 13 Mar 2020 19:12:19 -0700 Subject: [PATCH 0778/1109] CTS: Test WifiNl80211Manager.OemSecurityType Bug: 150979317 Test: atest android.net.wifi.nl80211.cts Change-Id: I1ad45223641e4e4b88be1fc8f5396b6b4f6abd61 --- .../nl80211/cts/WifiNl80211ManagerTest.java | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 tests/cts/net/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java diff --git a/tests/cts/net/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java b/tests/cts/net/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java new file mode 100644 index 0000000000..fa8447d2da --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java @@ -0,0 +1,67 @@ +/* + * 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.wifi.nl80211.cts; + +import static android.net.wifi.nl80211.WifiNl80211Manager.OemSecurityType; + +import static com.google.common.truth.Truth.assertThat; + +import static org.junit.Assume.assumeTrue; + +import android.content.Context; +import android.net.wifi.ScanResult; +import android.net.wifi.cts.WifiFeature; +import android.net.wifi.nl80211.WifiNl80211Manager; + +import androidx.test.filters.SmallTest; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Arrays; + +/** CTS tests for {@link WifiNl80211Manager}. */ +@SmallTest +@RunWith(AndroidJUnit4.class) +public class WifiNl80211ManagerTest { + + @Before + public void setUp() { + Context context = InstrumentationRegistry.getInstrumentation().getContext(); + // skip tests if Wifi is not supported + assumeTrue(WifiFeature.isWifiSupported(context)); + } + + @Test + public void testOemSecurityTypeConstructor() { + OemSecurityType securityType = new OemSecurityType( + ScanResult.PROTOCOL_WPA, + Arrays.asList(ScanResult.KEY_MGMT_PSK, ScanResult.KEY_MGMT_SAE), + Arrays.asList(ScanResult.CIPHER_NONE, ScanResult.CIPHER_TKIP), + ScanResult.CIPHER_CCMP); + + assertThat(securityType.protocol).isEqualTo(ScanResult.PROTOCOL_WPA); + assertThat(securityType.keyManagement) + .isEqualTo(Arrays.asList(ScanResult.KEY_MGMT_PSK, ScanResult.KEY_MGMT_SAE)); + assertThat(securityType.pairwiseCipher) + .isEqualTo(Arrays.asList(ScanResult.CIPHER_NONE, ScanResult.CIPHER_TKIP)); + assertThat(securityType.groupCipher).isEqualTo(ScanResult.CIPHER_CCMP); + } +} From 00e72f57df065f0873570c20e175bf0228564e4d Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Thu, 12 Mar 2020 17:06:36 -0700 Subject: [PATCH 0779/1109] Add tests for support of Wifi bands and standards This commit adds the CTS support for the following APIs: WifiManager#is5GHzBandSupported() WifiManager#is6GHzBandSupported() WifiManager#isWifiStandardSupported() Bug: 151372208 Test: atest android.net.wifi.cts.WifiManagerTest Change-Id: Id8ff303eba878db222e75bd514f7430efc754edb --- .../android/net/wifi/cts/WifiManagerTest.java | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 46d4e7f371..2e3f18811b 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -1809,4 +1809,135 @@ public class WifiManagerTest extends AndroidTestCase { } mWifiManager.isEnhancedOpenSupported(); } + + /** + * Test that {@link WifiManager#is5GHzBandSupported()} returns successfully in + * both WiFi enabled/disabled states. + * Note that the response depends on device support and hence both true/false + * are valid responses. + */ + public void testIs5GhzBandSupported() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + + // Check for 5GHz support with wifi enabled + setWifiEnabled(true); + PollingCheck.check( + "Wifi not enabled!", + 20000, + () -> mWifiManager.isWifiEnabled()); + boolean isSupportedEnabled = mWifiManager.is5GHzBandSupported(); + + // Check for 5GHz support with wifi disabled + setWifiEnabled(false); + PollingCheck.check( + "Wifi not disabled!", + 20000, + () -> !mWifiManager.isWifiEnabled()); + boolean isSupportedDisabled = mWifiManager.is5GHzBandSupported(); + + // If Support is true when WiFi is disable, then it has to be true when it is enabled. + // Note, the reverse is a valid case. + if (isSupportedDisabled) { + assertTrue(isSupportedEnabled); + } + } + + /** + * Test that {@link WifiManager#is6GHzBandSupported()} returns successfully in + * both Wifi enabled/disabled states. + * Note that the response depends on device support and hence both true/false + * are valid responses. + */ + public void testIs6GhzBandSupported() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + + // Check for 6GHz support with wifi enabled + setWifiEnabled(true); + PollingCheck.check( + "Wifi not enabled!", + 20000, + () -> mWifiManager.isWifiEnabled()); + boolean isSupportedEnabled = mWifiManager.is6GHzBandSupported(); + + // Check for 6GHz support with wifi disabled + setWifiEnabled(false); + PollingCheck.check( + "Wifi not disabled!", + 20000, + () -> !mWifiManager.isWifiEnabled()); + boolean isSupportedDisabled = mWifiManager.is6GHzBandSupported(); + + // If Support is true when WiFi is disable, then it has to be true when it is enabled. + // Note, the reverse is a valid case. + if (isSupportedDisabled) { + assertTrue(isSupportedEnabled); + } + } + + /** + * Test that {@link WifiManager#isWifiStandardSupported()} returns successfully in + * both Wifi enabled/disabled states. The test is to be performed on + * {@link WifiAnnotations}'s {@code WIFI_STANDARD_} + * Note that the response depends on device support and hence both true/false + * are valid responses. + */ + public void testIsWifiStandardsSupported() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + + // Check for WiFi standards support with wifi enabled + setWifiEnabled(true); + PollingCheck.check( + "Wifi not enabled!", + 20000, + () -> mWifiManager.isWifiEnabled()); + boolean isLegacySupportedEnabled = + mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_LEGACY); + boolean is11nSupporedEnabled = + mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11N); + boolean is11acSupportedEnabled = + mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AC); + boolean is11axSupportedEnabled = + mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AX); + + // Check for WiFi standards support with wifi disabled + setWifiEnabled(false); + PollingCheck.check( + "Wifi not disabled!", + 20000, + () -> !mWifiManager.isWifiEnabled()); + + boolean isLegacySupportedDisabled = + mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_LEGACY); + boolean is11nSupportedDisabled = + mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11N); + boolean is11acSupportedDisabled = + mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AC); + boolean is11axSupportedDisabled = + mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AX); + + if (isLegacySupportedDisabled) { + assertTrue(isLegacySupportedEnabled); + } + + if (is11nSupportedDisabled) { + assertTrue(is11nSupporedEnabled); + } + + if (is11acSupportedDisabled) { + assertTrue(is11acSupportedEnabled); + } + + if (is11axSupportedDisabled) { + assertTrue(is11axSupportedEnabled); + } + } } From 7f53eead8b34f59b588d3e5365fae24ef4143a55 Mon Sep 17 00:00:00 2001 From: lesl Date: Wed, 11 Mar 2020 19:30:49 +0800 Subject: [PATCH 0780/1109] cts: Add SoftAp API test in CTS Bug: 150307166 Bug: 150972516 Bug: 150972218 Bug: 150972206 Bug: 150969780 Bug: 150969541 Bug: 150969225 Bug: 150967334 Bug: 150643333 Test: atest android.net.wifi.cts.WifiManagerTest Change-Id: I10e19223b6370c6e149c48f43da45a64e235bccf --- .../android/net/wifi/cts/WifiManagerTest.java | 327 +++++++++++++++++- 1 file changed, 326 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index f4c20e3072..c8ace7c611 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -40,8 +40,12 @@ import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkRequest; +import android.net.TetheringManager; import android.net.wifi.ScanResult; +import android.net.wifi.SoftApCapability; import android.net.wifi.SoftApConfiguration; +import android.net.wifi.SoftApInfo; +import android.net.wifi.WifiClient; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; @@ -73,6 +77,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; +import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Objects; @@ -90,6 +95,7 @@ public class WifiManagerTest extends AndroidTestCase { private WifiManager mWifiManager; private ConnectivityManager mConnectivityManager; + private TetheringManager mTetheringManager; private WifiLock mWifiLock; private static MySync mMySync; private List mScanResults = null; @@ -97,6 +103,7 @@ public class WifiManagerTest extends AndroidTestCase { private final Object mLock = new Object(); private UiDevice mUiDevice; private boolean mWasVerboseLoggingEnabled; + private SoftApConfiguration mOriginalSoftApConfig = null; // Please refer to WifiManager private static final int MIN_RSSI = -100; @@ -199,7 +206,9 @@ public class WifiManagerTest extends AndroidTestCase { mContext.registerReceiver(mReceiver, mIntentFilter); mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); mConnectivityManager = getContext().getSystemService(ConnectivityManager.class); + mTetheringManager = getContext().getSystemService(TetheringManager.class); assertNotNull(mWifiManager); + assertNotNull(mTetheringManager); // turn on verbose logging for tests mWasVerboseLoggingEnabled = ShellIdentityUtils.invokeWithShellPermissions( @@ -222,6 +231,10 @@ public class WifiManagerTest extends AndroidTestCase { List savedNetworks = ShellIdentityUtils.invokeWithShellPermissions( mWifiManager::getConfiguredNetworks); assertFalse("Need at least one saved network", savedNetworks.isEmpty()); + + // Get original config for restore + mOriginalSoftApConfig = ShellIdentityUtils.invokeWithShellPermissions( + mWifiManager::getSoftApConfiguration); } @Override @@ -237,6 +250,9 @@ public class WifiManagerTest extends AndroidTestCase { mContext.unregisterReceiver(mReceiver); ShellIdentityUtils.invokeWithShellPermissions( () -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled)); + // restore original softap config + ShellIdentityUtils.invokeWithShellPermissions( + () -> mWifiManager.setSoftApConfiguration(mOriginalSoftApConfig)); Thread.sleep(DURATION); super.tearDown(); } @@ -506,6 +522,140 @@ public class WifiManagerTest extends AndroidTestCase { } } + public class TestSoftApCallback implements WifiManager.SoftApCallback { + Object softApLock; + int currentState; + int currentFailureReason; + List currentClientList; + SoftApInfo currentSoftApInfo; + SoftApCapability currentSoftApCapability; + MacAddress lastBlockedClientMacAddress; + int lastBlockedClientReason; + boolean onStateChangedCalled = false; + boolean onSoftapInfoChangedCalled = false; + boolean onSoftApCapabilityChangedCalled = false; + boolean onConnectedClientCalled = false; + boolean onBlockedClientConnectingCalled = false; + + TestSoftApCallback(Object lock) { + softApLock = lock; + } + + public boolean getOnStateChangedCalled() { + synchronized(softApLock) { + return onStateChangedCalled; + } + } + + public boolean getOnSoftapInfoChangedCalled() { + synchronized(softApLock) { + return onSoftapInfoChangedCalled; + } + } + + public boolean getOnSoftApCapabilityChangedCalled() { + synchronized(softApLock) { + return onSoftApCapabilityChangedCalled; + } + } + + public boolean getOnConnectedClientCalled() { + synchronized(softApLock) { + return onConnectedClientCalled; + } + } + + public boolean getOnBlockedClientConnectingCalled() { + synchronized(softApLock) { + return onBlockedClientConnectingCalled; + } + } + + public int getCurrentState() { + synchronized(softApLock) { + return currentState; + } + } + + public int getCurrentStateFailureReason() { + synchronized(softApLock) { + return currentFailureReason; + } + } + + public List getCurrentClientList() { + synchronized(softApLock) { + return currentClientList; + } + } + + public SoftApInfo getCurrentSoftApInfo() { + synchronized(softApLock) { + return currentSoftApInfo; + } + } + + public SoftApCapability getCurrentSoftApCapability() { + synchronized(softApLock) { + return currentSoftApCapability; + } + } + + public MacAddress getLastBlockedClientMacAddress() { + synchronized(softApLock) { + return lastBlockedClientMacAddress; + } + } + + public int getLastBlockedClientReason() { + synchronized(softApLock) { + return lastBlockedClientReason; + } + } + + @Override + public void onStateChanged(int state, int failureReason) { + synchronized(softApLock) { + currentState = state; + currentFailureReason = failureReason; + onStateChangedCalled = true; + } + } + + @Override + public void onConnectedClientsChanged(List clients) { + synchronized(softApLock) { + currentClientList = new ArrayList<>(clients); + onConnectedClientCalled = true; + } + } + + @Override + public void onInfoChanged(SoftApInfo softApInfo) { + synchronized(softApLock) { + currentSoftApInfo = softApInfo; + onSoftapInfoChangedCalled = true; + } + } + + @Override + public void onCapabilityChanged(SoftApCapability softApCapability) { + synchronized(softApLock) { + currentSoftApCapability = softApCapability; + onSoftApCapabilityChangedCalled = true; + } + } + + @Override + public void onBlockedClientConnecting(WifiClient client, int blockedReason) { + synchronized(softApLock) { + lastBlockedClientMacAddress = client.getMacAddress(); + lastBlockedClientReason = blockedReason; + onBlockedClientConnectingCalled = true; + } + } + } + private static class TestLocalOnlyHotspotCallback extends WifiManager.LocalOnlyHotspotCallback { Object hotspotLock; WifiManager.LocalOnlyHotspotReservation reservation = null; @@ -561,7 +711,10 @@ public class WifiManagerTest extends AndroidTestCase { } // check if we got the callback assertTrue(callback.onStartedCalled); - assertNotNull(callback.reservation.getSoftApConfiguration()); + + SoftApConfiguration softApConfig = callback.reservation.getSoftApConfiguration(); + assertNotNull(softApConfig); + assertNotNull(softApConfig.toWifiConfiguration()); if (!hasAutomotiveFeature()) { assertEquals( SoftApConfiguration.BAND_2GHZ, @@ -1141,6 +1294,178 @@ public class WifiManagerTest extends AndroidTestCase { > ENFORCED_NUM_NETWORK_SUGGESTIONS_PER_APP); } + private void verifyRegisterSoftApCallback(TestExecutor executor, TestSoftApCallback callback) + throws Exception{ + // Register callback to get SoftApCapability + mWifiManager.registerSoftApCallback(executor, callback); + PollingCheck.check( + "SoftAp register failed!", 1_000, + () -> { executor.runAll(); + // Verify callback is run on the supplied executor and called + return callback.getOnStateChangedCalled() && + callback.getOnSoftapInfoChangedCalled() && + callback.getOnSoftApCapabilityChangedCalled() && + callback.getOnConnectedClientCalled(); + }); + } + + private void verifySetGetSoftApConfig(SoftApConfiguration targetConfig) { + mWifiManager.setSoftApConfiguration(targetConfig); + // Bssid set dodesn't support for tethered hotspot + SoftApConfiguration currentConfig = mWifiManager.getSoftApConfiguration(); + assertNull(currentConfig.getBssid()); + compareSoftApConfiguration(targetConfig, currentConfig); + } + + private void compareSoftApConfiguration(SoftApConfiguration currentConfig, + SoftApConfiguration testSoftApConfig) { + assertEquals(currentConfig.getSsid(), testSoftApConfig.getSsid()); + assertEquals(currentConfig.getSecurityType(), testSoftApConfig.getSecurityType()); + assertEquals(currentConfig.getPassphrase(), testSoftApConfig.getPassphrase()); + assertEquals(currentConfig.isHiddenSsid(), testSoftApConfig.isHiddenSsid()); + assertEquals(currentConfig.getBand(), testSoftApConfig.getBand()); + assertEquals(currentConfig.getChannel(), testSoftApConfig.getChannel()); + assertEquals(currentConfig.getMaxNumberOfClients(), + testSoftApConfig.getMaxNumberOfClients()); + assertEquals(currentConfig.isAutoShutdownEnabled(), + testSoftApConfig.isAutoShutdownEnabled()); + assertEquals(currentConfig.getShutdownTimeoutMillis(), + testSoftApConfig.getShutdownTimeoutMillis()); + assertEquals(currentConfig.isClientControlByUserEnabled(), + testSoftApConfig.isClientControlByUserEnabled()); + assertEquals(currentConfig.getAllowedClientList(), + testSoftApConfig.getAllowedClientList()); + assertEquals(currentConfig.getBlockedClientList(), + testSoftApConfig.getBlockedClientList()); + } + + private void turnOffWifiAndTetheredHotspotIfEnabled() throws Exception { + if (mWifiManager.isWifiEnabled()) { + Log.d(TAG, "Turn off WiFi"); + mWifiManager.setWifiEnabled(false); + PollingCheck.check( + "Wifi turn off failed!", 2_000, + () -> mWifiManager.isWifiEnabled() == false); + } + if (mWifiManager.isWifiApEnabled()) { + mTetheringManager.stopTethering(ConnectivityManager.TETHERING_WIFI); + Log.d(TAG, "Turn off tethered Hotspot"); + PollingCheck.check( + "SoftAp turn off failed!", 2_000, + () -> mWifiManager.isWifiApEnabled() == false); + mTetheringManager.stopTethering(ConnectivityManager.TETHERING_WIFI); + } + } + + /** + * Verify that the configuration from getSoftApConfiguration is same as the configuration which + * set by setSoftApConfiguration. And depends softap capability callback to test different + * configuration. + * @throws Exception + */ + public void testSetGetSoftApConfigurationAndSoftApCapabilityCallback() throws Exception { + UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); + try { + uiAutomation.adoptShellPermissionIdentity(); + turnOffWifiAndTetheredHotspotIfEnabled(); + TestExecutor executor = new TestExecutor(); + TestSoftApCallback callback = new TestSoftApCallback(mLock); + verifyRegisterSoftApCallback(executor, callback); + + SoftApConfiguration.Builder softApConfigBuilder = new SoftApConfiguration.Builder() + .setSsid(TEST_SSID_UNQUOTED) + .setBssid(TEST_MAC) + .setPassphrase(TEST_PASSPHRASE, SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) + .setAutoShutdownEnabled(true) + .setShutdownTimeoutMillis(100000) + .setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ) + .setHiddenSsid(false); + + // Test SoftApConfiguration set and get + verifySetGetSoftApConfig(softApConfigBuilder.build()); + + // Test CLIENT_FORCE_DISCONNECT supported config. + if (callback.getCurrentSoftApCapability() + .areFeaturesSupported( + SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT)) { + softApConfigBuilder.setMaxNumberOfClients(10); + softApConfigBuilder.setClientControlByUserEnabled(true); + softApConfigBuilder.setBlockedClientList(new ArrayList<>()); + softApConfigBuilder.setAllowedClientList(new ArrayList<>()); + verifySetGetSoftApConfig(softApConfigBuilder.build()); + } + + // Test SAE config + if (callback.getCurrentSoftApCapability() + .areFeaturesSupported(SoftApCapability.SOFTAP_FEATURE_WPA3_SAE)) { + softApConfigBuilder + .setPassphrase(TEST_PASSPHRASE, + SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION); + verifySetGetSoftApConfig(softApConfigBuilder.build()); + softApConfigBuilder + .setPassphrase(TEST_PASSPHRASE, + SoftApConfiguration.SECURITY_TYPE_WPA3_SAE); + verifySetGetSoftApConfig(softApConfigBuilder.build()); + } + } finally { + uiAutomation.dropShellPermissionIdentity(); + } + } + + /** + * Verify that startTetheredHotspot with specific channel config. + * @throws Exception + */ + public void testStartTetheredHotspotWithChannelConfigAndSoftApStateAndInfoCallback() + throws Exception { + UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); + try { + uiAutomation.adoptShellPermissionIdentity(); + turnOffWifiAndTetheredHotspotIfEnabled(); + TestExecutor executor = new TestExecutor(); + TestSoftApCallback callback = new TestSoftApCallback(mLock); + verifyRegisterSoftApCallback(executor, callback); + + SoftApConfiguration testSoftApConfig = new SoftApConfiguration.Builder() + .setSsid(TEST_SSID_UNQUOTED) + .setPassphrase(TEST_PASSPHRASE, SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) + .setChannel(11, SoftApConfiguration.BAND_2GHZ) // Channel 11 = Freq 2462 + .build(); + + mWifiManager.setSoftApConfiguration(testSoftApConfig); + + // start tethering which used to verify startTetheredHotspot + mTetheringManager.startTethering(ConnectivityManager.TETHERING_WIFI, executor, + new TetheringManager.StartTetheringCallback() { + @Override + public void onTetheringFailed(final int result) { + } + }); + + // Verify state and info callback value as expected + PollingCheck.check( + "SoftAp channel and state mismatch!!!", 5_000, + () -> { executor.runAll(); + return WifiManager.WIFI_AP_STATE_ENABLED == callback.getCurrentState() && + 2462 == callback.getCurrentSoftApInfo().getFrequency(); + }); + + // stop tethering which used to verify stopSoftAp + mTetheringManager.stopTethering(ConnectivityManager.TETHERING_WIFI); + + // Verify clean up + PollingCheck.check( + "Stop Softap failed", 2_000, + () -> { executor.runAll(); + return WifiManager.WIFI_AP_STATE_DISABLED == callback.getCurrentState() && + 0 == callback.getCurrentSoftApInfo().getBandwidth() && + 0 == callback.getCurrentSoftApInfo().getFrequency(); + }); + } finally { + uiAutomation.dropShellPermissionIdentity(); + } + } + private static class TestActionListener implements WifiManager.ActionListener { private final Object mLock; public boolean onSuccessCalled = false; From 768315232018eb96fa225cc3858fbc1404b01bfa Mon Sep 17 00:00:00 2001 From: Automerger Merge Worker Date: Fri, 13 Mar 2020 07:13:45 +0000 Subject: [PATCH 0781/1109] Add IpConfigurationTest for new @SystemApi Add new cts for @SystemApi in IpConfiguration. Bug: 139268426 Bug: 135998869 Test: atest android.net.cts.IpConfigurationTest Change-Id: I942791abbdccc10d0e2a0018339a2ee4f74c7645 Merged-In: I942791abbdccc10d0e2a0018339a2ee4f74c7645 (cherry picked from aosp/1171795) --- .../android/net/cts/IpConfigurationTest.java | 151 ++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 tests/cts/net/src/android/net/cts/IpConfigurationTest.java diff --git a/tests/cts/net/src/android/net/cts/IpConfigurationTest.java b/tests/cts/net/src/android/net/cts/IpConfigurationTest.java new file mode 100644 index 0000000000..21be35142d --- /dev/null +++ b/tests/cts/net/src/android/net/cts/IpConfigurationTest.java @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2019 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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import android.net.IpConfiguration; +import android.net.LinkAddress; +import android.net.ProxyInfo; +import android.net.StaticIpConfiguration; + +import androidx.test.runner.AndroidJUnit4; + +import libcore.net.InetAddressUtils; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.net.InetAddress; +import java.util.ArrayList; + +@RunWith(AndroidJUnit4.class) +public final class IpConfigurationTest { + private static final int TYPE_IPASSIGNMENT_STATIC = 0; + private static final int TYPE_IPASSIGNMENT_DHCP = 1; + + private static final int TYPE_PROXY_SETTINGS_NONE = 0; + private static final int TYPE_PROXY_SETTINGS_STATIC = 1; + private static final int TYPE_PROXY_SETTINGS_PAC = 2; + + private static final LinkAddress LINKADDR = new LinkAddress("192.0.2.2/25"); + private static final InetAddress GATEWAY = InetAddressUtils.parseNumericAddress("192.0.2.1"); + private static final InetAddress DNS1 = InetAddressUtils.parseNumericAddress("8.8.8.8"); + private static final InetAddress DNS2 = InetAddressUtils.parseNumericAddress("8.8.4.4"); + private static final String DOMAINS = "example.com"; + + private static final ArrayList dnsServers = new ArrayList<>(); + + private StaticIpConfiguration mStaticIpConfig; + private ProxyInfo mProxy; + + @Before + public void setUp() { + dnsServers.add(DNS1); + dnsServers.add(DNS2); + mStaticIpConfig = new StaticIpConfiguration.Builder() + .setIpAddress(LINKADDR) + .setGateway(GATEWAY) + .setDnsServers(dnsServers) + .setDomains(DOMAINS) + .build(); + + mProxy = ProxyInfo.buildDirectProxy("test", 8888); + } + + @Test + public void testConstructor() { + IpConfiguration ipConfig = new IpConfiguration(); + checkEmpty(ipConfig); + assertIpConfigurationEqual(ipConfig, new IpConfiguration()); + assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig)); + + ipConfig = createIpConfiguration(TYPE_IPASSIGNMENT_STATIC, + TYPE_PROXY_SETTINGS_PAC); + assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig)); + + ipConfig = createIpConfiguration(TYPE_IPASSIGNMENT_STATIC, + TYPE_PROXY_SETTINGS_STATIC); + assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig)); + + ipConfig = createIpConfiguration(TYPE_IPASSIGNMENT_DHCP, + TYPE_PROXY_SETTINGS_PAC); + assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig)); + + ipConfig = createIpConfiguration(TYPE_IPASSIGNMENT_DHCP, + TYPE_PROXY_SETTINGS_STATIC); + assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig)); + + ipConfig = createIpConfiguration(TYPE_IPASSIGNMENT_DHCP, + TYPE_PROXY_SETTINGS_NONE); + assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig)); + } + + private void checkEmpty(IpConfiguration config) { + assertEquals(IpConfiguration.IpAssignment.UNASSIGNED, + config.getIpAssignment().UNASSIGNED); + assertEquals(IpConfiguration.ProxySettings.UNASSIGNED, + config.getProxySettings().UNASSIGNED); + assertNull(config.getStaticIpConfiguration()); + assertNull(config.getHttpProxy()); + } + + private IpConfiguration createIpConfiguration(int ipAssignmentType, + int proxySettingType) { + + final IpConfiguration ipConfig = new IpConfiguration(); + + switch (ipAssignmentType) { + case TYPE_IPASSIGNMENT_STATIC: + ipConfig.setIpAssignment(IpConfiguration.IpAssignment.STATIC); + break; + case TYPE_IPASSIGNMENT_DHCP: + ipConfig.setIpAssignment(IpConfiguration.IpAssignment.DHCP); + break; + default: + throw new IllegalArgumentException("Unknown ip assignment type."); + } + + switch (proxySettingType) { + case TYPE_PROXY_SETTINGS_NONE: + ipConfig.setProxySettings(IpConfiguration.ProxySettings.NONE); + break; + case TYPE_PROXY_SETTINGS_STATIC: + ipConfig.setProxySettings(IpConfiguration.ProxySettings.STATIC); + break; + case TYPE_PROXY_SETTINGS_PAC: + ipConfig.setProxySettings(IpConfiguration.ProxySettings.PAC); + break; + default: + throw new IllegalArgumentException("Unknown proxy setting type."); + } + + ipConfig.setStaticIpConfiguration(mStaticIpConfig); + ipConfig.setHttpProxy(mProxy); + + return ipConfig; + } + + private void assertIpConfigurationEqual(IpConfiguration source, IpConfiguration target) { + assertEquals(source.getIpAssignment(), target.getIpAssignment()); + assertEquals(source.getProxySettings(), target.getProxySettings()); + assertEquals(source.getHttpProxy(), target.getHttpProxy()); + assertEquals(source.getStaticIpConfiguration(), target.getStaticIpConfiguration()); + } +} From d40827d1bef331fada15359c105501ca65133d9d Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Mon, 16 Mar 2020 07:35:50 -0700 Subject: [PATCH 0782/1109] [CTS] Add test for WifiManager#addOrUpdatePasspointConfiguration Bug: 151613705 Test: atest WifiManagerTest Change-Id: I5f2537c501b065006d3a2f56cf671382e20cd737 --- .../android/net/wifi/cts/WifiManagerTest.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 2e3f18811b..5db348fd7d 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -49,6 +49,8 @@ import android.net.wifi.WifiManager.WifiLock; import android.net.wifi.WifiNetworkConnectionStatistics; import android.net.wifi.hotspot2.ConfigParser; import android.net.wifi.hotspot2.PasspointConfiguration; +import android.net.wifi.hotspot2.pps.Credential; +import android.net.wifi.hotspot2.pps.HomeSp; import android.os.Process; import android.os.SystemClock; import android.os.UserHandle; @@ -1940,4 +1942,46 @@ public class WifiManagerTest extends AndroidTestCase { assertTrue(is11axSupportedEnabled); } } + + private static PasspointConfiguration createPasspointConfiguration() { + PasspointConfiguration config = new PasspointConfiguration(); + HomeSp homeSp = new HomeSp(); + homeSp.setFqdn("test.com"); + homeSp.setFriendlyName("friendly name"); + homeSp.setRoamingConsortiumOis(new long[]{0x55, 0x66}); + config.setHomeSp(homeSp); + Credential.SimCredential simCred = new Credential.SimCredential(); + simCred.setImsi("123456*"); + simCred.setEapType(23 /* EAP_AKA */); + Credential cred = new Credential(); + cred.setRealm("realm"); + cred.setSimCredential(simCred); + config.setCredential(cred); + + return config; + } + + /** + * Tests {@link WifiManager#addOrUpdatePasspointConfiguration(PasspointConfiguration)} + * adds a Passpoint configuration correctly by getting it once it is added, and comparing it + * to the local copy of the configuration. + */ + public void testAddOrUpdatePasspointConfiguration() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + + // Create and install a Passpoint configuration + PasspointConfiguration passpointConfiguration = createPasspointConfiguration(); + mWifiManager.addOrUpdatePasspointConfiguration(passpointConfiguration); + + // Compare configurations + List configurations = mWifiManager.getPasspointConfigurations(); + assertNotNull(configurations); + assertEquals(passpointConfiguration, configurations.get(0)); + + // Clean up + mWifiManager.removePasspointConfiguration(passpointConfiguration.getHomeSp().getFqdn()); + } } From fbe50c723af71beeebefcf4bcc79ad5d554c73db Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Mon, 16 Mar 2020 09:59:47 -0700 Subject: [PATCH 0783/1109] WifiNetworkSpecifierTest: Add tests for enterprise builder methods Bug: 150236894 Test: atest android.net.wifi.cts Change-Id: Ie902dfa2c0fb83505c0b570b77462fcdf4c4ecaf --- .../wifi/cts/WifiNetworkSpecifierTest.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java index 96cf45ff1f..2065bb025c 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java @@ -31,6 +31,7 @@ import android.net.NetworkCapabilities; import android.net.NetworkRequest; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiEnterpriseConfig; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.NetworkRequestMatchCallback; @@ -506,4 +507,44 @@ public class WifiNetworkSpecifierTest extends AndroidTestCase { .build(); testUserRejectionWithSpecifier(specifier); } + + /** + * Tests the builder for WPA2 enterprise networks. + * Note: Can't do end to end tests for such networks in CTS environment. + */ + public void testBuilderForWpa2Enterprise() { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + WifiNetworkSpecifier specifier1 = new WifiNetworkSpecifier.Builder() + .setSsid(WifiInfo.sanitizeSsid(mTestNetwork.SSID)) + .setWpa2EnterpriseConfig(new WifiEnterpriseConfig()) + .build(); + WifiNetworkSpecifier specifier2 = new WifiNetworkSpecifier.Builder() + .setSsid(WifiInfo.sanitizeSsid(mTestNetwork.SSID)) + .setWpa2EnterpriseConfig(new WifiEnterpriseConfig()) + .build(); + assertThat(specifier1.satisfiedBy(specifier2)).isTrue(); + } + + /** + * Tests the builder for WPA3 enterprise networks. + * Note: Can't do end to end tests for such networks in CTS environment. + */ + public void testBuilderForWpa3Enterprise() { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + WifiNetworkSpecifier specifier1 = new WifiNetworkSpecifier.Builder() + .setSsid(WifiInfo.sanitizeSsid(mTestNetwork.SSID)) + .setWpa3EnterpriseConfig(new WifiEnterpriseConfig()) + .build(); + WifiNetworkSpecifier specifier2 = new WifiNetworkSpecifier.Builder() + .setSsid(WifiInfo.sanitizeSsid(mTestNetwork.SSID)) + .setWpa3EnterpriseConfig(new WifiEnterpriseConfig()) + .build(); + assertThat(specifier1.satisfiedBy(specifier2)).isTrue(); + } } From 96f9efcb759894a454120436ecdcd7645bce10a4 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Mon, 16 Mar 2020 10:05:54 -0700 Subject: [PATCH 0784/1109] WifiNetworkSuggestionTest: Add test for WAPI builder method Bug: 150236894 Test: atest android.net.wifi.cts Change-Id: I294f309ec972c24dfe83d9c40fd33fb591398872 --- .../wifi/cts/WifiNetworkSuggestionTest.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java index 994b6c907a..e73abb8b54 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java @@ -17,6 +17,7 @@ package android.net.wifi.cts; import static android.net.wifi.WifiEnterpriseConfig.Eap.AKA; +import static android.net.wifi.WifiEnterpriseConfig.Eap.WAPI_CERT; import android.net.MacAddress; import android.net.wifi.WifiEnterpriseConfig; @@ -198,6 +199,28 @@ public class WifiNetworkSuggestionTest extends AndroidTestCase { assertNull(suggestion.getPasspointConfig()); } + /** + * Tests {@link android.net.wifi.WifiNetworkSuggestion.Builder} class. + */ + public void testBuilderWithWapiEnterprise() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); + enterpriseConfig.setEapMethod(WAPI_CERT); + WifiNetworkSuggestion suggestion = + createBuilderWithCommonParams() + .setWapiEnterpriseConfig(enterpriseConfig) + .build(); + validateCommonParams(suggestion); + assertNull(suggestion.getPassphrase()); + assertNotNull(suggestion.getEnterpriseConfig()); + assertEquals(enterpriseConfig.getEapMethod(), + suggestion.getEnterpriseConfig().getEapMethod()); + assertNull(suggestion.getPasspointConfig()); + } + /** * Helper function for creating a {@link PasspointConfiguration} for testing. * From 90d49fbc579f2f769551d91bbae99a540d57a6c6 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Mon, 16 Mar 2020 11:08:14 -0700 Subject: [PATCH 0785/1109] WifiManagerTest: Add test for isTdls & isStaApConcurrency supported Bug: 150236894 Test: atest android.net.wifi.cts Change-Id: Id532a189b0d3e6848408e7a798acda13669ffb52 --- .../android/net/wifi/cts/WifiManagerTest.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 46d4e7f371..2368d1be0a 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -1472,6 +1472,45 @@ public class WifiManagerTest extends AndroidTestCase { mWifiManager.isPreferredNetworkOffloadSupported(); } + /** + * Tests {@link WifiManager#isTdlsSupported()} does not crash. + */ + public void testIsTdlsSupported() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + mWifiManager.isTdlsSupported(); + } + + /** + * Tests {@link WifiManager#isStaApConcurrencySupported(). + */ + public void testIsStaApConcurrencySupported() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + // check that softap mode is supported by the device + if (!mWifiManager.isPortableHotspotSupported()) { + return; + } + assertTrue(mWifiManager.isWifiEnabled()); + + boolean isStaApConcurrencySupported = mWifiManager.isStaApConcurrencySupported(); + // start local only hotspot. + TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot(); + if (isStaApConcurrencySupported) { + assertTrue(mWifiManager.isWifiEnabled()); + } else { + // no concurrency, wifi should be disabled. + assertFalse(mWifiManager.isWifiEnabled()); + } + stopLocalOnlyHotspot(callback, true); + + assertTrue(mWifiManager.isWifiEnabled()); + } + private static class TestTrafficStateCallback implements WifiManager.TrafficStateCallback { private final Object mLock; public boolean onStateChangedCalled = false; From 74ab41b1cdfde999332a7ff79bec531dfb211208 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Mon, 16 Mar 2020 14:07:35 -0700 Subject: [PATCH 0786/1109] WifiMigrationTest: Remove all usage of WifiMigration.loadFromStore In preparation of moving away from this API surface to a different mechanism. Bug: 149418926 Test: atest android.net.wifi.cts Change-Id: I5805d9dc27a248b633d514356f603f63af799429 --- .../net/wifi/cts/WifiMigrationTest.java | 35 ------------------- 1 file changed, 35 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiMigrationTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiMigrationTest.java index 6e19a21217..ea59f00a22 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiMigrationTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiMigrationTest.java @@ -48,41 +48,6 @@ public class WifiMigrationTest extends AndroidTestCase { super.tearDown(); } - /** - * Tests {@link android.net.wifi.WifiMigration.ConfigStoreMigrationData} class. - */ - public void testWifiMigrationConfigStoreDataBuilder() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - WifiConfiguration savedNetwork1 = new WifiConfiguration(); - savedNetwork1.SSID = "\"test1\""; - WifiConfiguration savedNetwork2 = new WifiConfiguration(); - savedNetwork1.SSID = "\"test2\""; - List savedNetworks = Arrays.asList(savedNetwork1, savedNetwork2); - - SoftApConfiguration softApConfiguration = new SoftApConfiguration.Builder() - .setSsid("\"test3\"") - .build(); - - WifiMigration.ConfigStoreMigrationData migrationData = - new WifiMigration.ConfigStoreMigrationData.Builder() - .setUserSavedNetworkConfigurations(savedNetworks) - .setUserSoftApConfiguration(softApConfiguration) - .build(); - - assertNotNull(migrationData); - assertEquals(savedNetworks.size(), - migrationData.getUserSavedNetworkConfigurations().size()); - assertEquals(savedNetwork1.SSID, - migrationData.getUserSavedNetworkConfigurations().get(0).SSID); - assertEquals(savedNetwork2.SSID, - migrationData.getUserSavedNetworkConfigurations().get(1).SSID); - assertEquals(softApConfiguration.getSsid(), - migrationData.getUserSoftApConfiguration().getSsid()); - } - /** * Tests {@link android.net.wifi.WifiMigration.ConfigStoreMigrationData} class. */ From 6a780a7c161eec756da9c8a9a0a64e0bf52126a3 Mon Sep 17 00:00:00 2001 From: David Su Date: Mon, 16 Mar 2020 22:47:20 -0700 Subject: [PATCH 0787/1109] CTS: test WifiNl80211Manager.sendMgmtFrame Link probing is an optional feature gated by an overlay. Unfortunately, there is no public/system API that can be used to check if link probing is supported on the device. `adb shell cmd wifi send-link-probe` requires root, which is not supported by CTS. For devices that do not support link probing, this API could even throw an exception. Thus, this test does not have any expectations. Bug: 150978929 Test: atest android.net.wifi.nl80211.cts.WifiNl80211ManagerTest Change-Id: I13f9be5571c0eb7d64cc86bea5b7fd8addc1db5c --- .../nl80211/cts/WifiNl80211ManagerTest.java | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java b/tests/cts/net/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java index fa8447d2da..f1f3010ddf 100644 --- a/tests/cts/net/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java @@ -42,11 +42,13 @@ import java.util.Arrays; @RunWith(AndroidJUnit4.class) public class WifiNl80211ManagerTest { + private Context mContext; + @Before public void setUp() { - Context context = InstrumentationRegistry.getInstrumentation().getContext(); + mContext = InstrumentationRegistry.getInstrumentation().getContext(); // skip tests if Wifi is not supported - assumeTrue(WifiFeature.isWifiSupported(context)); + assumeTrue(WifiFeature.isWifiSupported(mContext)); } @Test @@ -64,4 +66,19 @@ public class WifiNl80211ManagerTest { .isEqualTo(Arrays.asList(ScanResult.CIPHER_NONE, ScanResult.CIPHER_TKIP)); assertThat(securityType.groupCipher).isEqualTo(ScanResult.CIPHER_CCMP); } + + @Test + public void testSendMgmtFrame() { + try { + WifiNl80211Manager manager = mContext.getSystemService(WifiNl80211Manager.class); + manager.sendMgmtFrame("wlan0", new byte[]{}, -1, Runnable::run, + new WifiNl80211Manager.SendMgmtFrameCallback() { + @Override + public void onAck(int elapsedTimeMs) {} + + @Override + public void onFailure(int reason) {} + }); + } catch (Exception ignore) {} + } } From 65031e4d9f289260cc55e69e35d96b6471919947 Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Tue, 17 Mar 2020 13:38:09 -0700 Subject: [PATCH 0788/1109] [CTS] Add tests for hotspot2.OsuProvider getters Added coverage for below APIs: getFriendlyName() getServerUri() Bug: 150977165 Test: atest WifiHotspot2Test Change-Id: I0abe5ab63dff6793103552870322da6a2f426dba --- .../net/wifi/cts/WifiHotspot2Test.java | 53 ++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiHotspot2Test.java b/tests/cts/net/src/android/net/wifi/cts/WifiHotspot2Test.java index 96e1caaebe..a05b81b932 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiHotspot2Test.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiHotspot2Test.java @@ -18,23 +18,45 @@ package android.net.wifi.cts; import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NONE; +import android.net.Uri; +import android.net.wifi.hotspot2.OsuProvider; import android.net.wifi.hotspot2.PasspointConfiguration; import android.net.wifi.hotspot2.pps.Credential; import android.net.wifi.hotspot2.pps.HomeSp; import android.test.AndroidTestCase; +import android.text.TextUtils; +import java.lang.reflect.Constructor; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; public class WifiHotspot2Test extends AndroidTestCase { static final int SIM_CREDENTIAL = 0; static final int USER_CREDENTIAL = 1; static final int CERT_CREDENTIAL = 2; - + private static final String TEST_SSID = "TEST SSID"; + private static final String TEST_FRIENDLY_NAME = "Friendly Name"; + private static final Map TEST_FRIENDLY_NAMES = + new HashMap() { + { + put("en", TEST_FRIENDLY_NAME); + put("kr", TEST_FRIENDLY_NAME + 2); + put("jp", TEST_FRIENDLY_NAME + 3); + } + }; + private static final String TEST_SERVICE_DESCRIPTION = "Dummy Service"; + private static final Uri TEST_SERVER_URI = Uri.parse("https://test.com"); + private static final String TEST_NAI = "test.access.com"; + private static final List TEST_METHOD_LIST = + Arrays.asList(1 /* METHOD_SOAP_XML_SPP */); @Override protected void setUp() throws Exception { super.setUp(); @@ -434,4 +456,33 @@ public class WifiHotspot2Test extends AndroidTestCase { return createCredential(userCred, null, null, null, null, FakeKeys.CA_CERT0); } + + /** + * Tests {@link OsuProvider#getFriendlyName()} and {@link OsuProvider#getServerUri()} methods. + *

    + * Test that getting a set friendly name and server URI produces the same value + */ + public void testOsuProviderGetters() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + + // Using Java reflection to construct an OsuProvider instance because its constructor is + // hidden and not available to apps. + Class osuProviderClass = Class.forName("android.net.wifi.hotspot2.OsuProvider"); + Constructor osuProviderClassConstructor = osuProviderClass.getConstructor(String.class, + Map.class, String.class, Uri.class, String.class, List.class); + + OsuProvider osuProvider = (OsuProvider) osuProviderClassConstructor.newInstance(TEST_SSID, + TEST_FRIENDLY_NAMES, TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, + TEST_METHOD_LIST); + String lang = Locale.getDefault().getLanguage(); + String friendlyName = TEST_FRIENDLY_NAMES.get(lang); + if (TextUtils.isEmpty(friendlyName)) { + friendlyName = TEST_FRIENDLY_NAMES.get("en"); + } + assertEquals(friendlyName, osuProvider.getFriendlyName()); + assertEquals(TEST_SERVER_URI, osuProvider.getServerUri()); + } } From a4a48ef75937964487c345c948dcdfcf91e41e0f Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 17 Mar 2020 17:39:35 -0700 Subject: [PATCH 0789/1109] CTS: Test PNO Scanning Test that PNO scans reconnects us to a saved network when Wifi is disconnected and screen is off. This also adds coverage for WifiNl80211Manager.startPnoScan. Bug: 150978929 Test: atest android.net.wifi.cts.WifiManagerTest Change-Id: Id0487f4df48ea013d67e19faecd96b5a469f09da --- .../android/net/wifi/cts/WifiManagerTest.java | 61 ++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 51a4f32a64..fc4f2eaaac 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -81,9 +81,11 @@ import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Objects; +import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Executor; @@ -1212,8 +1214,12 @@ public class WifiManagerTest extends AndroidTestCase { Thread.sleep(DURATION_SCREEN_TOGGLE); } - private void turnScreenOff() throws Exception { + private void turnScreenOffNoDelay() throws Exception { mUiDevice.executeShellCommand("input keyevent KEYCODE_SLEEP"); + } + + private void turnScreenOff() throws Exception { + turnScreenOffNoDelay(); // Since the screen on/off intent is ordered, they will not be sent right now. Thread.sleep(DURATION_SCREEN_TOGGLE); } @@ -1799,6 +1805,59 @@ public class WifiManagerTest extends AndroidTestCase { mWifiManager.isPreferredNetworkOffloadSupported(); } + /** Test that PNO scans reconnects us when the device is disconnected and the screen is off. */ + public void testPnoScan() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + if (!mWifiManager.isPreferredNetworkOffloadSupported()) { + // skip the test if PNO scanning is not supported + return; + } + + // make sure we're connected + waitForConnection(); + + WifiInfo currentNetwork = ShellIdentityUtils.invokeWithShellPermissions( + mWifiManager::getConnectionInfo); + + // disable all networks that aren't already disabled + List savedNetworks = ShellIdentityUtils.invokeWithShellPermissions( + mWifiManager::getConfiguredNetworks); + Set disabledNetworkIds = new HashSet<>(); + for (WifiConfiguration config : savedNetworks) { + if (config.getNetworkSelectionStatus().getNetworkSelectionDisableReason() + == WifiConfiguration.NetworkSelectionStatus.DISABLED_NONE) { + ShellIdentityUtils.invokeWithShellPermissions( + () -> mWifiManager.disableNetwork(config.networkId)); + disabledNetworkIds.add(config.networkId); + } + } + + try { + // wait for disconnection from current network + waitForDisconnection(); + + // turn screen off + turnScreenOffNoDelay(); + + // re-enable the current network - this will trigger PNO + ShellIdentityUtils.invokeWithShellPermissions( + () -> mWifiManager.enableNetwork(currentNetwork.getNetworkId(), false)); + disabledNetworkIds.remove(currentNetwork.getNetworkId()); + + // PNO should reconnect us back to the network we disconnected from + waitForConnection(); + } finally { + // re-enable disabled networks + for (int disabledNetworkId : disabledNetworkIds) { + ShellIdentityUtils.invokeWithShellPermissions( + () -> mWifiManager.enableNetwork(disabledNetworkId, false)); + } + } + } + /** * Tests {@link WifiManager#isTdlsSupported()} does not crash. */ From 1f1a316fb2a62ac219efb07910575d573ade6b3d Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Tue, 17 Mar 2020 15:02:49 -0700 Subject: [PATCH 0790/1109] [CTS] Added tests for hotspot2 provisioning APIs Added coverage for below APIs: ProvisioningCallback() WifiManager#startSubscriptionProvisioning() Bug: 150977584 Test: atest WifiManagerTest Change-Id: Ic810b8a4fdeb22a96900971b355c336670199ed6 --- .../android/net/wifi/cts/WifiManagerTest.java | 127 ++++++++++++++++-- 1 file changed, 113 insertions(+), 14 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index fc4f2eaaac..65d9dea41e 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -32,7 +32,6 @@ import android.content.IntentFilter; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; -import android.net.util.MacAddressUtils; import android.net.ConnectivityManager; import android.net.LinkProperties; import android.net.MacAddress; @@ -41,6 +40,8 @@ import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkRequest; import android.net.TetheringManager; +import android.net.Uri; +import android.net.util.MacAddressUtils; import android.net.wifi.ScanResult; import android.net.wifi.SoftApCapability; import android.net.wifi.SoftApConfiguration; @@ -52,9 +53,14 @@ import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.WifiLock; import android.net.wifi.WifiNetworkConnectionStatistics; import android.net.wifi.hotspot2.ConfigParser; +import android.net.wifi.hotspot2.OsuProvider; import android.net.wifi.hotspot2.PasspointConfiguration; +import android.net.wifi.hotspot2.ProvisioningCallback; import android.net.wifi.hotspot2.pps.Credential; import android.net.wifi.hotspot2.pps.HomeSp; +import android.os.Handler; +import android.os.HandlerExecutor; +import android.os.HandlerThread; import android.os.Process; import android.os.SystemClock; import android.os.UserHandle; @@ -78,15 +84,18 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.lang.reflect.Constructor; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Objects; import java.util.Set; -import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Executor; import java.util.concurrent.Executors; @@ -130,7 +139,7 @@ public class WifiManagerTest extends AndroidTestCase { private static final int SCAN_TIMEOUT_MSEC = 9000; private static final int TIMEOUT_MSEC = 6000; private static final int WAIT_MSEC = 60; - private static final int DURATION = 10_000; + private static final int TEST_WAIT_DURATION_MS = 10_000; private static final int DURATION_SCREEN_TOGGLE = 2000; private static final int DURATION_SETTINGS_TOGGLE = 1_000; private static final int WIFI_SCAN_TEST_INTERVAL_MILLIS = 60 * 1000; @@ -190,6 +199,54 @@ public class WifiManagerTest extends AndroidTestCase { } } }; + // Initialize with an invalid status value (0) + private int mProvisioningStatus = 0; + // Initialize with an invalid status value (0) + private int mProvisioningFailureStatus = 0; + private boolean mProvisioningComplete = false; + private ProvisioningCallback mProvisioningCallback = new ProvisioningCallback() { + @Override + public void onProvisioningFailure(int status) { + synchronized (mLock) { + mProvisioningFailureStatus = status; + mLock.notify(); + } + } + + @Override + public void onProvisioningStatus(int status) { + synchronized (mLock) { + mProvisioningStatus = status; + mLock.notify(); + } + } + + @Override + public void onProvisioningComplete() { + mProvisioningComplete = true; + } + }; + private static final String TEST_SSID = "TEST SSID"; + private static final String TEST_FRIENDLY_NAME = "Friendly Name"; + private static final Map TEST_FRIENDLY_NAMES = + new HashMap() { + { + put("en", TEST_FRIENDLY_NAME); + put("kr", TEST_FRIENDLY_NAME + 2); + put("jp", TEST_FRIENDLY_NAME + 3); + } + }; + private static final String TEST_SERVICE_DESCRIPTION = "Dummy Service"; + private static final Uri TEST_SERVER_URI = Uri.parse("https://test.com"); + private static final String TEST_NAI = "test.access.com"; + private static final List TEST_METHOD_LIST = + Arrays.asList(1 /* METHOD_SOAP_XML_SPP */); + private final HandlerThread mHandlerThread = new HandlerThread("WifiManagerTest"); + protected final Executor mExecutor; + { + mHandlerThread.start(); + mExecutor = new HandlerExecutor(new Handler(mHandlerThread.getLooper())); + } @Override protected void setUp() throws Exception { @@ -228,7 +285,7 @@ public class WifiManagerTest extends AndroidTestCase { setWifiEnabled(true); mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); turnScreenOnNoDelay(); - Thread.sleep(DURATION); + Thread.sleep(TEST_WAIT_DURATION_MS); assertTrue(mWifiManager.isWifiEnabled()); synchronized (mMySync) { mMySync.expectedState = STATE_NULL; @@ -259,7 +316,7 @@ public class WifiManagerTest extends AndroidTestCase { // restore original softap config ShellIdentityUtils.invokeWithShellPermissions( () -> mWifiManager.setSoftApConfiguration(mOriginalSoftApConfig)); - Thread.sleep(DURATION); + Thread.sleep(TEST_WAIT_DURATION_MS); super.tearDown(); } @@ -377,7 +434,7 @@ public class WifiManagerTest extends AndroidTestCase { + " empty when location is disabled!"); } setWifiEnabled(false); - Thread.sleep(DURATION); + Thread.sleep(TEST_WAIT_DURATION_MS); startScan(); if (mWifiManager.isScanAlwaysAvailable() && isScanCurrentlyAvailable()) { // Make sure at least one AP is found. @@ -712,7 +769,7 @@ public class WifiManagerTest extends AndroidTestCase { try { mWifiManager.startLocalOnlyHotspot(callback, null); // now wait for callback - mLock.wait(DURATION); + mLock.wait(TEST_WAIT_DURATION_MS); } catch (InterruptedException e) { } // check if we got the callback @@ -806,7 +863,7 @@ public class WifiManagerTest extends AndroidTestCase { boolean wifiEnabled = mWifiManager.isWifiEnabled(); // now we should fail to toggle wifi state. assertFalse(mWifiManager.setWifiEnabled(!wifiEnabled)); - Thread.sleep(DURATION); + Thread.sleep(TEST_WAIT_DURATION_MS); assertEquals(wifiEnabled, mWifiManager.isWifiEnabled()); } @@ -1553,7 +1610,7 @@ public class WifiManagerTest extends AndroidTestCase { mWifiManager.connect(savedNetworks.get(0), actionListener); } // now wait for callback - mLock.wait(DURATION); + mLock.wait(TEST_WAIT_DURATION_MS); } catch (InterruptedException e) { } } @@ -1632,7 +1689,7 @@ public class WifiManagerTest extends AndroidTestCase { .build(), networkCallbackListener); // now wait for callback - mLock.wait(DURATION); + mLock.wait(TEST_WAIT_DURATION_MS); } catch (InterruptedException e) { } } @@ -1680,7 +1737,7 @@ public class WifiManagerTest extends AndroidTestCase { modSavedNetwork.meteredOverride = WifiConfiguration.METERED_OVERRIDE_METERED; mWifiManager.save(modSavedNetwork, actionListener); // now wait for callback - mLock.wait(DURATION); + mLock.wait(TEST_WAIT_DURATION_MS); } catch (InterruptedException e) { } } @@ -1728,7 +1785,7 @@ public class WifiManagerTest extends AndroidTestCase { try { mWifiManager.forget(newNetworkId, actionListener); // now wait for callback - mLock.wait(DURATION); + mLock.wait(TEST_WAIT_DURATION_MS); } catch (InterruptedException e) { } } @@ -1962,7 +2019,7 @@ public class WifiManagerTest extends AndroidTestCase { // Send some traffic to trigger the traffic state change callbacks. sendTraffic(); // now wait for callback - mLock.wait(DURATION); + mLock.wait(TEST_WAIT_DURATION_MS); } catch (InterruptedException e) { } } @@ -2185,7 +2242,7 @@ public class WifiManagerTest extends AndroidTestCase { .build(), networkCallbackListener); // now wait for callback - mLock.wait(DURATION); + mLock.wait(TEST_WAIT_DURATION_MS); } catch (InterruptedException e) { } } @@ -2407,4 +2464,46 @@ public class WifiManagerTest extends AndroidTestCase { // Clean up mWifiManager.removePasspointConfiguration(passpointConfiguration.getHomeSp().getFqdn()); } + + /** + * Tests that + * {@link WifiManager#startSubscriptionProvisioning(OsuProvider, Executor, ProvisioningCallback)} + * starts a subscription provisioning, and confirm a status callback invoked once. + */ + public void testStartSubscriptionProvisioning() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + + // Using Java reflection to construct an OsuProvider instance because its constructor is + // hidden and not available to apps. + Class osuProviderClass = Class.forName("android.net.wifi.hotspot2.OsuProvider"); + Constructor osuProviderClassConstructor = osuProviderClass.getConstructor(String.class, + Map.class, String.class, Uri.class, String.class, List.class); + + OsuProvider osuProvider = (OsuProvider) osuProviderClassConstructor.newInstance(TEST_SSID, + TEST_FRIENDLY_NAMES, TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, + TEST_METHOD_LIST); + + UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); + try { + uiAutomation.adoptShellPermissionIdentity(); + synchronized (mLock) { + // Start a subscription provisioning for a non-existent Passpoint R2 AP + mWifiManager.startSubscriptionProvisioning(osuProvider, mExecutor, + mProvisioningCallback); + mLock.wait(TEST_WAIT_DURATION_MS); + } + } finally { + uiAutomation.dropShellPermissionIdentity(); + } + + // Expect only a single callback event, connecting. Since AP doesn't exist, it ends here + assertEquals(ProvisioningCallback.OSU_STATUS_AP_CONNECTING, mProvisioningStatus); + // No failure callbacks expected + assertEquals(0, mProvisioningFailureStatus); + // No completion callback expected + assertFalse(mProvisioningComplete); + } } From 6afc73aef6a05a0f9114cd19138848b30c34dff1 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Wed, 18 Mar 2020 16:23:28 -0700 Subject: [PATCH 0791/1109] WifiMigrationTest: Add test for WifiMigration.loadFromSettings This assumes that OEM's were using the same AOSP @Settings.Global values to persist the data (which is probably true on all devices). Bug: 150236894 Test: atest android.net.wifi.cts.WifiMigrationTest Change-Id: I7e80730c81e6ed4773cf187e4eb1018528edb158 --- .../net/wifi/cts/WifiMigrationTest.java | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiMigrationTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiMigrationTest.java index ea59f00a22..7d94ad3ff8 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiMigrationTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiMigrationTest.java @@ -16,16 +16,9 @@ package android.net.wifi.cts; -import static org.junit.Assert.assertNotNull; - -import android.net.wifi.SoftApConfiguration; -import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiMigration; import android.test.AndroidTestCase; -import java.util.Arrays; -import java.util.List; - public class WifiMigrationTest extends AndroidTestCase { private static final String TEST_SSID_UNQUOTED = "testSsid1"; @@ -49,7 +42,7 @@ public class WifiMigrationTest extends AndroidTestCase { } /** - * Tests {@link android.net.wifi.WifiMigration.ConfigStoreMigrationData} class. + * Tests {@link android.net.wifi.WifiMigration.SettingsMigrationData.Builder} class. */ public void testWifiMigrationSettingsDataBuilder() throws Exception { if (!WifiFeature.isWifiSupported(getContext())) { @@ -76,4 +69,15 @@ public class WifiMigrationTest extends AndroidTestCase { assertTrue(migrationData.isVerboseLoggingEnabled()); assertEquals(TEST_SSID_UNQUOTED, migrationData.getP2pDeviceName()); } + + /** + * Tests {@link android.net.wifi.WifiMigration.SettingsMigrationData} class. + */ + public void testWifiMigrationSettings() throws Exception { + try { + // ensure that this does not crash. + WifiMigration.loadFromSettings(getContext()); + } catch (Exception ignore) { + } + } } From 938c3858720592e69ae1e071daa39623a3cdff8e Mon Sep 17 00:00:00 2001 From: markchien Date: Tue, 17 Mar 2020 13:51:39 +0800 Subject: [PATCH 0792/1109] Clean up for TetheringManager API change Bug: 149858697 Bug: 151243337 Test: atest CtsTetheringTest Change-Id: I817cb62f0f41d72e861952394ac8fbbfdc360f11 --- .../src/android/tethering/cts/TetheringManagerTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java index 98dbe52e41..4d72eae3e4 100644 --- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java +++ b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java @@ -180,15 +180,15 @@ public class TetheringManagerTest { } } - private class StartTetheringCallback extends TetheringManager.StartTetheringCallback { + private class StartTetheringCallback implements TetheringManager.StartTetheringCallback { @Override public void onTetheringStarted() { // Do nothing, TetherChangeReceiver will wait until it receives the broadcast. } @Override - public void onTetheringFailed(final int resultCode) { - fail("startTethering fail: " + resultCode); + public void onTetheringFailed(final int error) { + fail("startTethering fail: " + error); } } From df5e4229932c880b6ab78d908fdaa06ee7aa17e6 Mon Sep 17 00:00:00 2001 From: markchien Date: Tue, 17 Mar 2020 13:51:39 +0800 Subject: [PATCH 0793/1109] Clean up for TetheringManager API change Bug: 149858697 Bug: 151243337 Test: atest CtsTetheringTest Change-Id: I817cb62f0f41d72e861952394ac8fbbfdc360f11 Merged-In: I817cb62f0f41d72e861952394ac8fbbfdc360f11 --- .../src/android/tethering/cts/TetheringManagerTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java index 98dbe52e41..4d72eae3e4 100644 --- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java +++ b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java @@ -180,15 +180,15 @@ public class TetheringManagerTest { } } - private class StartTetheringCallback extends TetheringManager.StartTetheringCallback { + private class StartTetheringCallback implements TetheringManager.StartTetheringCallback { @Override public void onTetheringStarted() { // Do nothing, TetherChangeReceiver will wait until it receives the broadcast. } @Override - public void onTetheringFailed(final int resultCode) { - fail("startTethering fail: " + resultCode); + public void onTetheringFailed(final int error) { + fail("startTethering fail: " + error); } } From 4da74f040ac8891b2bcd2b8b2332ac4f9037ee41 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Thu, 19 Mar 2020 06:33:10 -0700 Subject: [PATCH 0794/1109] WifiManagerTest: Make traffic state change test more robust Traffic state changed callbacks can be triggered multiple times with different data indicators. Ensure that we wait for the expected state before unblocking. Bug: 151900245 Test: atest android.net.wifi.cts.WifiManagerTest Change-Id: Ie451070bf2ab430f57ff83b0cefca7050aa8df59 --- .../net/src/android/net/wifi/cts/WifiManagerTest.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 51a4f32a64..16c7477aff 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -1840,11 +1840,13 @@ public class WifiManagerTest extends AndroidTestCase { private static class TestTrafficStateCallback implements WifiManager.TrafficStateCallback { private final Object mLock; + private final int mWaitForState; public boolean onStateChangedCalled = false; public int state = -1; - TestTrafficStateCallback(Object lock) { + TestTrafficStateCallback(Object lock, int waitForState) { mLock = lock; + mWaitForState = waitForState; } @Override @@ -1852,7 +1854,9 @@ public class WifiManagerTest extends AndroidTestCase { synchronized (mLock) { onStateChangedCalled = true; this.state = state; - mLock.notify(); + if (mWaitForState == state) { // only notify if we got the expected state. + mLock.notify(); + } } } } @@ -1886,7 +1890,8 @@ public class WifiManagerTest extends AndroidTestCase { // skip the test if WiFi is not supported return; } - TestTrafficStateCallback trafficStateCallback = new TestTrafficStateCallback(mLock); + TestTrafficStateCallback trafficStateCallback = + new TestTrafficStateCallback(mLock, DATA_ACTIVITY_INOUT); UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); try { uiAutomation.adoptShellPermissionIdentity(); From 40dc8e50535f84204053c5b5948384a0db381bec Mon Sep 17 00:00:00 2001 From: Nate Jiang Date: Thu, 19 Mar 2020 14:13:00 -0700 Subject: [PATCH 0795/1109] Add Cts test for createNetworkSpecifierPmk Bug: 150976232 Test: atest SingleDeviceTest Change-Id: Idb8e28067f08c7d767649d182c325304c6a2fff3 --- .../net/wifi/aware/cts/SingleDeviceTest.java | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java index 5eb3e3680a..1645f32845 100644 --- a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java +++ b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java @@ -64,6 +64,9 @@ public class SingleDeviceTest extends AndroidTestCase { // wait for Wi-Fi Aware state changes & network requests callbacks static private final int WAIT_FOR_AWARE_CHANGE_SECS = 10; // 10 seconds + private static final int MIN_DISTANCE_MM = 1 * 1000; + private static final int MAX_DISTANCE_MM = 3 * 1000; + private static final byte[] PMK_VALID = "01234567890123456789012345678901".getBytes(); private final Object mLock = new Object(); private final HandlerThread mHandlerThread = new HandlerThread("SingleDeviceTest"); @@ -741,7 +744,8 @@ public class SingleDeviceTest extends AndroidTestCase { } /** - * Request an Aware data-path (encrypted) as a Responder with an arbitrary peer MAC address. + * Request an Aware data-path (encrypted with Passphrase) as a Responder with an arbitrary peer + * MAC address. * Validate that receive an onUnavailable() callback. */ public void testDataPathPassphraseOutOfBandFail() { @@ -773,6 +777,40 @@ public class SingleDeviceTest extends AndroidTestCase { session.close(); } + /** + * Request an Aware data-path (encrypted with PMK) as a Responder with an arbitrary peer MAC + * address. + * Validate that receive an onUnavailable() callback. + */ + public void testDataPathPmkOutOfBandFail() { + if (!TestUtils.shouldTestWifiAware(getContext())) { + return; + } + MacAddress mac = MacAddress.fromString("00:01:02:03:04:05"); + + // 1. initialize Aware: only purpose is to make sure it is available for OOB data-path + WifiAwareSession session = attachAndGetSession(); + + PublishConfig publishConfig = new PublishConfig.Builder().setServiceName( + "ValidName").build(); + DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); + session.publish(publishConfig, discoveryCb, mHandler); + assertTrue("Publish started", + discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED)); + + // 2. request an AWARE network + NetworkCallbackTest networkCb = new NetworkCallbackTest(); + NetworkRequest nr = new NetworkRequest.Builder().addTransportType( + NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier( + session.createNetworkSpecifierPmk( + WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, mac.toByteArray(), + PMK_VALID)).build(); + mConnectivityManager.requestNetwork(nr, networkCb); + assertTrue("OnUnavailable not received", networkCb.waitForOnUnavailable()); + + session.close(); + } + // local utilities private WifiAwareSession attachAndGetSession() { From 483497ca8d3115354f310b1d4f7210ec263861a6 Mon Sep 17 00:00:00 2001 From: Nate Jiang Date: Thu, 19 Mar 2020 14:26:09 -0700 Subject: [PATCH 0796/1109] Add test for SubscribeConfig.Builder().setMinDistanceMm(int) Bug: 150975711 Test: atest SingleDeviceTest Change-Id: I7ca4c3af034e3816c63d87d924e7ed3ef64b5984 --- .../net/src/android/net/wifi/aware/cts/SingleDeviceTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java index 1645f32845..29f091b8b4 100644 --- a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java +++ b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java @@ -618,7 +618,8 @@ public class SingleDeviceTest extends AndroidTestCase { // 2. update-subscribe subscribeConfig = new SubscribeConfig.Builder().setServiceName( - serviceName).setServiceSpecificInfo("extras".getBytes()).build(); + serviceName).setServiceSpecificInfo("extras".getBytes()) + .setMinDistanceMm(MIN_DISTANCE_MM).build(); discoverySession.updateSubscribe(subscribeConfig); assertTrue("Subscribe update", discoveryCb.waitForCallback( DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED)); From 5dd8299525eb59c205f01bec336148bd57b5daec Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Thu, 19 Mar 2020 14:24:05 -0700 Subject: [PATCH 0797/1109] ConnectedNetworkScorerTest: Add tests for wifi usability stats Bug: 150236894 Bug: 150973472 Test: atest android.net.wifi.cts.ConnectedNetworkScorerTest Change-Id: Ic55dbbe672da5492db5382aa6c427976355518ed --- .../wifi/cts/ConnectedNetworkScorerTest.java | 236 ++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 tests/cts/net/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java diff --git a/tests/cts/net/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java b/tests/cts/net/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java new file mode 100644 index 0000000000..5869ee8ea4 --- /dev/null +++ b/tests/cts/net/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java @@ -0,0 +1,236 @@ +/* + * 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.wifi.cts; + +import static android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_FAILURE; +import static android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_NO_PROBE; +import static android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_SUCCESS; +import static android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_UNKNOWN; + +import static com.google.common.truth.Truth.assertThat; + +import android.app.UiAutomation; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiManager; +import android.net.wifi.WifiUsabilityStatsEntry; +import android.support.test.uiautomator.UiDevice; +import android.telephony.TelephonyManager; +import android.test.AndroidTestCase; + +import androidx.test.platform.app.InstrumentationRegistry; + +import com.android.compatibility.common.util.PollingCheck; +import com.android.compatibility.common.util.ShellIdentityUtils; +import com.android.compatibility.common.util.SystemUtil; + +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +public class ConnectedNetworkScorerTest extends AndroidTestCase { + private WifiManager mWifiManager; + private UiDevice mUiDevice; + private boolean mWasVerboseLoggingEnabled; + + private static final int DURATION = 10_000; + private static final int DURATION_SCREEN_TOGGLE = 2000; + + @Override + protected void setUp() throws Exception { + super.setUp(); + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + mWifiManager = getContext().getSystemService(WifiManager.class); + assertNotNull(mWifiManager); + + // turn on verbose logging for tests + mWasVerboseLoggingEnabled = ShellIdentityUtils.invokeWithShellPermissions( + () -> mWifiManager.isVerboseLoggingEnabled()); + ShellIdentityUtils.invokeWithShellPermissions( + () -> mWifiManager.setVerboseLoggingEnabled(true)); + + if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true); + mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); + turnScreenOn(); + PollingCheck.check("Wifi not enabled", DURATION, () -> mWifiManager.isWifiEnabled()); + List savedNetworks = ShellIdentityUtils.invokeWithShellPermissions( + () -> mWifiManager.getConfiguredNetworks()); + assertFalse("Need at least one saved network", savedNetworks.isEmpty()); + // Wait for wifi is to be connected + PollingCheck.check( + "Wifi not connected", + DURATION, + () -> mWifiManager.getConnectionInfo().getNetworkId() != -1); + assertThat(mWifiManager.getConnectionInfo().getNetworkId()).isNotEqualTo(-1); + } + + @Override + protected void tearDown() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + super.tearDown(); + return; + } + if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true); + turnScreenOff(); + ShellIdentityUtils.invokeWithShellPermissions( + () -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled)); + super.tearDown(); + } + + private void setWifiEnabled(boolean enable) throws Exception { + // now trigger the change using shell commands. + SystemUtil.runShellCommand("svc wifi " + (enable ? "enable" : "disable")); + } + + private void turnScreenOn() throws Exception { + mUiDevice.executeShellCommand("input keyevent KEYCODE_WAKEUP"); + mUiDevice.executeShellCommand("wm dismiss-keyguard"); + // Since the screen on/off intent is ordered, they will not be sent right now. + Thread.sleep(DURATION_SCREEN_TOGGLE); + } + + private void turnScreenOff() throws Exception { + mUiDevice.executeShellCommand("input keyevent KEYCODE_SLEEP"); + } + + private static class TestUsabilityStatsListener implements + WifiManager.OnWifiUsabilityStatsListener { + private final CountDownLatch mCountDownLatch; + public int seqNum; + public boolean isSameBssidAndFre; + public WifiUsabilityStatsEntry statsEntry; + + TestUsabilityStatsListener(CountDownLatch countDownLatch) { + mCountDownLatch = countDownLatch; + } + + @Override + public void onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq, + WifiUsabilityStatsEntry statsEntry) { + this.seqNum = seqNum; + this.isSameBssidAndFre = isSameBssidAndFreq; + this.statsEntry = statsEntry; + mCountDownLatch.countDown(); + } + } + + /** + * Tests the {@link android.net.wifi.WifiUsabilityStatsEntry} retrieved from + * {@link WifiManager.OnWifiUsabilityStatsListener}. + */ + public void testWifiUsabilityStatsEntry() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + CountDownLatch countDownLatch = new CountDownLatch(1); + UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); + TestUsabilityStatsListener usabilityStatsListener = + new TestUsabilityStatsListener(countDownLatch); + try { + uiAutomation.adoptShellPermissionIdentity(); + mWifiManager.addOnWifiUsabilityStatsListener( + Executors.newSingleThreadExecutor(), usabilityStatsListener); + // Wait for new usability stats (while connected & screen on this is triggered + // by platform periodically). + assertThat(countDownLatch.await(DURATION, TimeUnit.MILLISECONDS)).isTrue(); + + assertThat(usabilityStatsListener.statsEntry).isNotNull(); + WifiUsabilityStatsEntry statsEntry = usabilityStatsListener.statsEntry; + + assertThat(statsEntry.getTimeStampMillis()).isGreaterThan(0L); + assertThat(statsEntry.getRssi()).isLessThan(0); + assertThat(statsEntry.getLinkSpeedMbps()).isGreaterThan(0); + assertThat(statsEntry.getTotalTxSuccess()).isGreaterThan(0L); + assertThat(statsEntry.getTotalTxRetries()).isAtLeast(0L); + assertThat(statsEntry.getTotalTxBad()).isAtLeast(0L); + assertThat(statsEntry.getTotalRxSuccess()).isAtLeast(0L); + assertThat(statsEntry.getTotalRadioOnTimeMillis()).isGreaterThan(0L); + assertThat(statsEntry.getTotalRadioTxTimeMillis()).isGreaterThan(0L); + assertThat(statsEntry.getTotalRadioRxTimeMillis()).isGreaterThan(0L); + assertThat(statsEntry.getTotalScanTimeMillis()).isGreaterThan(0L); + assertThat(statsEntry.getTotalNanScanTimeMillis()).isAtLeast(0L); + assertThat(statsEntry.getTotalBackgroundScanTimeMillis()).isAtLeast(0L); + assertThat(statsEntry.getTotalRoamScanTimeMillis()).isAtLeast(0L); + assertThat(statsEntry.getTotalPnoScanTimeMillis()).isAtLeast(0L); + assertThat(statsEntry.getTotalHotspot2ScanTimeMillis()).isAtLeast(0L); + assertThat(statsEntry.getTotalCcaBusyFreqTimeMillis()).isAtLeast(0L); + assertThat(statsEntry.getTotalRadioOnTimeMillis()).isGreaterThan(0L); + assertThat(statsEntry.getTotalBeaconRx()).isGreaterThan(0L); + assertThat(statsEntry.getProbeStatusSinceLastUpdate()) + .isAnyOf(PROBE_STATUS_SUCCESS, + PROBE_STATUS_FAILURE, + PROBE_STATUS_NO_PROBE, + PROBE_STATUS_UNKNOWN); + // -1 is default value for some of these fields if they're not available. + assertThat(statsEntry.getProbeElapsedTimeSinceLastUpdateMillis()).isAtLeast(-1); + assertThat(statsEntry.getProbeMcsRateSinceLastUpdate()).isAtLeast(-1); + assertThat(statsEntry.getRxLinkSpeedMbps()).isAtLeast(-1); + // no longer populated, return default value. + assertThat(statsEntry.getCellularDataNetworkType()) + .isAnyOf(TelephonyManager.NETWORK_TYPE_UNKNOWN, + TelephonyManager.NETWORK_TYPE_GPRS, + TelephonyManager.NETWORK_TYPE_EDGE, + TelephonyManager.NETWORK_TYPE_UMTS, + TelephonyManager.NETWORK_TYPE_CDMA, + TelephonyManager.NETWORK_TYPE_EVDO_0, + TelephonyManager.NETWORK_TYPE_EVDO_A, + TelephonyManager.NETWORK_TYPE_1xRTT, + TelephonyManager.NETWORK_TYPE_HSDPA, + TelephonyManager.NETWORK_TYPE_HSUPA, + TelephonyManager.NETWORK_TYPE_HSPA, + TelephonyManager.NETWORK_TYPE_IDEN, + TelephonyManager.NETWORK_TYPE_EVDO_B, + TelephonyManager.NETWORK_TYPE_LTE, + TelephonyManager.NETWORK_TYPE_EHRPD, + TelephonyManager.NETWORK_TYPE_HSPAP, + TelephonyManager.NETWORK_TYPE_GSM, + TelephonyManager.NETWORK_TYPE_TD_SCDMA, + TelephonyManager.NETWORK_TYPE_IWLAN, + TelephonyManager.NETWORK_TYPE_NR); + assertThat(statsEntry.getCellularSignalStrengthDbm()).isAtMost(0); + assertThat(statsEntry.getCellularSignalStrengthDb()).isAtMost(0); + assertThat(statsEntry.isSameRegisteredCell()).isFalse(); + } finally { + mWifiManager.removeOnWifiUsabilityStatsListener(usabilityStatsListener); + uiAutomation.dropShellPermissionIdentity(); + } + } + + /** + * Tests the {@link android.net.wifi.WifiManager#updateWifiUsabilityScore(int, int, int)} + */ + public void testUpdateWifiUsabilityScore() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); + try { + uiAutomation.adoptShellPermissionIdentity(); + // update scoring with dummy values. + mWifiManager.updateWifiUsabilityScore(0, 50, 50); + } finally { + uiAutomation.dropShellPermissionIdentity(); + } + } + +} From b6b4c49895b700081e021c5b80fbd89748487bd2 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Thu, 19 Mar 2020 15:09:28 -0700 Subject: [PATCH 0798/1109] ConnectedNetworkScorerTest: Add test for connected network scorer Bug: 150236894 Bug: 150973472 Test: atest android.net.wifi.cts.ConnectedNetworkScorerTest Change-Id: Id928678bfefe00f66229f4dbd9915c7f41274972 --- .../wifi/cts/ConnectedNetworkScorerTest.java | 110 +++++++++++++++++- 1 file changed, 109 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java b/tests/cts/net/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java index 5869ee8ea4..ce5bb81d7b 100644 --- a/tests/cts/net/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java @@ -58,7 +58,7 @@ public class ConnectedNetworkScorerTest extends AndroidTestCase { return; } mWifiManager = getContext().getSystemService(WifiManager.class); - assertNotNull(mWifiManager); + assertThat(mWifiManager).isNotNull(); // turn on verbose logging for tests mWasVerboseLoggingEnabled = ShellIdentityUtils.invokeWithShellPermissions( @@ -233,4 +233,112 @@ public class ConnectedNetworkScorerTest extends AndroidTestCase { } } + private static class TestConnectedNetworkScorer implements + WifiManager.WifiConnectedNetworkScorer { + private CountDownLatch mCountDownLatch; + public int startSessionId; + public int stopSessionId; + public WifiManager.ScoreUpdateObserver scoreUpdateObserver; + + TestConnectedNetworkScorer(CountDownLatch countDownLatch) { + mCountDownLatch = countDownLatch; + } + + @Override + public void onStart(int sessionId) { + synchronized (mCountDownLatch) { + this.startSessionId = sessionId; + mCountDownLatch.countDown(); + } + } + + @Override + public void onStop(int sessionId) { + synchronized (mCountDownLatch) { + this.stopSessionId = sessionId; + mCountDownLatch.countDown(); + } + } + + @Override + public void onSetScoreUpdateObserver(WifiManager.ScoreUpdateObserver observerImpl) { + this.scoreUpdateObserver = observerImpl; + } + + public void resetCountDownLatch(CountDownLatch countDownLatch) { + synchronized (mCountDownLatch) { + mCountDownLatch = countDownLatch; + } + } + } + + /** + * Tests the {@link android.net.wifi.WifiConnectedNetworkScorer} interface. + * + * Note: We could write more interesting test cases (if the device has a mobile connection), but + * that would make the test flaky. The default network/route selection on the device is not just + * controlled by the wifi scorer input, but also based on params which are controlled by + * other parts of the platform (likely in connectivity service) and hence will behave + * differently on OEM devices. + */ + public void testSetWifiConnectedNetworkScorer() throws Exception { + if (!WifiFeature.isWifiSupported(getContext())) { + // skip the test if WiFi is not supported + return; + } + CountDownLatch countDownLatchScorer = new CountDownLatch(1); + CountDownLatch countDownLatchUsabilityStats = new CountDownLatch(1); + UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); + TestConnectedNetworkScorer connectedNetworkScorer = + new TestConnectedNetworkScorer(countDownLatchScorer); + TestUsabilityStatsListener usabilityStatsListener = + new TestUsabilityStatsListener(countDownLatchUsabilityStats); + try { + uiAutomation.adoptShellPermissionIdentity(); + mWifiManager.setWifiConnectedNetworkScorer( + Executors.newSingleThreadExecutor(), connectedNetworkScorer); + // Since we're already connected, wait for onStart to be invoked. + assertThat(countDownLatchScorer.await(DURATION, TimeUnit.MILLISECONDS)).isTrue(); + + assertThat(connectedNetworkScorer.startSessionId).isAtLeast(0); + assertThat(connectedNetworkScorer.scoreUpdateObserver).isNotNull(); + WifiManager.ScoreUpdateObserver scoreUpdateObserver = + connectedNetworkScorer.scoreUpdateObserver; + + // Now trigger a dummy score update. + scoreUpdateObserver.notifyScoreUpdate(connectedNetworkScorer.startSessionId, 50); + + // Register the usability listener + mWifiManager.addOnWifiUsabilityStatsListener( + Executors.newSingleThreadExecutor(), usabilityStatsListener); + // Trigger a usability stats update. + scoreUpdateObserver.triggerUpdateOfWifiUsabilityStats( + connectedNetworkScorer.startSessionId); + // Ensure that we got the stats update callback. + assertThat(countDownLatchUsabilityStats.await(DURATION, TimeUnit.MILLISECONDS)) + .isTrue(); + assertThat(usabilityStatsListener.seqNum).isAtLeast(0); + + // Reset the scorer countdown latch for onStop + countDownLatchScorer = new CountDownLatch(1); + connectedNetworkScorer.resetCountDownLatch(countDownLatchScorer); + // Now disconnect from the network. + mWifiManager.disconnect(); + // Wait for it to be disconnected. + PollingCheck.check( + "Wifi not disconnected", + DURATION, + () -> mWifiManager.getConnectionInfo().getNetworkId() == -1); + assertThat(mWifiManager.getConnectionInfo().getNetworkId()).isEqualTo(-1); + + // Wait for stop to be invoked and ensure that the session id matches. + assertThat(countDownLatchScorer.await(DURATION, TimeUnit.MILLISECONDS)).isTrue(); + assertThat(connectedNetworkScorer.stopSessionId) + .isEqualTo(connectedNetworkScorer.startSessionId); + } finally { + mWifiManager.removeOnWifiUsabilityStatsListener(usabilityStatsListener); + mWifiManager.clearWifiConnectedNetworkScorer(); + uiAutomation.dropShellPermissionIdentity(); + } + } } From f25df0d381c27936d75994268f355537e150d927 Mon Sep 17 00:00:00 2001 From: lesl Date: Fri, 20 Mar 2020 17:47:43 +0800 Subject: [PATCH 0799/1109] cts: unregister softap callback after finish the test Bug: 150307166 Test: atest android.net.wifi.cts.WifiManagerTest Change-Id: If189be91217f4f94e358fc0aedd2bfcc36f96c84 --- .../net/src/android/net/wifi/cts/WifiManagerTest.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index ae5ef75af6..12db0257be 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -1447,11 +1447,11 @@ public class WifiManagerTest extends AndroidTestCase { */ public void testSetGetSoftApConfigurationAndSoftApCapabilityCallback() throws Exception { UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); + TestExecutor executor = new TestExecutor(); + TestSoftApCallback callback = new TestSoftApCallback(mLock); try { uiAutomation.adoptShellPermissionIdentity(); turnOffWifiAndTetheredHotspotIfEnabled(); - TestExecutor executor = new TestExecutor(); - TestSoftApCallback callback = new TestSoftApCallback(mLock); verifyRegisterSoftApCallback(executor, callback); SoftApConfiguration.Builder softApConfigBuilder = new SoftApConfiguration.Builder() @@ -1490,6 +1490,7 @@ public class WifiManagerTest extends AndroidTestCase { verifySetGetSoftApConfig(softApConfigBuilder.build()); } } finally { + mWifiManager.unregisterSoftApCallback(callback); uiAutomation.dropShellPermissionIdentity(); } } @@ -1501,11 +1502,11 @@ public class WifiManagerTest extends AndroidTestCase { public void testStartTetheredHotspotWithChannelConfigAndSoftApStateAndInfoCallback() throws Exception { UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); + TestExecutor executor = new TestExecutor(); + TestSoftApCallback callback = new TestSoftApCallback(mLock); try { uiAutomation.adoptShellPermissionIdentity(); turnOffWifiAndTetheredHotspotIfEnabled(); - TestExecutor executor = new TestExecutor(); - TestSoftApCallback callback = new TestSoftApCallback(mLock); verifyRegisterSoftApCallback(executor, callback); SoftApConfiguration testSoftApConfig = new SoftApConfiguration.Builder() @@ -1544,6 +1545,7 @@ public class WifiManagerTest extends AndroidTestCase { 0 == callback.getCurrentSoftApInfo().getFrequency(); }); } finally { + mWifiManager.unregisterSoftApCallback(callback); uiAutomation.dropShellPermissionIdentity(); } } From 29c4a944064d40a76fab571c1cb597bb46d3c05a Mon Sep 17 00:00:00 2001 From: Nate Jiang Date: Thu, 19 Mar 2020 16:57:03 -0700 Subject: [PATCH 0800/1109] Add cts test for ResponderLocation Bug: 150976615 Test: atest WifiRttTest Change-Id: I830c50d2011ef024b2e758d4558379ab12f1ebae --- .../android/net/wifi/rtt/cts/WifiRttTest.java | 157 +++++++++++++++++- 1 file changed, 156 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java b/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java index d5361d730d..25a90b55a1 100644 --- a/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java +++ b/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java @@ -21,6 +21,7 @@ import static org.mockito.Mockito.mock; import android.net.wifi.ScanResult; import android.net.wifi.rtt.RangingRequest; import android.net.wifi.rtt.RangingResult; +import android.net.wifi.rtt.ResponderLocation; import android.platform.test.annotations.AppModeFull; import com.android.compatibility.common.util.DeviceReportLog; @@ -163,7 +164,8 @@ public class WifiRttTest extends TestBase { // Analyze results assertTrue("Wi-Fi RTT failure rate exceeds threshold: FAIL=" + numFailures + ", ITERATIONS=" - + NUM_OF_RTT_ITERATIONS + ", AP RSSI=" + testAp.level, + + NUM_OF_RTT_ITERATIONS + ", AP RSSI=" + testAp.level + + ", AP SSID=" + testAp.SSID, numFailures <= NUM_OF_RTT_ITERATIONS * MAX_FAILURE_RATE_PERCENT / 100); if (numFailures != NUM_OF_RTT_ITERATIONS) { double distanceAvg = distanceSum / (NUM_OF_RTT_ITERATIONS - numFailures); @@ -213,4 +215,157 @@ public class WifiRttTest extends TestBase { + "many peers", false); } + + /** + * Verify ResponderLocation API + */ + public void testRangingToTestApWithResponderLocation() throws InterruptedException { + if (!shouldTestWifiRtt(getContext())) { + return; + } + // Scan for IEEE 802.11mc supporting APs + ScanResult testAp = scanForTestAp(NUM_SCANS_SEARCHING_FOR_IEEE80211MC_AP); + assertTrue( + "Cannot find any test APs which support RTT / IEEE 802.11mc - please verify that " + + "your test setup includes them!", + testAp != null); + + // Perform RTT operations + RangingRequest request = new RangingRequest.Builder().addAccessPoint(testAp).build(); + ResultCallback callback = new ResultCallback(); + mWifiRttManager.startRanging(request, mExecutor, callback); + assertTrue("Wi-Fi RTT results: no callback! ", + callback.waitForCallback()); + + RangingResult result = callback.getResults().get(0); + assertEquals("Ranging request not success", + result.getStatus(), RangingResult.STATUS_SUCCESS); + ResponderLocation responderLocation = result.getUnverifiedResponderLocation(); + assertNotNull("ResponderLocation should not be null", responderLocation); + assertTrue("ResponderLocation is not valid", responderLocation.isLciSubelementValid()); + + // Check LCI related APIs + int exceptionCount = 0; + int apiCount = 0; + try { + apiCount++; + responderLocation.getLatitudeUncertainty(); + } catch (IllegalStateException e) { + exceptionCount++; + } + try { + apiCount++; + responderLocation.getLatitude(); + } catch (IllegalStateException e) { + exceptionCount++; + } + try { + apiCount++; + responderLocation.getLongitudeUncertainty(); + } catch (IllegalStateException e) { + exceptionCount++; + } + try { + apiCount++; + responderLocation.getLongitude(); + } catch (IllegalStateException e) { + exceptionCount++; + } + try { + apiCount++; + responderLocation.getAltitudeType(); + } catch (IllegalStateException e) { + exceptionCount++; + } + try { + apiCount++; + responderLocation.getAltitudeUncertainty(); + } catch (IllegalStateException e) { + exceptionCount++; + } + try { + apiCount++; + responderLocation.getAltitude(); + } catch (IllegalStateException e) { + exceptionCount++; + } + try { + apiCount++; + responderLocation.getDatum(); + } catch (IllegalStateException e) { + exceptionCount++; + } + try { + apiCount++; + responderLocation.getRegisteredLocationAgreementIndication(); + } catch (IllegalStateException e) { + exceptionCount++; + } + try { + apiCount++; + responderLocation.getLciVersion(); + } catch (IllegalStateException e) { + exceptionCount++; + } + try { + apiCount++; + assertNotNull(responderLocation.toLocation()); + } catch (IllegalStateException e) { + exceptionCount++; + } + // If LCI is not valid, all APIs should throw exception, otherwise no exception. + assertEquals("Exception number should equal to API number", + responderLocation.isLciSubelementValid()? 0 : apiCount, exceptionCount); + + // Verify ZaxisSubelement APIs + apiCount = 0; + exceptionCount = 0; + + try { + apiCount++; + responderLocation.getExpectedToMove(); + } catch (IllegalStateException e) { + exceptionCount++; + } + + try { + apiCount++; + responderLocation.getFloorNumber(); + } catch (IllegalStateException e) { + exceptionCount++; + } + + try { + apiCount++; + responderLocation.getHeightAboveFloorMeters(); + } catch (IllegalStateException e) { + exceptionCount++; + } + + try { + apiCount++; + responderLocation.getHeightAboveFloorUncertaintyMeters(); + } catch (IllegalStateException e) { + exceptionCount++; + } + // If Zaxis is not valid, all APIs should throw exception, otherwise no exception. + assertEquals("Exception number should equal to API number", + responderLocation.isZaxisSubelementValid() ? 0 : apiCount, exceptionCount); + // Verify civic location + if (responderLocation.toCivicLocationAddress() == null) { + assertNull(responderLocation.toCivicLocationSparseArray()); + } else { + assertNotNull(responderLocation.toCivicLocationSparseArray()); + } + // Verify map image + if (responderLocation.getMapImageUri() == null) { + assertNull(responderLocation.getMapImageMimeType()); + } else { + assertNotNull(responderLocation.getMapImageMimeType()); + } + boolean extraInfoOnAssociationIndication = + responderLocation.getExtraInfoOnAssociationIndication(); + assertNotNull("ColocatedBSSID list should be nonNull", + responderLocation.getColocatedBssids()); + } } From 1ccef6fefe605899484106e615b38add25da6f5d Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Fri, 20 Mar 2020 11:58:08 -0700 Subject: [PATCH 0801/1109] WifiMigration: Add test for the config store APIs This only tests that the API does exist, there isn't any other feasible tests for this API surface. Bug: 150973073 Test: atest android.net.wifi.cts.WifiMigrationTest Change-Id: I094e716027a6eb0995b6c20ed351ee12b91fce85 --- .../net/wifi/cts/WifiMigrationTest.java | 57 ++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiMigrationTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiMigrationTest.java index 7d94ad3ff8..c74c177039 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiMigrationTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiMigrationTest.java @@ -16,7 +16,10 @@ package android.net.wifi.cts; +import android.app.ActivityManager; import android.net.wifi.WifiMigration; +import android.os.UserHandle; +import android.os.UserManager; import android.test.AndroidTestCase; public class WifiMigrationTest extends AndroidTestCase { @@ -75,9 +78,61 @@ public class WifiMigrationTest extends AndroidTestCase { */ public void testWifiMigrationSettings() throws Exception { try { - // ensure that this does not crash. WifiMigration.loadFromSettings(getContext()); } catch (Exception ignore) { } } + + /** + * Tests {@link WifiMigration#convertAndRetrieveSharedConfigStoreFile(int)}, + * {@link WifiMigration#convertAndRetrieveUserConfigStoreFile(int, UserHandle)}, + * {@link WifiMigration#removeSharedConfigStoreFile(int)} and + * {@link WifiMigration#removeUserConfigStoreFile(int, UserHandle)}. + */ + public void testWifiMigrationConfigStore() throws Exception { + try { + WifiMigration.convertAndRetrieveSharedConfigStoreFile( + WifiMigration.STORE_FILE_SHARED_GENERAL); + } catch (Exception ignore) { + } + try { + WifiMigration.convertAndRetrieveSharedConfigStoreFile( + WifiMigration.STORE_FILE_SHARED_SOFTAP); + } catch (Exception ignore) { + } + try { + WifiMigration.convertAndRetrieveUserConfigStoreFile( + WifiMigration.STORE_FILE_USER_GENERAL, + UserHandle.of(ActivityManager.getCurrentUser())); + } catch (Exception ignore) { + } + try { + WifiMigration.convertAndRetrieveUserConfigStoreFile( + WifiMigration.STORE_FILE_USER_NETWORK_SUGGESTIONS, + UserHandle.of(ActivityManager.getCurrentUser())); + } catch (Exception ignore) { + } + try { + WifiMigration.removeSharedConfigStoreFile( + WifiMigration.STORE_FILE_SHARED_GENERAL); + } catch (Exception ignore) { + } + try { + WifiMigration.removeSharedConfigStoreFile( + WifiMigration.STORE_FILE_SHARED_SOFTAP); + } catch (Exception ignore) { + } + try { + WifiMigration.removeUserConfigStoreFile( + WifiMigration.STORE_FILE_USER_GENERAL, + UserHandle.of(ActivityManager.getCurrentUser())); + } catch (Exception ignore) { + } + try { + WifiMigration.removeUserConfigStoreFile( + WifiMigration.STORE_FILE_USER_NETWORK_SUGGESTIONS, + UserHandle.of(ActivityManager.getCurrentUser())); + } catch (Exception ignore) { + } + } } From 90e7e6cf3fed3a03b3858032a9718270769b4142 Mon Sep 17 00:00:00 2001 From: Remi NGUYEN VAN Date: Mon, 23 Mar 2020 16:29:46 +0900 Subject: [PATCH 0802/1109] Fix AudioGroupTest on Q The AudioGroup constructor with a Context parameter does not exist on Q devices. Use the previous constructor on older devices. Test: atest CtsNetTestCasesLatestSdk on Q and R devices Bug: 150918852 Change-Id: I24c3e7ab8c7219d6f345943ead3e3b6418fa7f47 --- tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java b/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java index fee8621c70..fc78e96e11 100644 --- a/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java +++ b/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java @@ -21,9 +21,12 @@ import android.net.rtp.AudioCodec; import android.net.rtp.AudioGroup; import android.net.rtp.AudioStream; import android.net.rtp.RtpStream; +import android.os.Build; import android.platform.test.annotations.AppModeFull; import android.test.AndroidTestCase; +import androidx.core.os.BuildCompat; + import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; @@ -62,7 +65,10 @@ public class AudioGroupTest extends AndroidTestCase { mSocketB.connect(mStreamB.getLocalAddress(), mStreamB.getLocalPort()); mStreamB.associate(mSocketB.getLocalAddress(), mSocketB.getLocalPort()); - mGroup = new AudioGroup(mContext); + // BuildCompat.isAtLeastR is documented to return false on release SDKs (including R) + mGroup = Build.VERSION.SDK_INT > Build.VERSION_CODES.Q || BuildCompat.isAtLeastR() + ? new AudioGroup(mContext) + : new AudioGroup(); // Constructor with context argument was introduced in R } @Override From ad92bb63b5eddecf7cdad5e3e43a566143fe86a7 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Mon, 23 Mar 2020 08:06:00 -0700 Subject: [PATCH 0803/1109] WifiManagerTest: Use getPrivilegedConfiguredNetworks() in factory reset test Bug: 152048238 Test: atest android.net.wifi.cts.WifiManagerTest Reproduced the original issue (i.e tests after testFactoryReset failing) with a PSK network on the device & verified that this CL fixes the failures. Change-Id: I56947a78142e971c8da6a1c098ebbd0f1e7d370d --- tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 12db0257be..6613ab9808 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -2166,7 +2166,7 @@ public class WifiManagerTest extends AndroidTestCase { uiAutomation.adoptShellPermissionIdentity(); // These below API's only work with privileged permissions (obtained via shell identity // for test) - savedNetworks = mWifiManager.getConfiguredNetworks(); + savedNetworks = mWifiManager.getPrivilegedConfiguredNetworks(); mWifiManager.factoryReset(); // Ensure all the saved networks are removed. From da85d8b190bfdc745895716410ade45bbf9df07d Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Mon, 23 Mar 2020 09:02:45 -0700 Subject: [PATCH 0804/1109] cts(wifi): Disable scan throttling for tests with startScan Scan throttling could lead to flaky tests. Bug: 152048238 Test: atest android.net.wifi.cts Change-Id: Id314da9238c592fcbfde448231bf86f3cf679e62 --- .../android/net/wifi/cts/ScanResultTest.java | 19 +++++++++++++++++++ .../android/net/wifi/cts/WifiManagerTest.java | 8 ++++++++ .../wifi/cts/WifiNetworkSpecifierTest.java | 8 ++++++++ 3 files changed, 35 insertions(+) diff --git a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java index 161b0b43eb..1977378c1a 100644 --- a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java @@ -34,6 +34,7 @@ import android.net.wifi.WifiManager.WifiLock; import android.platform.test.annotations.AppModeFull; import android.test.AndroidTestCase; +import com.android.compatibility.common.util.ShellIdentityUtils; import com.android.compatibility.common.util.SystemUtil; @AppModeFull(reason = "Cannot get WifiManager in instant app mode") @@ -45,6 +46,8 @@ public class ScanResultTest extends AndroidTestCase { private WifiManager mWifiManager; private WifiLock mWifiLock; private static MySync mMySync; + private boolean mWasVerboseLoggingEnabled; + private boolean mWasScanThrottleEnabled; private static final int STATE_NULL = 0; private static final int STATE_WIFI_CHANGING = 1; @@ -113,6 +116,18 @@ public class ScanResultTest extends AndroidTestCase { mContext.registerReceiver(mReceiver, mIntentFilter); mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); assertThat(mWifiManager).isNotNull(); + + // turn on verbose logging for tests + mWasVerboseLoggingEnabled = ShellIdentityUtils.invokeWithShellPermissions( + () -> mWifiManager.isVerboseLoggingEnabled()); + ShellIdentityUtils.invokeWithShellPermissions( + () -> mWifiManager.setVerboseLoggingEnabled(true)); + // Disable scan throttling for tests. + mWasScanThrottleEnabled = ShellIdentityUtils.invokeWithShellPermissions( + () -> mWifiManager.isScanThrottleEnabled()); + ShellIdentityUtils.invokeWithShellPermissions( + () -> mWifiManager.setScanThrottleEnabled(false)); + mWifiLock = mWifiManager.createWifiLock(TAG); mWifiLock.acquire(); if (!mWifiManager.isWifiEnabled()) @@ -133,6 +148,10 @@ public class ScanResultTest extends AndroidTestCase { mContext.unregisterReceiver(mReceiver); if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true); + ShellIdentityUtils.invokeWithShellPermissions( + () -> mWifiManager.setScanThrottleEnabled(mWasScanThrottleEnabled)); + ShellIdentityUtils.invokeWithShellPermissions( + () -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled)); Thread.sleep(ENABLE_WAIT_MSEC); super.tearDown(); } diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 6613ab9808..9700ca1a6e 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -118,6 +118,7 @@ public class WifiManagerTest extends AndroidTestCase { private final Object mLock = new Object(); private UiDevice mUiDevice; private boolean mWasVerboseLoggingEnabled; + private boolean mWasScanThrottleEnabled; private SoftApConfiguration mOriginalSoftApConfig = null; // Please refer to WifiManager @@ -278,6 +279,11 @@ public class WifiManagerTest extends AndroidTestCase { () -> mWifiManager.isVerboseLoggingEnabled()); ShellIdentityUtils.invokeWithShellPermissions( () -> mWifiManager.setVerboseLoggingEnabled(true)); + // Disable scan throttling for tests. + mWasScanThrottleEnabled = ShellIdentityUtils.invokeWithShellPermissions( + () -> mWifiManager.isScanThrottleEnabled()); + ShellIdentityUtils.invokeWithShellPermissions( + () -> mWifiManager.setScanThrottleEnabled(false)); mWifiLock = mWifiManager.createWifiLock(TAG); mWifiLock.acquire(); @@ -311,6 +317,8 @@ public class WifiManagerTest extends AndroidTestCase { setWifiEnabled(true); mWifiLock.release(); mContext.unregisterReceiver(mReceiver); + ShellIdentityUtils.invokeWithShellPermissions( + () -> mWifiManager.setScanThrottleEnabled(mWasScanThrottleEnabled)); ShellIdentityUtils.invokeWithShellPermissions( () -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled)); // restore original softap config diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java index 2065bb025c..83018fa1cb 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java @@ -71,6 +71,7 @@ public class WifiNetworkSpecifierTest extends AndroidTestCase { private final Object mUiLock = new Object(); private WifiConfiguration mTestNetwork; private boolean mWasVerboseLoggingEnabled; + private boolean mWasScanThrottleEnabled; private static final int DURATION = 10_000; private static final int DURATION_UI_INTERACTION = 15_000; @@ -93,6 +94,11 @@ public class WifiNetworkSpecifierTest extends AndroidTestCase { () -> mWifiManager.isVerboseLoggingEnabled()); ShellIdentityUtils.invokeWithShellPermissions( () -> mWifiManager.setVerboseLoggingEnabled(true)); + // Disable scan throttling for tests. + mWasScanThrottleEnabled = ShellIdentityUtils.invokeWithShellPermissions( + () -> mWifiManager.isScanThrottleEnabled()); + ShellIdentityUtils.invokeWithShellPermissions( + () -> mWifiManager.setScanThrottleEnabled(false)); if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true); mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); @@ -126,6 +132,8 @@ public class WifiNetworkSpecifierTest extends AndroidTestCase { turnScreenOff(); ShellIdentityUtils.invokeWithShellPermissions( () -> mWifiManager.enableNetwork(mTestNetwork.networkId, false)); + ShellIdentityUtils.invokeWithShellPermissions( + () -> mWifiManager.setScanThrottleEnabled(mWasScanThrottleEnabled)); ShellIdentityUtils.invokeWithShellPermissions( () -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled)); super.tearDown(); From 67de87eed06bca9b3bf0bf182338f3cf69f84c95 Mon Sep 17 00:00:00 2001 From: Dan Shi Date: Thu, 19 Mar 2020 12:07:49 -0700 Subject: [PATCH 0805/1109] Add vts10 suite to existing vts tests This is to prepare renaming vts to vts10. Bug: 151896491 Test: local build Exempt-From-Owner-Approval: This CL adds all tests in vts to a new suite vts10. vts10 will be the new name of existing vts suite. This CL won't change test logic or behavior. Change-Id: Ia9af1fbddc66d3c94976a58c36d274425f1fe461 --- tests/cts/hostside/Android.bp | 1 + tests/cts/hostside/app/Android.bp | 1 + tests/cts/hostside/app2/Android.bp | 1 + tests/cts/net/Android.bp | 1 + tests/cts/net/api23Test/Android.bp | 1 + tests/cts/net/appForApi23/Android.bp | 1 + tests/cts/net/native/qtaguid/Android.bp | 1 + 7 files changed, 7 insertions(+) diff --git a/tests/cts/hostside/Android.bp b/tests/cts/hostside/Android.bp index b6f514233a..a8cc95ba5f 100644 --- a/tests/cts/hostside/Android.bp +++ b/tests/cts/hostside/Android.bp @@ -25,6 +25,7 @@ java_test_host { test_suites: [ "cts", "vts", + "vts10", "general-tests", ], } diff --git a/tests/cts/hostside/app/Android.bp b/tests/cts/hostside/app/Android.bp index e988ea4763..8b6d38b821 100644 --- a/tests/cts/hostside/app/Android.bp +++ b/tests/cts/hostside/app/Android.bp @@ -36,6 +36,7 @@ android_test_helper_app { test_suites: [ "cts", "vts", + "vts10", "general-tests", ], } diff --git a/tests/cts/hostside/app2/Android.bp b/tests/cts/hostside/app2/Android.bp index 8a3c8e712a..0bb0d2f631 100644 --- a/tests/cts/hostside/app2/Android.bp +++ b/tests/cts/hostside/app2/Android.bp @@ -24,6 +24,7 @@ android_test_helper_app { test_suites: [ "cts", "vts", + "vts10", "general-tests", ], certificate: ":cts-net-app", diff --git a/tests/cts/net/Android.bp b/tests/cts/net/Android.bp index 624d149776..d77f416557 100644 --- a/tests/cts/net/Android.bp +++ b/tests/cts/net/Android.bp @@ -65,6 +65,7 @@ android_test { test_suites: [ "cts", "vts", + "vts10", "general-tests", ], test_config_template: "AndroidTestTemplate.xml", diff --git a/tests/cts/net/api23Test/Android.bp b/tests/cts/net/api23Test/Android.bp index ffe854e2e9..614a5a2a76 100644 --- a/tests/cts/net/api23Test/Android.bp +++ b/tests/cts/net/api23Test/Android.bp @@ -46,6 +46,7 @@ android_test { test_suites: [ "cts", "vts", + "vts10", "general-tests", ], diff --git a/tests/cts/net/appForApi23/Android.bp b/tests/cts/net/appForApi23/Android.bp index 82e2a08c10..17cfe3821b 100644 --- a/tests/cts/net/appForApi23/Android.bp +++ b/tests/cts/net/appForApi23/Android.bp @@ -27,6 +27,7 @@ android_test { test_suites: [ "cts", "vts", + "vts10", "general-tests", ], diff --git a/tests/cts/net/native/qtaguid/Android.bp b/tests/cts/net/native/qtaguid/Android.bp index c0f0613040..054937b4fa 100644 --- a/tests/cts/net/native/qtaguid/Android.bp +++ b/tests/cts/net/native/qtaguid/Android.bp @@ -43,6 +43,7 @@ cc_test { test_suites: [ "cts", "vts", + "vts10", ], cflags: [ From 01cb32c3321112472f545a1cffccd3c277f70fbb Mon Sep 17 00:00:00 2001 From: Nate Jiang Date: Mon, 23 Mar 2020 11:47:04 -0700 Subject: [PATCH 0806/1109] Add test for aware rtt Bug: 150977837 Test: atest WifiRttTest Change-Id: If19b8708fd76df7f0be3fb5b338b4c58d7279402 --- .../android/net/wifi/rtt/cts/WifiRttTest.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java b/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java index 25a90b55a1..49aa47ec38 100644 --- a/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java +++ b/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java @@ -18,7 +18,9 @@ package android.net.wifi.rtt.cts; import static org.mockito.Mockito.mock; +import android.net.MacAddress; import android.net.wifi.ScanResult; +import android.net.wifi.aware.PeerHandle; import android.net.wifi.rtt.RangingRequest; import android.net.wifi.rtt.RangingResult; import android.net.wifi.rtt.ResponderLocation; @@ -52,6 +54,9 @@ public class WifiRttTest extends TestBase { // Minimum valid RSSI value private static final int MIN_VALID_RSSI = -100; + // Valid Mac Address + private static final MacAddress MAC = MacAddress.fromString("00:01:02:03:04:05"); + /** * Test Wi-Fi RTT ranging operation: * - Scan for visible APs for the test AP (which is validated to support IEEE 802.11mc) @@ -368,4 +373,36 @@ public class WifiRttTest extends TestBase { assertNotNull("ColocatedBSSID list should be nonNull", responderLocation.getColocatedBssids()); } + + /** + * Verify ranging request with aware peer Mac address and peer handle. + */ + public void testAwareRttWithMacAddress() throws InterruptedException { + RangingRequest request = new RangingRequest.Builder() + .addWifiAwarePeer(MAC).build(); + ResultCallback callback = new ResultCallback(); + mWifiRttManager.startRanging(request, mExecutor, callback); + assertTrue("Wi-Fi RTT results: no callback", + callback.waitForCallback()); + List rangingResults = callback.getResults(); + assertNotNull("Wi-Fi RTT results: null results", rangingResults); + assertEquals(1, rangingResults.size()); + assertEquals(RangingResult.STATUS_FAIL, rangingResults.get(0).getStatus()); + } + + /** + * Verify ranging request with aware peer handle. + */ + public void testAwareRttWithPeerHandle() throws InterruptedException { + PeerHandle peerHandle = mock(PeerHandle.class); + RangingRequest request = new RangingRequest.Builder() + .addWifiAwarePeer(peerHandle).build(); + ResultCallback callback = new ResultCallback(); + mWifiRttManager.startRanging(request, mExecutor, callback); + assertTrue("Wi-Fi RTT results: no callback", + callback.waitForCallback()); + List rangingResults = callback.getResults(); + assertNotNull("Wi-Fi RTT results: null results", rangingResults); + assertEquals("Invalid peerHandle should return 0 result", 0, rangingResults.size()); + } } From 06aec03aba4f3e408f241243db5c6fe6d6e6ad03 Mon Sep 17 00:00:00 2001 From: Nate Jiang Date: Mon, 23 Mar 2020 14:57:59 -0700 Subject: [PATCH 0807/1109] Add test for WifiAwareNetworkSpecifier and ParcelablePeerHandle Test WifiAwareNetworkSpecifier satisfiedBy API Test ParcelablePeerHandle parcel Bug: 150975738 Bug: 150976784 Test: atest SingleDeviceTest Change-Id: I56f775774557b34935b7781f57c0b6f7b7e4e9b4 --- .../net/wifi/aware/cts/SingleDeviceTest.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java index 29f091b8b4..8f233244e8 100644 --- a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java +++ b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java @@ -16,7 +16,9 @@ package android.net.wifi.aware.cts; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; +import static org.mockito.Mockito.mock; import android.content.BroadcastReceiver; import android.content.Context; @@ -30,17 +32,21 @@ import android.net.NetworkRequest; import android.net.wifi.WifiManager; import android.net.wifi.aware.AttachCallback; import android.net.wifi.aware.Characteristics; +import android.net.wifi.aware.DiscoverySession; import android.net.wifi.aware.DiscoverySessionCallback; import android.net.wifi.aware.IdentityChangedListener; +import android.net.wifi.aware.ParcelablePeerHandle; import android.net.wifi.aware.PeerHandle; import android.net.wifi.aware.PublishConfig; import android.net.wifi.aware.PublishDiscoverySession; import android.net.wifi.aware.SubscribeConfig; import android.net.wifi.aware.SubscribeDiscoverySession; import android.net.wifi.aware.WifiAwareManager; +import android.net.wifi.aware.WifiAwareNetworkSpecifier; import android.net.wifi.aware.WifiAwareSession; import android.os.Handler; import android.os.HandlerThread; +import android.os.Parcel; import android.platform.test.annotations.AppModeFull; import android.test.AndroidTestCase; @@ -812,6 +818,43 @@ public class SingleDeviceTest extends AndroidTestCase { session.close(); } + /** + * Test WifiAwareNetworkSpecifier. + */ + public void testWifiAwareNetworkSpecifier() { + DiscoverySession session = mock(DiscoverySession.class); + PeerHandle handle = mock(PeerHandle.class); + WifiAwareNetworkSpecifier networkSpecifier = + new WifiAwareNetworkSpecifier.Builder(session, handle).build(); + assertFalse(networkSpecifier.satisfiedBy(null)); + assertTrue(networkSpecifier.satisfiedBy(networkSpecifier)); + + WifiAwareNetworkSpecifier anotherNetworkSpecifier = + new WifiAwareNetworkSpecifier.Builder(session, handle).setPmk(PMK_VALID).build(); + assertFalse(networkSpecifier.satisfiedBy(anotherNetworkSpecifier)); + } + + /** + * Test ParcelablePeerHandle parcel. + */ + public void testParcelablePeerHandle() { + PeerHandle peerHandle = mock(PeerHandle.class); + ParcelablePeerHandle parcelablePeerHandle = new ParcelablePeerHandle(peerHandle); + Parcel parcelW = Parcel.obtain(); + parcelablePeerHandle.writeToParcel(parcelW, 0); + byte[] bytes = parcelW.marshall(); + parcelW.recycle(); + + Parcel parcelR = Parcel.obtain(); + parcelR.unmarshall(bytes, 0, bytes.length); + parcelR.setDataPosition(0); + ParcelablePeerHandle rereadParcelablePeerHandle = + ParcelablePeerHandle.CREATOR.createFromParcel(parcelR); + + assertEquals(parcelablePeerHandle, rereadParcelablePeerHandle); + assertEquals(parcelablePeerHandle.hashCode(), rereadParcelablePeerHandle.hashCode()); + } + // local utilities private WifiAwareSession attachAndGetSession() { From 6b4a05b47485638d85eeec4633468bd4fbc46bf0 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Mon, 23 Mar 2020 15:54:29 -0700 Subject: [PATCH 0808/1109] WifiManagerTest: Use addNetwork + enableNetwork instead of save WifiManager.save() is an asynchronous operation. This is sometime causing the tests to be flaky (dropShellIdentity occurs while this is being processed). Use the synchronous legacy API's instead for rewinding the effects of factory reset. Bug: 152048238 Test: atest android.net.wifi.cts.WifiManagerTest Change-Id: Ibb0e04cf931511fcda1b1a81fd6eda4583196c2e --- tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 9700ca1a6e..3153149629 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -2183,7 +2183,9 @@ public class WifiManagerTest extends AndroidTestCase { // Restore the original saved networks. if (savedNetworks != null) { for (WifiConfiguration network : savedNetworks) { - mWifiManager.save(network, null); + network.networkId = WifiConfiguration.INVALID_NETWORK_ID; + int networkId = mWifiManager.addNetwork(network); + mWifiManager.enableNetwork(networkId, false); } } uiAutomation.dropShellPermissionIdentity(); From 7338a25a99b44d76d431a0e57ca2964bb1ef2098 Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 12 Mar 2020 22:36:18 -0700 Subject: [PATCH 0809/1109] CTS: Add tests for RssiCurve Bug: 151110495 Test: atest android.net.cts.RssiCurveTest Change-Id: Ife157773f7bdb07d62c5b9a66810328d9fd5ac91 --- .../src/android/net/cts/RssiCurveTest.java | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 tests/cts/net/src/android/net/cts/RssiCurveTest.java diff --git a/tests/cts/net/src/android/net/cts/RssiCurveTest.java b/tests/cts/net/src/android/net/cts/RssiCurveTest.java new file mode 100644 index 0000000000..d651b7186b --- /dev/null +++ b/tests/cts/net/src/android/net/cts/RssiCurveTest.java @@ -0,0 +1,102 @@ +/* + * 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.cts; + +import static com.google.common.truth.Truth.assertThat; + +import android.net.RssiCurve; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +/** CTS tests for {@link RssiCurve}. */ +@RunWith(AndroidJUnit4.class) +public class RssiCurveTest { + + @Test + public void lookupScore_constantCurve() { + // One bucket from rssi=-100 to 100 with score 10. + RssiCurve curve = new RssiCurve(-100, 200, new byte[] { 10 }); + assertThat(curve.lookupScore(-200)).isEqualTo(10); + assertThat(curve.lookupScore(-100)).isEqualTo(10); + assertThat(curve.lookupScore(0)).isEqualTo(10); + assertThat(curve.lookupScore(100)).isEqualTo(10); + assertThat(curve.lookupScore(200)).isEqualTo(10); + } + + @Test + public void lookupScore_changingCurve() { + // One bucket from -100 to 0 with score -10, and one bucket from 0 to 100 with score 10. + RssiCurve curve = new RssiCurve(-100, 100, new byte[] { -10, 10 }); + assertThat(curve.lookupScore(-200)).isEqualTo(-10); + assertThat(curve.lookupScore(-100)).isEqualTo(-10); + assertThat(curve.lookupScore(-50)).isEqualTo(-10); + assertThat(curve.lookupScore(0)).isEqualTo(10); + assertThat(curve.lookupScore(50)).isEqualTo(10); + assertThat(curve.lookupScore(100)).isEqualTo(10); + assertThat(curve.lookupScore(200)).isEqualTo(10); + } + + @Test + public void lookupScore_linearCurve() { + // Curve starting at -110, with 15 buckets of width 10 whose scores increases by 10 with + // each bucket. The current active network gets a boost of 15 to its RSSI. + RssiCurve curve = new RssiCurve( + -110, + 10, + new byte[] { -20, -10, 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120 }, + 15); + + assertThat(curve.lookupScore(-120)).isEqualTo(-20); + assertThat(curve.lookupScore(-120, false)).isEqualTo(-20); + assertThat(curve.lookupScore(-120, true)).isEqualTo(-20); + + assertThat(curve.lookupScore(-111)).isEqualTo(-20); + assertThat(curve.lookupScore(-111, false)).isEqualTo(-20); + assertThat(curve.lookupScore(-111, true)).isEqualTo(-10); + + assertThat(curve.lookupScore(-110)).isEqualTo(-20); + assertThat(curve.lookupScore(-110, false)).isEqualTo(-20); + assertThat(curve.lookupScore(-110, true)).isEqualTo(-10); + + assertThat(curve.lookupScore(-105)).isEqualTo(-20); + assertThat(curve.lookupScore(-105, false)).isEqualTo(-20); + assertThat(curve.lookupScore(-105, true)).isEqualTo(0); + + assertThat(curve.lookupScore(-100)).isEqualTo(-10); + assertThat(curve.lookupScore(-100, false)).isEqualTo(-10); + assertThat(curve.lookupScore(-100, true)).isEqualTo(0); + + assertThat(curve.lookupScore(-50)).isEqualTo(40); + assertThat(curve.lookupScore(-50, false)).isEqualTo(40); + assertThat(curve.lookupScore(-50, true)).isEqualTo(50); + + assertThat(curve.lookupScore(0)).isEqualTo(90); + assertThat(curve.lookupScore(0, false)).isEqualTo(90); + assertThat(curve.lookupScore(0, true)).isEqualTo(100); + + assertThat(curve.lookupScore(30)).isEqualTo(120); + assertThat(curve.lookupScore(30, false)).isEqualTo(120); + assertThat(curve.lookupScore(30, true)).isEqualTo(120); + + assertThat(curve.lookupScore(40)).isEqualTo(120); + assertThat(curve.lookupScore(40, false)).isEqualTo(120); + assertThat(curve.lookupScore(40, true)).isEqualTo(120); + } +} From f79818b88b6385010d3b6916720e7d6a7ab1bde5 Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Mon, 23 Mar 2020 18:11:35 +0800 Subject: [PATCH 0810/1109] Test IpConfiguration field count and parceling round trip Add test for IpConfiguration and also address review comments from aosp/1171795. Bug: 139268426 Test: CtsNetTestCasesLatestSdk:android.net.cts.IpConfigurationTest Change-Id: Ib30a98e11bdcd9d473b713f7e4c317172b14f000 --- .../android/net/cts/IpConfigurationTest.java | 78 ++++++------------- 1 file changed, 25 insertions(+), 53 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/IpConfigurationTest.java b/tests/cts/net/src/android/net/cts/IpConfigurationTest.java index 21be35142d..c6bc0770b8 100644 --- a/tests/cts/net/src/android/net/cts/IpConfigurationTest.java +++ b/tests/cts/net/src/android/net/cts/IpConfigurationTest.java @@ -16,6 +16,8 @@ package android.net.cts; +import static com.android.testutils.ParcelUtilsKt.assertParcelSane; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; @@ -37,13 +39,6 @@ import java.util.ArrayList; @RunWith(AndroidJUnit4.class) public final class IpConfigurationTest { - private static final int TYPE_IPASSIGNMENT_STATIC = 0; - private static final int TYPE_IPASSIGNMENT_DHCP = 1; - - private static final int TYPE_PROXY_SETTINGS_NONE = 0; - private static final int TYPE_PROXY_SETTINGS_STATIC = 1; - private static final int TYPE_PROXY_SETTINGS_PAC = 2; - private static final LinkAddress LINKADDR = new LinkAddress("192.0.2.2/25"); private static final InetAddress GATEWAY = InetAddressUtils.parseNumericAddress("192.0.2.1"); private static final InetAddress DNS1 = InetAddressUtils.parseNumericAddress("8.8.8.8"); @@ -76,24 +71,31 @@ public final class IpConfigurationTest { assertIpConfigurationEqual(ipConfig, new IpConfiguration()); assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig)); - ipConfig = createIpConfiguration(TYPE_IPASSIGNMENT_STATIC, - TYPE_PROXY_SETTINGS_PAC); + ipConfig.setStaticIpConfiguration(mStaticIpConfig); + ipConfig.setHttpProxy(mProxy); + + ipConfig.setIpAssignment(IpConfiguration.IpAssignment.STATIC); + ipConfig.setProxySettings(IpConfiguration.ProxySettings.PAC); assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig)); - ipConfig = createIpConfiguration(TYPE_IPASSIGNMENT_STATIC, - TYPE_PROXY_SETTINGS_STATIC); + ipConfig.setIpAssignment(IpConfiguration.IpAssignment.STATIC); + ipConfig.setProxySettings(IpConfiguration.ProxySettings.STATIC); assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig)); - ipConfig = createIpConfiguration(TYPE_IPASSIGNMENT_DHCP, - TYPE_PROXY_SETTINGS_PAC); + ipConfig.setIpAssignment(IpConfiguration.IpAssignment.DHCP); + ipConfig.setProxySettings(IpConfiguration.ProxySettings.PAC); assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig)); - ipConfig = createIpConfiguration(TYPE_IPASSIGNMENT_DHCP, - TYPE_PROXY_SETTINGS_STATIC); + ipConfig.setIpAssignment(IpConfiguration.IpAssignment.DHCP); + ipConfig.setProxySettings(IpConfiguration.ProxySettings.PAC); assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig)); - ipConfig = createIpConfiguration(TYPE_IPASSIGNMENT_DHCP, - TYPE_PROXY_SETTINGS_NONE); + ipConfig.setIpAssignment(IpConfiguration.IpAssignment.DHCP); + ipConfig.setProxySettings(IpConfiguration.ProxySettings.STATIC); + assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig)); + + ipConfig.setIpAssignment(IpConfiguration.IpAssignment.DHCP); + ipConfig.setProxySettings(IpConfiguration.ProxySettings.NONE); assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig)); } @@ -106,46 +108,16 @@ public final class IpConfigurationTest { assertNull(config.getHttpProxy()); } - private IpConfiguration createIpConfiguration(int ipAssignmentType, - int proxySettingType) { - - final IpConfiguration ipConfig = new IpConfiguration(); - - switch (ipAssignmentType) { - case TYPE_IPASSIGNMENT_STATIC: - ipConfig.setIpAssignment(IpConfiguration.IpAssignment.STATIC); - break; - case TYPE_IPASSIGNMENT_DHCP: - ipConfig.setIpAssignment(IpConfiguration.IpAssignment.DHCP); - break; - default: - throw new IllegalArgumentException("Unknown ip assignment type."); - } - - switch (proxySettingType) { - case TYPE_PROXY_SETTINGS_NONE: - ipConfig.setProxySettings(IpConfiguration.ProxySettings.NONE); - break; - case TYPE_PROXY_SETTINGS_STATIC: - ipConfig.setProxySettings(IpConfiguration.ProxySettings.STATIC); - break; - case TYPE_PROXY_SETTINGS_PAC: - ipConfig.setProxySettings(IpConfiguration.ProxySettings.PAC); - break; - default: - throw new IllegalArgumentException("Unknown proxy setting type."); - } - - ipConfig.setStaticIpConfiguration(mStaticIpConfig); - ipConfig.setHttpProxy(mProxy); - - return ipConfig; - } - private void assertIpConfigurationEqual(IpConfiguration source, IpConfiguration target) { assertEquals(source.getIpAssignment(), target.getIpAssignment()); assertEquals(source.getProxySettings(), target.getProxySettings()); assertEquals(source.getHttpProxy(), target.getHttpProxy()); assertEquals(source.getStaticIpConfiguration(), target.getStaticIpConfiguration()); } + + @Test + public void testParcel() { + final IpConfiguration config = new IpConfiguration(); + assertParcelSane(config, 4); + } } From 13694bc4f4e52127ad0e60dc16e576ec4fd93165 Mon Sep 17 00:00:00 2001 From: lesl Date: Tue, 24 Mar 2020 22:52:55 +0800 Subject: [PATCH 0811/1109] cts: setBssid supported for tethered mode hotspot Bug: 152180102 Test: atest android.net.wifi.cts.WifiManagerTest#testSetGetSoftApConfigurationAndSoftApCapabilityCallback Change-Id: I742e8a562046a996d8c69af7c6902ddd75fea72c --- tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 3153149629..4cbdf62a7e 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -1403,13 +1403,13 @@ public class WifiManagerTest extends AndroidTestCase { mWifiManager.setSoftApConfiguration(targetConfig); // Bssid set dodesn't support for tethered hotspot SoftApConfiguration currentConfig = mWifiManager.getSoftApConfiguration(); - assertNull(currentConfig.getBssid()); compareSoftApConfiguration(targetConfig, currentConfig); } private void compareSoftApConfiguration(SoftApConfiguration currentConfig, SoftApConfiguration testSoftApConfig) { assertEquals(currentConfig.getSsid(), testSoftApConfig.getSsid()); + assertEquals(currentConfig.getBssid(), testSoftApConfig.getBssid()); assertEquals(currentConfig.getSecurityType(), testSoftApConfig.getSecurityType()); assertEquals(currentConfig.getPassphrase(), testSoftApConfig.getPassphrase()); assertEquals(currentConfig.isHiddenSsid(), testSoftApConfig.isHiddenSsid()); From 53bc7c3a501d41db02a9a2300740d98261934bd4 Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 19 Mar 2020 21:59:37 -0700 Subject: [PATCH 0812/1109] CTS: Split Wifi tests out of CtsNetTestCases Create CtsWifiTestCases. (dirty cherry-pick from internal branch) Bug: 129133376 Test: atest CtsWifiTestCases Change-Id: Iaa51f7ec86e6b4bfe64dcb26a8d8b818dd356608 Merged-In: Iaa51f7ec86e6b4bfe64dcb26a8d8b818dd356608 --- tests/cts/net/src/android/net/wifi/OWNERS | 5 - .../net/wifi/aware/cts/SingleDeviceTest.java | 787 ------------ .../android/net/wifi/aware/cts/TestUtils.java | 69 -- .../android/net/wifi/cts/ConcurrencyTest.java | 461 ------- .../net/wifi/cts/ConfigParserTest.java | 114 -- .../src/android/net/wifi/cts/FakeKeys.java | 257 ---- .../net/wifi/cts/MulticastLockTest.java | 79 -- .../android/net/wifi/cts/NsdManagerTest.java | 592 --------- .../android/net/wifi/cts/PpsMoParserTest.java | 131 -- .../android/net/wifi/cts/ScanResultTest.java | 233 ---- .../net/wifi/cts/SupplicantStateTest.java | 42 - .../net/wifi/cts/WifiConfigurationTest.java | 51 - .../wifi/cts/WifiEnterpriseConfigTest.java | 796 ------------- .../src/android/net/wifi/cts/WifiFeature.java | 32 - .../android/net/wifi/cts/WifiInfoTest.java | 170 --- .../android/net/wifi/cts/WifiLockTest.java | 90 -- .../android/net/wifi/cts/WifiManagerTest.java | 1056 ----------------- .../net/wifi/p2p/cts/WifiP2pConfigTest.java | 62 - .../android/net/wifi/rtt/cts/TestBase.java | 237 ---- .../android/net/wifi/rtt/cts/WifiRttTest.java | 214 ---- 20 files changed, 5478 deletions(-) delete mode 100644 tests/cts/net/src/android/net/wifi/OWNERS delete mode 100644 tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/aware/cts/TestUtils.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/ConfigParserTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/FakeKeys.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/MulticastLockTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/PpsMoParserTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiFeature.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiLockTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pConfigTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/rtt/cts/TestBase.java delete mode 100644 tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java diff --git a/tests/cts/net/src/android/net/wifi/OWNERS b/tests/cts/net/src/android/net/wifi/OWNERS deleted file mode 100644 index 4a6001bcfe..0000000000 --- a/tests/cts/net/src/android/net/wifi/OWNERS +++ /dev/null @@ -1,5 +0,0 @@ -etancohen@google.com -lorenzo@google.com -mplass@google.com -rpius@google.com -satk@google.com diff --git a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java deleted file mode 100644 index 1901f02cdc..0000000000 --- a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java +++ /dev/null @@ -1,787 +0,0 @@ -/* - * Copyright (C) 2017 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.wifi.aware.cts; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.location.LocationManager; -import android.net.ConnectivityManager; -import android.net.MacAddress; -import android.net.NetworkCapabilities; -import android.net.NetworkRequest; -import android.net.wifi.WifiManager; -import android.net.wifi.aware.AttachCallback; -import android.net.wifi.aware.Characteristics; -import android.net.wifi.aware.DiscoverySessionCallback; -import android.net.wifi.aware.IdentityChangedListener; -import android.net.wifi.aware.PeerHandle; -import android.net.wifi.aware.PublishConfig; -import android.net.wifi.aware.PublishDiscoverySession; -import android.net.wifi.aware.SubscribeConfig; -import android.net.wifi.aware.SubscribeDiscoverySession; -import android.net.wifi.aware.WifiAwareManager; -import android.net.wifi.aware.WifiAwareSession; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.SystemClock; -import android.platform.test.annotations.AppModeFull; -import android.test.AndroidTestCase; - -import com.android.compatibility.common.util.SystemUtil; - -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -/** - * Wi-Fi Aware CTS test suite: single device testing. Performs tests on a single - * device to validate Wi-Fi Aware. - */ -@AppModeFull(reason = "Cannot get WifiAwareManager in instant app mode") -public class SingleDeviceTest extends AndroidTestCase { - private static final String TAG = "WifiAwareCtsTests"; - - // wait for Wi-Fi Aware state changes & network requests callbacks - static private final int WAIT_FOR_AWARE_CHANGE_SECS = 10; // 10 seconds - - private final Object mLock = new Object(); - private final HandlerThread mHandlerThread = new HandlerThread("SingleDeviceTest"); - private final Handler mHandler; - { - mHandlerThread.start(); - mHandler = new Handler(mHandlerThread.getLooper()); - } - - private WifiAwareManager mWifiAwareManager; - private WifiManager mWifiManager; - private WifiManager.WifiLock mWifiLock; - private ConnectivityManager mConnectivityManager; - - // used to store any WifiAwareSession allocated during tests - will clean-up after tests - private List mSessions = new ArrayList<>(); - - private class WifiAwareBroadcastReceiver extends BroadcastReceiver { - private CountDownLatch mBlocker = new CountDownLatch(1); - - @Override - public void onReceive(Context context, Intent intent) { - if (WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED.equals(intent.getAction())) { - mBlocker.countDown(); - } - } - - boolean waitForStateChange() throws InterruptedException { - return mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS); - } - } - - private class AttachCallbackTest extends AttachCallback { - static final int ATTACHED = 0; - static final int ATTACH_FAILED = 1; - static final int ERROR = 2; // no callback: timeout, interruption - - private CountDownLatch mBlocker = new CountDownLatch(1); - private int mCallbackCalled = ERROR; // garbage init - private WifiAwareSession mSession = null; - - @Override - public void onAttached(WifiAwareSession session) { - mCallbackCalled = ATTACHED; - mSession = session; - synchronized (mLock) { - mSessions.add(session); - } - mBlocker.countDown(); - } - - @Override - public void onAttachFailed() { - mCallbackCalled = ATTACH_FAILED; - mBlocker.countDown(); - } - - /** - * Waits for any of the callbacks to be called - or an error (timeout, interruption). - * Returns one of the ATTACHED, ATTACH_FAILED, or ERROR values. - */ - int waitForAnyCallback() { - try { - boolean noTimeout = mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS); - if (noTimeout) { - return mCallbackCalled; - } else { - return ERROR; - } - } catch (InterruptedException e) { - return ERROR; - } - } - - /** - * Access the session created by a callback. Only useful to be called after calling - * waitForAnyCallback() and getting the ATTACHED code back. - */ - WifiAwareSession getSession() { - return mSession; - } - } - - private class IdentityChangedListenerTest extends IdentityChangedListener { - private CountDownLatch mBlocker = new CountDownLatch(1); - private byte[] mMac = null; - - @Override - public void onIdentityChanged(byte[] mac) { - mMac = mac; - mBlocker.countDown(); - } - - /** - * Waits for the listener callback to be called - or an error (timeout, interruption). - * Returns true on callback called, false on error (timeout, interruption). - */ - boolean waitForListener() { - try { - return mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS); - } catch (InterruptedException e) { - return false; - } - } - - /** - * Returns the MAC address of the discovery interface supplied to the triggered callback. - */ - byte[] getMac() { - return mMac; - } - } - - private class DiscoverySessionCallbackTest extends DiscoverySessionCallback { - static final int ON_PUBLISH_STARTED = 0; - static final int ON_SUBSCRIBE_STARTED = 1; - static final int ON_SESSION_CONFIG_UPDATED = 2; - static final int ON_SESSION_CONFIG_FAILED = 3; - static final int ON_SESSION_TERMINATED = 4; - static final int ON_SERVICE_DISCOVERED = 5; - static final int ON_MESSAGE_SEND_SUCCEEDED = 6; - static final int ON_MESSAGE_SEND_FAILED = 7; - static final int ON_MESSAGE_RECEIVED = 8; - - private final Object mLocalLock = new Object(); - - private CountDownLatch mBlocker; - private int mCurrentWaitForCallback; - private ArrayDeque mCallbackQueue = new ArrayDeque<>(); - - private PublishDiscoverySession mPublishDiscoverySession; - private SubscribeDiscoverySession mSubscribeDiscoverySession; - - private void processCallback(int callback) { - synchronized (mLocalLock) { - if (mBlocker != null && mCurrentWaitForCallback == callback) { - mBlocker.countDown(); - } else { - mCallbackQueue.addLast(callback); - } - } - } - - @Override - public void onPublishStarted(PublishDiscoverySession session) { - mPublishDiscoverySession = session; - processCallback(ON_PUBLISH_STARTED); - } - - @Override - public void onSubscribeStarted(SubscribeDiscoverySession session) { - mSubscribeDiscoverySession = session; - processCallback(ON_SUBSCRIBE_STARTED); - } - - @Override - public void onSessionConfigUpdated() { - processCallback(ON_SESSION_CONFIG_UPDATED); - } - - @Override - public void onSessionConfigFailed() { - processCallback(ON_SESSION_CONFIG_FAILED); - } - - @Override - public void onSessionTerminated() { - processCallback(ON_SESSION_TERMINATED); - } - - @Override - public void onServiceDiscovered(PeerHandle peerHandle, byte[] serviceSpecificInfo, - List matchFilter) { - processCallback(ON_SERVICE_DISCOVERED); - } - - @Override - public void onMessageSendSucceeded(int messageId) { - processCallback(ON_MESSAGE_SEND_SUCCEEDED); - } - - @Override - public void onMessageSendFailed(int messageId) { - processCallback(ON_MESSAGE_SEND_FAILED); - } - - @Override - public void onMessageReceived(PeerHandle peerHandle, byte[] message) { - processCallback(ON_MESSAGE_RECEIVED); - } - - /** - * Wait for the specified callback - any of the ON_* constants. Returns a true - * on success (specified callback triggered) or false on failure (timed-out or - * interrupted while waiting for the requested callback). - * - * Note: other callbacks happening while while waiting for the specified callback will - * be queued. - */ - boolean waitForCallback(int callback) { - return waitForCallback(callback, WAIT_FOR_AWARE_CHANGE_SECS); - } - - /** - * Wait for the specified callback - any of the ON_* constants. Returns a true - * on success (specified callback triggered) or false on failure (timed-out or - * interrupted while waiting for the requested callback). - * - * Same as waitForCallback(int callback) execpt that allows specifying a custom timeout. - * The default timeout is a short value expected to be sufficient for all behaviors which - * should happen relatively quickly. Specifying a custom timeout should only be done for - * those cases which are known to take a specific longer period of time. - * - * Note: other callbacks happening while while waiting for the specified callback will - * be queued. - */ - boolean waitForCallback(int callback, int timeoutSec) { - synchronized (mLocalLock) { - boolean found = mCallbackQueue.remove(callback); - if (found) { - return true; - } - - mCurrentWaitForCallback = callback; - mBlocker = new CountDownLatch(1); - } - - try { - return mBlocker.await(timeoutSec, TimeUnit.SECONDS); - } catch (InterruptedException e) { - return false; - } - } - - /** - * Indicates whether the specified callback (any of the ON_* constants) has already - * happened and in the queue. Useful when the order of events is important. - */ - boolean hasCallbackAlreadyHappened(int callback) { - synchronized (mLocalLock) { - return mCallbackQueue.contains(callback); - } - } - - /** - * Returns the last created publish discovery session. - */ - PublishDiscoverySession getPublishDiscoverySession() { - PublishDiscoverySession session = mPublishDiscoverySession; - mPublishDiscoverySession = null; - return session; - } - - /** - * Returns the last created subscribe discovery session. - */ - SubscribeDiscoverySession getSubscribeDiscoverySession() { - SubscribeDiscoverySession session = mSubscribeDiscoverySession; - mSubscribeDiscoverySession = null; - return session; - } - } - - private class NetworkCallbackTest extends ConnectivityManager.NetworkCallback { - private CountDownLatch mBlocker = new CountDownLatch(1); - - @Override - public void onUnavailable() { - mBlocker.countDown(); - } - - /** - * Wait for the onUnavailable() callback to be triggered. Returns true if triggered, - * otherwise (timed-out, interrupted) returns false. - */ - boolean waitForOnUnavailable() { - try { - return mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS); - } catch (InterruptedException e) { - return false; - } - } - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - - assertTrue("Wi-Fi Aware requires Location to be Enabled", - ((LocationManager) getContext().getSystemService( - Context.LOCATION_SERVICE)).isLocationEnabled()); - - mWifiAwareManager = (WifiAwareManager) getContext().getSystemService( - Context.WIFI_AWARE_SERVICE); - assertNotNull("Wi-Fi Aware Manager", mWifiAwareManager); - - mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); - assertNotNull("Wi-Fi Manager", mWifiManager); - mWifiLock = mWifiManager.createWifiLock(TAG); - mWifiLock.acquire(); - if (!mWifiManager.isWifiEnabled()) { - SystemUtil.runShellCommand("svc wifi enable"); - } - - mConnectivityManager = (ConnectivityManager) getContext().getSystemService( - Context.CONNECTIVITY_SERVICE); - assertNotNull("Connectivity Manager", mConnectivityManager); - - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED); - WifiAwareBroadcastReceiver receiver = new WifiAwareBroadcastReceiver(); - mContext.registerReceiver(receiver, intentFilter); - if (!mWifiAwareManager.isAvailable()) { - assertTrue("Timeout waiting for Wi-Fi Aware to change status", - receiver.waitForStateChange()); - assertTrue("Wi-Fi Aware is not available (should be)", mWifiAwareManager.isAvailable()); - } - } - - @Override - protected void tearDown() throws Exception { - if (!TestUtils.shouldTestWifiAware(getContext())) { - super.tearDown(); - return; - } - - synchronized (mLock) { - for (WifiAwareSession session : mSessions) { - // no damage from destroying twice (i.e. ok if test cleaned up after itself already) - session.close(); - } - mSessions.clear(); - } - - super.tearDown(); - } - - /** - * Validate: - * - Characteristics are available - * - Characteristics values are legitimate. Not in the CDD. However, the tested values are - * based on the Wi-Fi Aware protocol. - */ - public void testCharacteristics() { - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - - Characteristics characteristics = mWifiAwareManager.getCharacteristics(); - assertNotNull("Wi-Fi Aware characteristics are null", characteristics); - assertEquals("Service Name Length", characteristics.getMaxServiceNameLength(), 255); - assertEquals("Service Specific Information Length", - characteristics.getMaxServiceSpecificInfoLength(), 255); - assertEquals("Match Filter Length", characteristics.getMaxMatchFilterLength(), 255); - } - - /** - * Validate that on Wi-Fi Aware availability change we get a broadcast + the API returns - * correct status. - */ - public void testAvailabilityStatusChange() throws Exception { - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED); - - // 1. Disable Wi-Fi - WifiAwareBroadcastReceiver receiver1 = new WifiAwareBroadcastReceiver(); - mContext.registerReceiver(receiver1, intentFilter); - SystemUtil.runShellCommand("svc wifi disable"); - - assertTrue("Timeout waiting for Wi-Fi Aware to change status", - receiver1.waitForStateChange()); - assertFalse("Wi-Fi Aware is available (should not be)", mWifiAwareManager.isAvailable()); - - // 2. Enable Wi-Fi - WifiAwareBroadcastReceiver receiver2 = new WifiAwareBroadcastReceiver(); - mContext.registerReceiver(receiver2, intentFilter); - SystemUtil.runShellCommand("svc wifi enable"); - - assertTrue("Timeout waiting for Wi-Fi Aware to change status", - receiver2.waitForStateChange()); - assertTrue("Wi-Fi Aware is not available (should be)", mWifiAwareManager.isAvailable()); - } - - /** - * Validate that can attach to Wi-Fi Aware. - */ - public void testAttachNoIdentity() { - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - - WifiAwareSession session = attachAndGetSession(); - session.close(); - } - - /** - * Validate that can attach to Wi-Fi Aware and get identity information. Use the identity - * information to validate that MAC address changes on every attach. - * - * Note: relies on no other entity using Wi-Fi Aware during the CTS test. Since if it is used - * then the attach/destroy will not correspond to enable/disable and will not result in a new - * MAC address being generated. - */ - public void testAttachDiscoveryAddressChanges() { - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - - final int numIterations = 10; - Set macs = new HashSet<>(); - - for (int i = 0; i < numIterations; ++i) { - AttachCallbackTest attachCb = new AttachCallbackTest(); - IdentityChangedListenerTest identityL = new IdentityChangedListenerTest(); - mWifiAwareManager.attach(attachCb, identityL, mHandler); - assertEquals("Wi-Fi Aware attach: iteration " + i, AttachCallbackTest.ATTACHED, - attachCb.waitForAnyCallback()); - assertTrue("Wi-Fi Aware attach: iteration " + i, identityL.waitForListener()); - - WifiAwareSession session = attachCb.getSession(); - assertNotNull("Wi-Fi Aware session: iteration " + i, session); - - byte[] mac = identityL.getMac(); - assertNotNull("Wi-Fi Aware discovery MAC: iteration " + i, mac); - - session.close(); - - macs.add(new TestUtils.MacWrapper(mac)); - } - - assertEquals("", numIterations, macs.size()); - } - - /** - * Validate a successful publish discovery session lifetime: publish, update publish, destroy. - */ - public void testPublishDiscoverySuccess() { - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - - final String serviceName = "ValidName"; - - WifiAwareSession session = attachAndGetSession(); - - PublishConfig publishConfig = new PublishConfig.Builder().setServiceName( - serviceName).build(); - DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); - - // 1. publish - session.publish(publishConfig, discoveryCb, mHandler); - assertTrue("Publish started", - discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED)); - PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession(); - assertNotNull("Publish session", discoverySession); - - // 2. update-publish - publishConfig = new PublishConfig.Builder().setServiceName( - serviceName).setServiceSpecificInfo("extras".getBytes()).build(); - discoverySession.updatePublish(publishConfig); - assertTrue("Publish update", discoveryCb.waitForCallback( - DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED)); - - // 3. destroy - assertFalse("Publish not terminated", discoveryCb.hasCallbackAlreadyHappened( - DiscoverySessionCallbackTest.ON_SESSION_TERMINATED)); - discoverySession.close(); - - // 4. try update post-destroy: should time-out waiting for cb - discoverySession.updatePublish(publishConfig); - assertFalse("Publish update post destroy", discoveryCb.waitForCallback( - DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED)); - - session.close(); - } - - /** - * Validate that publish with a Time To Live (TTL) setting expires within the specified - * time (and validates that the terminate callback is triggered). - */ - public void testPublishLimitedTtlSuccess() { - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - - final String serviceName = "ValidName"; - final int ttlSec = 5; - - WifiAwareSession session = attachAndGetSession(); - - PublishConfig publishConfig = new PublishConfig.Builder().setServiceName( - serviceName).setTtlSec(ttlSec).setTerminateNotificationEnabled(true).build(); - DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); - - // 1. publish - session.publish(publishConfig, discoveryCb, mHandler); - assertTrue("Publish started", - discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED)); - PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession(); - assertNotNull("Publish session", discoverySession); - - // 2. wait for terminate within 'ttlSec'. - assertTrue("Publish terminated", - discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_SESSION_TERMINATED, - ttlSec + 5)); - - // 3. try update post-termination: should time-out waiting for cb - publishConfig = new PublishConfig.Builder().setServiceName( - serviceName).setServiceSpecificInfo("extras".getBytes()).build(); - discoverySession.updatePublish(publishConfig); - assertFalse("Publish update post terminate", discoveryCb.waitForCallback( - DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED)); - - session.close(); - } - - /** - * Validate a successful subscribe discovery session lifetime: subscribe, update subscribe, - * destroy. - */ - public void testSubscribeDiscoverySuccess() { - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - - final String serviceName = "ValidName"; - - WifiAwareSession session = attachAndGetSession(); - - SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName( - serviceName).build(); - DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); - - // 1. subscribe - session.subscribe(subscribeConfig, discoveryCb, mHandler); - assertTrue("Subscribe started", - discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_SUBSCRIBE_STARTED)); - SubscribeDiscoverySession discoverySession = discoveryCb.getSubscribeDiscoverySession(); - assertNotNull("Subscribe session", discoverySession); - - // 2. update-subscribe - subscribeConfig = new SubscribeConfig.Builder().setServiceName( - serviceName).setServiceSpecificInfo("extras".getBytes()).build(); - discoverySession.updateSubscribe(subscribeConfig); - assertTrue("Subscribe update", discoveryCb.waitForCallback( - DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED)); - - // 3. destroy - assertFalse("Subscribe not terminated", discoveryCb.hasCallbackAlreadyHappened( - DiscoverySessionCallbackTest.ON_SESSION_TERMINATED)); - discoverySession.close(); - - // 4. try update post-destroy: should time-out waiting for cb - discoverySession.updateSubscribe(subscribeConfig); - assertFalse("Subscribe update post destroy", discoveryCb.waitForCallback( - DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED)); - - session.close(); - } - - /** - * Validate that subscribe with a Time To Live (TTL) setting expires within the specified - * time (and validates that the terminate callback is triggered). - */ - public void testSubscribeLimitedTtlSuccess() { - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - - final String serviceName = "ValidName"; - final int ttlSec = 5; - - WifiAwareSession session = attachAndGetSession(); - - SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName( - serviceName).setTtlSec(ttlSec).setTerminateNotificationEnabled(true).build(); - DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); - - // 1. subscribe - session.subscribe(subscribeConfig, discoveryCb, mHandler); - assertTrue("Subscribe started", - discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_SUBSCRIBE_STARTED)); - SubscribeDiscoverySession discoverySession = discoveryCb.getSubscribeDiscoverySession(); - assertNotNull("Subscribe session", discoverySession); - - // 2. wait for terminate within 'ttlSec'. - assertTrue("Subscribe terminated", - discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_SESSION_TERMINATED, - ttlSec + 5)); - - // 3. try update post-termination: should time-out waiting for cb - subscribeConfig = new SubscribeConfig.Builder().setServiceName( - serviceName).setServiceSpecificInfo("extras".getBytes()).build(); - discoverySession.updateSubscribe(subscribeConfig); - assertFalse("Subscribe update post terminate", discoveryCb.waitForCallback( - DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED)); - - session.close(); - } - - /** - * Test the send message flow. Since testing single device cannot send to a real peer - - * validate that sending to a bogus peer fails. - */ - public void testSendMessageFail() { - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - - WifiAwareSession session = attachAndGetSession(); - - PublishConfig publishConfig = new PublishConfig.Builder().setServiceName( - "ValidName").build(); - DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); - - // 1. publish - session.publish(publishConfig, discoveryCb, mHandler); - assertTrue("Publish started", - discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED)); - PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession(); - assertNotNull("Publish session", discoverySession); - - // 2. send a message with a null peer-handle - expect exception - try { - discoverySession.sendMessage(null, -1290, "some message".getBytes()); - fail("Expected IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // empty - } - - discoverySession.close(); - session.close(); - } - - /** - * Request an Aware data-path (open) as a Responder with an arbitrary peer MAC address. Validate - * that receive an onUnavailable() callback. - */ - public void testDataPathOpenOutOfBandFail() { - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - MacAddress mac = MacAddress.fromString("00:01:02:03:04:05"); - - // 1. initialize Aware: only purpose is to make sure it is available for OOB data-path - WifiAwareSession session = attachAndGetSession(); - - PublishConfig publishConfig = new PublishConfig.Builder().setServiceName( - "ValidName").build(); - DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); - session.publish(publishConfig, discoveryCb, mHandler); - assertTrue("Publish started", - discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED)); - - // 2. request an AWARE network - NetworkCallbackTest networkCb = new NetworkCallbackTest(); - NetworkRequest nr = new NetworkRequest.Builder().addTransportType( - NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier( - session.createNetworkSpecifierOpen( - WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, - mac.toByteArray())).build(); - mConnectivityManager.requestNetwork(nr, networkCb); - assertTrue("OnUnavailable not received", networkCb.waitForOnUnavailable()); - - session.close(); - } - - /** - * Request an Aware data-path (encrypted) as a Responder with an arbitrary peer MAC address. - * Validate that receive an onUnavailable() callback. - */ - public void testDataPathPassphraseOutOfBandFail() { - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - MacAddress mac = MacAddress.fromString("00:01:02:03:04:05"); - - // 1. initialize Aware: only purpose is to make sure it is available for OOB data-path - WifiAwareSession session = attachAndGetSession(); - - PublishConfig publishConfig = new PublishConfig.Builder().setServiceName( - "ValidName").build(); - DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); - session.publish(publishConfig, discoveryCb, mHandler); - assertTrue("Publish started", - discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED)); - - // 2. request an AWARE network - NetworkCallbackTest networkCb = new NetworkCallbackTest(); - NetworkRequest nr = new NetworkRequest.Builder().addTransportType( - NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier( - session.createNetworkSpecifierPassphrase( - WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, mac.toByteArray(), - "abcdefghihk")).build(); - mConnectivityManager.requestNetwork(nr, networkCb); - assertTrue("OnUnavailable not received", networkCb.waitForOnUnavailable()); - - session.close(); - } - - // local utilities - - private WifiAwareSession attachAndGetSession() { - AttachCallbackTest attachCb = new AttachCallbackTest(); - mWifiAwareManager.attach(attachCb, mHandler); - int cbCalled = attachCb.waitForAnyCallback(); - assertEquals("Wi-Fi Aware attach", AttachCallbackTest.ATTACHED, cbCalled); - - WifiAwareSession session = attachCb.getSession(); - assertNotNull("Wi-Fi Aware session", session); - - return session; - } -} diff --git a/tests/cts/net/src/android/net/wifi/aware/cts/TestUtils.java b/tests/cts/net/src/android/net/wifi/aware/cts/TestUtils.java deleted file mode 100644 index a12c8bb0d2..0000000000 --- a/tests/cts/net/src/android/net/wifi/aware/cts/TestUtils.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2017 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.wifi.aware.cts; - -import android.content.Context; -import android.content.pm.PackageManager; - -import java.util.Arrays; - -/** - * Test utilities for Wi-Fi Aware CTS test suite. - */ -class TestUtils { - static final String TAG = "WifiAwareCtsTests"; - - /** - * Returns a flag indicating whether or not Wi-Fi Aware should be tested. Wi-Fi Aware - * should be tested if the feature is supported on the current device. - */ - static boolean shouldTestWifiAware(Context context) { - final PackageManager pm = context.getPackageManager(); - return pm.hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE); - } - - /** - * Wraps a byte[] (MAC address representation). Intended to provide hash and equality operators - * so that the MAC address can be used in containers. - */ - static class MacWrapper { - private byte[] mMac; - - MacWrapper(byte[] mac) { - mMac = mac; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (!(o instanceof MacWrapper)) { - return false; - } - - MacWrapper lhs = (MacWrapper) o; - return Arrays.equals(mMac, lhs.mMac); - } - - @Override - public int hashCode() { - return Arrays.hashCode(mMac); - } - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java b/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java deleted file mode 100644 index ba0832f8b6..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java +++ /dev/null @@ -1,461 +0,0 @@ -/* - * Copyright (C) 2012 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.wifi.cts; - -import static org.junit.Assert.assertNotEquals; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.net.ConnectivityManager; -import android.net.ConnectivityManager.NetworkCallback; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.NetworkInfo; -import android.net.NetworkRequest; -import android.net.wifi.WifiManager; -import android.net.wifi.p2p.WifiP2pManager; -import android.provider.Settings; -import android.platform.test.annotations.AppModeFull; -import android.test.AndroidTestCase; -import android.util.Log; - -import com.android.compatibility.common.util.SystemUtil; - -import java.util.Arrays; -import java.util.BitSet; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -@AppModeFull(reason = "Cannot get WifiManager in instant app mode") -public class ConcurrencyTest extends AndroidTestCase { - private class MySync { - static final int WIFI_STATE = 0; - static final int P2P_STATE = 1; - static final int DISCOVERY_STATE = 2; - static final int NETWORK_INFO = 3; - - public BitSet pendingSync = new BitSet(); - - public int expectedWifiState; - public int expectedP2pState; - public int expectedDiscoveryState; - public NetworkInfo expectedNetworkInfo; - } - - private class MyResponse { - public boolean valid = false; - - public boolean success; - public int p2pState; - public int discoveryState; - public NetworkInfo networkInfo; - } - - private WifiManager mWifiManager; - private WifiP2pManager mWifiP2pManager; - private WifiP2pManager.Channel mWifiP2pChannel; - private MySync mMySync = new MySync(); - private MyResponse mMyResponse = new MyResponse(); - - private static final String TAG = "ConcurrencyTest"; - private static final int TIMEOUT_MSEC = 6000; - private static final int WAIT_MSEC = 60; - private static final int DURATION = 10000; - private IntentFilter mIntentFilter; - private final BroadcastReceiver mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - final String action = intent.getAction(); - if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { - synchronized (mMySync) { - mMySync.pendingSync.set(MySync.WIFI_STATE); - mMySync.expectedWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, - WifiManager.WIFI_STATE_DISABLED); - mMySync.notify(); - } - } else if(action.equals(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION)) { - synchronized (mMySync) { - mMySync.pendingSync.set(MySync.P2P_STATE); - mMySync.expectedP2pState = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, - WifiP2pManager.WIFI_P2P_STATE_DISABLED); - mMySync.notify(); - } - } else if (action.equals(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION)) { - synchronized (mMySync) { - mMySync.pendingSync.set(MySync.DISCOVERY_STATE); - mMySync.expectedDiscoveryState = intent.getIntExtra( - WifiP2pManager.EXTRA_DISCOVERY_STATE, - WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED); - mMySync.notify(); - } - } else if (action.equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) { - synchronized (mMySync) { - mMySync.pendingSync.set(MySync.NETWORK_INFO); - mMySync.expectedNetworkInfo = (NetworkInfo) intent.getExtra( - WifiP2pManager.EXTRA_NETWORK_INFO, null); - mMySync.notify(); - } - } - } - }; - - @Override - protected void setUp() throws Exception { - super.setUp(); - if (!WifiFeature.isWifiSupported(getContext()) && - !WifiFeature.isP2pSupported(getContext())) { - // skip the test if WiFi && p2p are not supported - return; - } - mIntentFilter = new IntentFilter(); - mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); - mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); - mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION); - mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); - - mContext.registerReceiver(mReceiver, mIntentFilter); - mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); - assertNotNull(mWifiManager); - if (mWifiManager.isWifiEnabled()) { - SystemUtil.runShellCommand("svc wifi disable"); - Thread.sleep(DURATION); - } - assertTrue(!mWifiManager.isWifiEnabled()); - mMySync.expectedWifiState = WifiManager.WIFI_STATE_DISABLED; - mMySync.expectedP2pState = WifiP2pManager.WIFI_P2P_STATE_DISABLED; - mMySync.expectedDiscoveryState = WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED; - mMySync.expectedNetworkInfo = null; - } - - @Override - protected void tearDown() throws Exception { - if (!WifiFeature.isWifiSupported(getContext()) && - !WifiFeature.isP2pSupported(getContext())) { - // skip the test if WiFi and p2p are not supported - super.tearDown(); - return; - } - mContext.unregisterReceiver(mReceiver); - - enableWifi(); - super.tearDown(); - } - - private boolean waitForBroadcasts(List waitSyncList) { - synchronized (mMySync) { - long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; - while (System.currentTimeMillis() < timeout) { - List handledSyncList = waitSyncList.stream() - .filter(w -> mMySync.pendingSync.get(w)) - .collect(Collectors.toList()); - handledSyncList.forEach(w -> mMySync.pendingSync.clear(w)); - waitSyncList.removeAll(handledSyncList); - if (waitSyncList.isEmpty()) { - break; - } - try { - mMySync.wait(WAIT_MSEC); - } catch (InterruptedException e) { } - } - if (!waitSyncList.isEmpty()) { - Log.i(TAG, "Missing broadcast: " + waitSyncList); - } - return waitSyncList.isEmpty(); - } - } - - private boolean waitForBroadcasts(int waitSingleSync) { - return waitForBroadcasts( - new LinkedList(Arrays.asList(waitSingleSync))); - } - - private boolean waitForServiceResponse(MyResponse waitResponse) { - synchronized (waitResponse) { - long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; - while (System.currentTimeMillis() < timeout) { - try { - waitResponse.wait(WAIT_MSEC); - } catch (InterruptedException e) { } - - if (waitResponse.valid) { - return true; - } - } - return false; - } - } - - // Return true if location is enabled. - private boolean isLocationEnabled() { - return Settings.Secure.getInt(getContext().getContentResolver(), - Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF) - != Settings.Secure.LOCATION_MODE_OFF; - } - - // Returns true if the device has location feature. - private boolean hasLocationFeature() { - return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION); - } - - private void resetResponse(MyResponse responseObj) { - synchronized (responseObj) { - responseObj.valid = false; - responseObj.networkInfo = null; - } - } - - /* - * Enables Wifi and block until connection is established. - */ - private void enableWifi() throws InterruptedException { - if (!mWifiManager.isWifiEnabled()) { - SystemUtil.runShellCommand("svc wifi enable"); - } - - ConnectivityManager cm = - (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkRequest request = - new NetworkRequest.Builder().addTransportType(NetworkCapabilities.TRANSPORT_WIFI) - .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) - .build(); - final CountDownLatch latch = new CountDownLatch(1); - NetworkCallback networkCallback = new NetworkCallback() { - @Override - public void onAvailable(Network network) { - latch.countDown(); - } - }; - cm.registerNetworkCallback(request, networkCallback); - latch.await(DURATION, TimeUnit.MILLISECONDS); - - cm.unregisterNetworkCallback(networkCallback); - } - - private boolean setupWifiP2p() { - // Cannot support p2p alone - if (!WifiFeature.isWifiSupported(getContext())) { - assertTrue(!WifiFeature.isP2pSupported(getContext())); - return false; - } - - if (!WifiFeature.isP2pSupported(getContext())) { - // skip the test if p2p is not supported - return false; - } - - if (!hasLocationFeature()) { - Log.d(TAG, "Skipping test as location is not supported"); - return false; - } - if (!isLocationEnabled()) { - fail("Please enable location for this test - since P-release WiFi Direct" - + " needs Location enabled."); - } - - mWifiP2pManager = - (WifiP2pManager) getContext().getSystemService(Context.WIFI_P2P_SERVICE); - mWifiP2pChannel = mWifiP2pManager.initialize( - getContext(), getContext().getMainLooper(), null); - - assertNotNull(mWifiP2pManager); - assertNotNull(mWifiP2pChannel); - - long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; - while (!mWifiManager.isWifiEnabled() && System.currentTimeMillis() < timeout) { - try { - enableWifi(); - } catch (InterruptedException e) { } - } - - assertTrue(mWifiManager.isWifiEnabled()); - - assertTrue(waitForBroadcasts( - new LinkedList( - Arrays.asList(MySync.WIFI_STATE, MySync.P2P_STATE)))); - - assertEquals(WifiManager.WIFI_STATE_ENABLED, mMySync.expectedWifiState); - assertEquals(WifiP2pManager.WIFI_P2P_STATE_ENABLED, mMySync.expectedP2pState); - - assertTrue(waitForBroadcasts(MySync.NETWORK_INFO)); - // wait for changing to EnabledState - assertNotNull(mMySync.expectedNetworkInfo); - - return true; - } - - public void testConcurrency() { - if (!setupWifiP2p()) { - return; - } - - resetResponse(mMyResponse); - mWifiP2pManager.requestP2pState(mWifiP2pChannel, new WifiP2pManager.P2pStateListener() { - @Override - public void onP2pStateAvailable(int state) { - synchronized (mMyResponse) { - mMyResponse.valid = true; - mMyResponse.p2pState = state; - mMyResponse.notify(); - } - } - }); - assertTrue(waitForServiceResponse(mMyResponse)); - assertEquals(WifiP2pManager.WIFI_P2P_STATE_ENABLED, mMyResponse.p2pState); - } - - public void testRequestDiscoveryState() { - if (!setupWifiP2p()) { - return; - } - - resetResponse(mMyResponse); - mWifiP2pManager.requestDiscoveryState( - mWifiP2pChannel, new WifiP2pManager.DiscoveryStateListener() { - @Override - public void onDiscoveryStateAvailable(int state) { - synchronized (mMyResponse) { - mMyResponse.valid = true; - mMyResponse.discoveryState = state; - mMyResponse.notify(); - } - } - }); - assertTrue(waitForServiceResponse(mMyResponse)); - assertEquals(WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED, mMyResponse.discoveryState); - - resetResponse(mMyResponse); - mWifiP2pManager.discoverPeers(mWifiP2pChannel, new WifiP2pManager.ActionListener() { - @Override - public void onSuccess() { - synchronized (mMyResponse) { - mMyResponse.valid = true; - mMyResponse.success = true; - mMyResponse.notify(); - } - } - - @Override - public void onFailure(int reason) { - synchronized (mMyResponse) { - Log.d(TAG, "discoveryPeers failure reason: " + reason); - mMyResponse.valid = true; - mMyResponse.success = false; - mMyResponse.notify(); - } - } - }); - assertTrue(waitForServiceResponse(mMyResponse)); - assertTrue(mMyResponse.success); - assertTrue(waitForBroadcasts(MySync.DISCOVERY_STATE)); - - resetResponse(mMyResponse); - mWifiP2pManager.requestDiscoveryState(mWifiP2pChannel, - new WifiP2pManager.DiscoveryStateListener() { - @Override - public void onDiscoveryStateAvailable(int state) { - synchronized (mMyResponse) { - mMyResponse.valid = true; - mMyResponse.discoveryState = state; - mMyResponse.notify(); - } - } - }); - assertTrue(waitForServiceResponse(mMyResponse)); - assertEquals(WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED, mMyResponse.discoveryState); - - mWifiP2pManager.stopPeerDiscovery(mWifiP2pChannel, null); - } - - public void testRequestNetworkInfo() { - if (!setupWifiP2p()) { - return; - } - - resetResponse(mMyResponse); - mWifiP2pManager.requestNetworkInfo(mWifiP2pChannel, - new WifiP2pManager.NetworkInfoListener() { - @Override - public void onNetworkInfoAvailable(NetworkInfo info) { - synchronized (mMyResponse) { - mMyResponse.valid = true; - mMyResponse.networkInfo = info; - mMyResponse.notify(); - } - } - }); - assertTrue(waitForServiceResponse(mMyResponse)); - assertNotNull(mMyResponse.networkInfo); - // The state might be IDLE, DISCONNECTED, FAILED before a connection establishment. - // Just ensure the state is NOT CONNECTED. - assertNotEquals(NetworkInfo.DetailedState.CONNECTED, - mMySync.expectedNetworkInfo.getDetailedState()); - - resetResponse(mMyResponse); - mWifiP2pManager.createGroup(mWifiP2pChannel, new WifiP2pManager.ActionListener() { - @Override - public void onSuccess() { - synchronized (mMyResponse) { - mMyResponse.valid = true; - mMyResponse.success = true; - mMyResponse.notify(); - } - } - - @Override - public void onFailure(int reason) { - synchronized (mMyResponse) { - Log.d(TAG, "createGroup failure reason: " + reason); - mMyResponse.valid = true; - mMyResponse.success = false; - mMyResponse.notify(); - } - } - }); - assertTrue(waitForServiceResponse(mMyResponse)); - assertTrue(mMyResponse.success); - assertTrue(waitForBroadcasts(MySync.NETWORK_INFO)); - assertNotNull(mMySync.expectedNetworkInfo); - assertEquals(NetworkInfo.DetailedState.CONNECTED, - mMySync.expectedNetworkInfo.getDetailedState()); - - resetResponse(mMyResponse); - mWifiP2pManager.requestNetworkInfo(mWifiP2pChannel, - new WifiP2pManager.NetworkInfoListener() { - @Override - public void onNetworkInfoAvailable(NetworkInfo info) { - synchronized (mMyResponse) { - mMyResponse.valid = true; - mMyResponse.networkInfo = info; - mMyResponse.notify(); - } - } - }); - assertTrue(waitForServiceResponse(mMyResponse)); - assertNotNull(mMyResponse.networkInfo); - assertEquals(NetworkInfo.DetailedState.CONNECTED, - mMyResponse.networkInfo.getDetailedState()); - - mWifiP2pManager.removeGroup(mWifiP2pChannel, null); - } - -} diff --git a/tests/cts/net/src/android/net/wifi/cts/ConfigParserTest.java b/tests/cts/net/src/android/net/wifi/cts/ConfigParserTest.java deleted file mode 100644 index 52ed2a6d73..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/ConfigParserTest.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2017 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.wifi.cts; - -import android.net.wifi.hotspot2.ConfigParser; -import android.net.wifi.hotspot2.PasspointConfiguration; -import android.net.wifi.hotspot2.pps.Credential; -import android.net.wifi.hotspot2.pps.HomeSp; -import android.test.AndroidTestCase; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.Arrays; - -/** - * CTS tests for Hotspot 2.0 Release 1 installation file parsing API. - */ -public class ConfigParserTest extends AndroidTestCase { - /** - * Hotspot 2.0 Release 1 installation file that contains a Passpoint profile and a - * CA (Certificate Authority) X.509 certificate {@link FakeKeys#CA_CERT0}. - */ - private static final String PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT = - "assets/HSR1ProfileWithCACert.base64"; - - /** - * Read the content of the given resource file into a String. - * - * @param filename String name of the file - * @return String - * @throws IOException - */ - private String loadResourceFile(String filename) throws IOException { - InputStream in = getClass().getClassLoader().getResourceAsStream(filename); - BufferedReader reader = new BufferedReader(new InputStreamReader(in)); - StringBuilder builder = new StringBuilder(); - String line; - while ((line = reader.readLine()) != null) { - builder.append(line).append("\n"); - } - - return builder.toString(); - } - - /** - * Generate a {@link PasspointConfiguration} that matches the configuration specified in the - * XML file {@link #PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT}. - * - * @return {@link PasspointConfiguration} - */ - private PasspointConfiguration generateConfigurationFromProfile() { - PasspointConfiguration config = new PasspointConfiguration(); - - // HomeSP configuration. - HomeSp homeSp = new HomeSp(); - homeSp.setFriendlyName("Century House"); - homeSp.setFqdn("mi6.co.uk"); - homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L}); - config.setHomeSp(homeSp); - - // Credential configuration. - Credential credential = new Credential(); - credential.setRealm("shaken.stirred.com"); - Credential.UserCredential userCredential = new Credential.UserCredential(); - userCredential.setUsername("james"); - userCredential.setPassword("Ym9uZDAwNw=="); - userCredential.setEapType(21); - userCredential.setNonEapInnerMethod("MS-CHAP-V2"); - credential.setUserCredential(userCredential); - Credential.CertificateCredential certCredential = new Credential.CertificateCredential(); - certCredential.setCertType("x509v3"); - byte[] certSha256Fingerprint = new byte[32]; - Arrays.fill(certSha256Fingerprint, (byte)0x1f); - certCredential.setCertSha256Fingerprint(certSha256Fingerprint); - credential.setCertCredential(certCredential); - Credential.SimCredential simCredential = new Credential.SimCredential(); - simCredential.setImsi("imsi"); - simCredential.setEapType(24); - credential.setSimCredential(simCredential); - credential.setCaCertificate(FakeKeys.CA_CERT0); - config.setCredential(credential); - return config; - } - - /** - * Verify a valid installation file is parsed successfully with the matching contents. - * - * @throws Exception - */ - public void testParseConfigFile() throws Exception { - String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT); - PasspointConfiguration expectedConfig = generateConfigurationFromProfile(); - PasspointConfiguration actualConfig = - ConfigParser.parsePasspointConfig( - "application/x-wifi-config", configStr.getBytes()); - assertTrue(actualConfig.equals(expectedConfig)); - } -} \ No newline at end of file diff --git a/tests/cts/net/src/android/net/wifi/cts/FakeKeys.java b/tests/cts/net/src/android/net/wifi/cts/FakeKeys.java deleted file mode 100644 index f8753017db..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/FakeKeys.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (C) 2016 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.wifi.cts; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; - -/** - * A class containing test certificates and private keys. - */ -public class FakeKeys { - private static final String CA_CERT0_STRING = "-----BEGIN CERTIFICATE-----\n" + - "MIIDKDCCAhCgAwIBAgIJAILlFdwzLVurMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV\n" + - "BAMTB0VBUCBDQTEwHhcNMTYwMTEyMTE1MDE1WhcNMjYwMTA5MTE1MDE1WjASMRAw\n" + - "DgYDVQQDEwdFQVAgQ0ExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n" + - "znAPUz26Msae4ws43czR41/J2QtrSIZUKmVUsVumDbYHrPNvTXKSMXAcewORDQYX\n" + - "RqvHvpn8CscB1+oGXZvHwxj4zV0WKoK2zeXkau3vcyl3HIKupJfq2TEACefVjj0t\n" + - "JW+X35PGWp9/H5zIUNVNVjS7Ums84IvKhRB8512PB9UyHagXYVX5GWpAcVpyfrlR\n" + - "FI9Qdhh+Pbk0uyktdbf/CdfgHOoebrTtwRljM0oDtX+2Cv6j0wBK7hD8pPvf1+uy\n" + - "GzczigAU/4Kw7eZqydf9B+5RupR+IZipX41xEiIrKRwqi517WWzXcjaG2cNbf451\n" + - "xpH5PnV3i1tq04jMGQUzFwIDAQABo4GAMH4wHQYDVR0OBBYEFIwX4vs8BiBcScod\n" + - "5noZHRM8E4+iMEIGA1UdIwQ7MDmAFIwX4vs8BiBcScod5noZHRM8E4+ioRakFDAS\n" + - "MRAwDgYDVQQDEwdFQVAgQ0ExggkAguUV3DMtW6swDAYDVR0TBAUwAwEB/zALBgNV\n" + - "HQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAFfQqOTA7Rv7K+luQ7pnas4BYwHE\n" + - "9GEP/uohv6KOy0TGQFbrRTjFoLVNB9BZ1ymMDZ0/TIwIUc7wi7a8t5mEqYH153wW\n" + - "aWooiSjyLLhuI4sNrNCOtisdBq2r2MFXt6h0mAQYOPv8R8K7/fgSxGFqzhyNmmVL\n" + - "1qBJldx34SpwsTALQVPb4hGwJzZfr1PcpEQx6xMnTl8xEWZE3Ms99uaUxbQqIwRu\n" + - "LgAOkNCmY2m89VhzaHJ1uV85AdM/tD+Ysmlnnjt9LRCejbBipjIGjOXrg1JP+lxV\n" + - "muM4vH+P/mlmxsPPz0d65b+EGmJZpoLkO/tdNNvCYzjJpTEWpEsO6NMhKYo=\n" + - "-----END CERTIFICATE-----\n"; - public static final X509Certificate CA_CERT0 = loadCertificate(CA_CERT0_STRING); - - private static final String CA_CERT1_STRING = "-----BEGIN CERTIFICATE-----\n" + - "MIIDKDCCAhCgAwIBAgIJAOM5SzKO2pzCMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV\n" + - "BAMTB0VBUCBDQTAwHhcNMTYwMTEyMDAxMDQ3WhcNMjYwMTA5MDAxMDQ3WjASMRAw\n" + - "DgYDVQQDEwdFQVAgQ0EwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n" + - "89ug+IEKVQXnJGKg5g4uVHg6J/8iRUxR5k2eH5o03hrJNMfN2D+cBe/wCiZcnWbI\n" + - "GbGZACWm2nQth2wy9Zgm2LOd3b4ocrHYls3XLq6Qb5Dd7a0JKU7pdGufiNVEkrmF\n" + - "EB+N64wgwH4COTvCiN4erp5kyJwkfqAl2xLkZo0C464c9XoyQOXbmYD9A8v10wZu\n" + - "jyNsEo7Nr2USyw+qhjWSbFbEirP77Tvx+7pJQJwdtk1V9Tn73T2dGF2WHYejei9S\n" + - "mcWpdIUqsu9etYH+zDmtu7I1xlkwiaVsNr2+D+qaCJyOYqrDTKVNK5nmbBPXDWZc\n" + - "NoDbTOoqquX7xONpq9M6jQIDAQABo4GAMH4wHQYDVR0OBBYEFAZ3A2S4qJZZwuNY\n" + - "wkJ6mAdc0gVdMEIGA1UdIwQ7MDmAFAZ3A2S4qJZZwuNYwkJ6mAdc0gVdoRakFDAS\n" + - "MRAwDgYDVQQDEwdFQVAgQ0EwggkA4zlLMo7anMIwDAYDVR0TBAUwAwEB/zALBgNV\n" + - "HQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAHmdMwEhtys4d0E+t7owBmoVR+lU\n" + - "hMCcRtWs8YKX5WIM2kTweT0h/O1xwE1mWmRv/IbDAEb8od4BjAQLhIcolStr2JaO\n" + - "9ZzyxjOnNzqeErh/1DHDbb/moPpqfeJ8YiEz7nH/YU56Q8iCPO7TsgS0sNNE7PfN\n" + - "IUsBW0yHRgpQ4OxWmiZG2YZWiECRzAC0ecPzo59N5iH4vLQIMTMYquiDeMPQnn1e\n" + - "NDGxG8gCtDKIaS6tMg3a28MvWB094pr2ETou8O1C8Ji0Y4hE8QJmSdT7I4+GZjgW\n" + - "g94DZ5RiL7sdp3vC48CXOmeT61YBIvhGUsE1rPhXqkpqQ3Z3C4TFF0jXZZc=\n" + - "-----END CERTIFICATE-----\n"; - public static final X509Certificate CA_CERT1 = loadCertificate(CA_CERT1_STRING); - - private static final String CA_PUBLIC_CERT_STRING = "-----BEGIN CERTIFICATE-----\n" + - "MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx\n" + - "GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds\n" + - "b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV\n" + - "BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD\n" + - "VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa\n" + - "DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc\n" + - "THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb\n" + - "Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP\n" + - "c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX\n" + - "gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV\n" + - "HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF\n" + - "AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj\n" + - "Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG\n" + - "j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH\n" + - "hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC\n" + - "X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==\n" + - "-----END CERTIFICATE-----\n"; - public static final X509Certificate CA_PUBLIC_CERT = loadCertificate(CA_PUBLIC_CERT_STRING); - - private static final String CLIENT_CERT_STR = "-----BEGIN CERTIFICATE-----\n" + - "MIIE/DCCAuQCAQEwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxCzAJBgNV\n" + - "BAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdUZXN0aW5n\n" + - "MB4XDTE2MDkzMDIwNTQyOFoXDTE3MDkzMDIwNTQyOFowRDELMAkGA1UEBhMCVVMx\n" + - "CzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdU\n" + - "ZXN0aW5nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnpmcbuaeHfnJ\n" + - "k+2QNvxmdVFTawyFMNk0USCq5sexscwmxbewG/Rb8YnixwJWS44v2XkSujB67z5C\n" + - "s2qudFEhRXKdEuC6idbAuA97KjipHh0AAniWMsyv61fvbgsUC0b0canx3LiDq81p\n" + - "y28NNGmAvoazLZUZ4AhBRiwYZY6FKk723gmZoGbEIeG7J1dlXPusc1662rIjz4eU\n" + - "zlmmlvqyHfNqnNk8L14Vug6Xh+lOEGN85xhu1YHAEKGrS89kZxs5rum/cZU8KH2V\n" + - "v6eKnY03kxjiVLQtnLpm/7VUEoCMGHyruRj+p3my4+DgqMsmsH52RZCBsjyGlpbU\n" + - "NOwOTIX6xh+Rqloduz4AnrMYYIiIw2s8g+2zJM7VbcVKx0fGS26BKdrxgrXWfmNE\n" + - "nR0/REQ5AxDGw0jfTUvtdTkXAf+K4MDjcNLEZ+MA4rHfAfQWZtUR5BkHCQYxNpJk\n" + - "pA0gyk+BpKdC4WdzI14NSWsu5sRCmBCFqH6BTOSEq/V1cNorBxNwLSSTwFFqUDqx\n" + - "Y5nQLXygkJf9WHZWtSKeSjtOYgilz7UKzC2s3CsjmIyGFe+SwpuHJnuE4Uc8Z5Cb\n" + - "bjNGHPzqL6XnmzZHJp7RF8kBdKdjGC7dCUltzOfICZeKlzOOq+Kw42T/nXjuXvpb\n" + - "nkXNxg741Nwd6RecykXJbseFwm3EYxkCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEA\n" + - "Ga1mGwI9aXkL2fTPXO9YkAPzoGeX8aeuVYSQaSkNq+5vnogYCyAt3YDHjRG+ewTT\n" + - "WbnPA991xRAPac+biJeXWmwvgGj0YuT7e79phAiGkTTnbAjFHGfYnBy/tI/v7btO\n" + - "hRNElA5yTJ1m2fVbBEKXzMR83jrT9iyI+YLRN86zUZIaC86xxSbqnrdWN2jOK6MX\n" + - "dS8Arp9tPQjC/4gW+2Ilxv68jiYh+5auWHQZVjppWVY//iu4mAbkq1pTwQEhZ8F8\n" + - "Zrmh9DHh60hLFcfSuhIAwf/NMzppwdkjy1ruKVrpijhGKGp4OWu8nvOUgHSzxc7F\n" + - "PwpVZ5N2Ku4L8MLO6BG2VasRJK7l17TzDXlfLZHJjkuryOFxVaQKt8ZNFgTOaCXS\n" + - "E+gpTLksKU7riYckoiP4+H1sn9qcis0e8s4o/uf1UVc8GSdDw61ReGM5oZEDm1u8\n" + - "H9x20QU6igLqzyBpqvCKv7JNgU1uB2PAODHH78zJiUfnKd1y+o+J1iWzaGj3EFji\n" + - "T8AXksbTP733FeFXfggXju2dyBH+Z1S5BBTEOd1brWgXlHSAZGm97MKZ94r6/tkX\n" + - "qfv3fCos0DKz0oV7qBxYS8wiYhzrRVxG6ITAoH8uuUVVQaZF+G4nJ2jEqNbfuKyX\n" + - "ATQsVNjNNlDA0J33GobPMjT326wa4YAWMx8PI5PJZ3g=\n" + - "-----END CERTIFICATE-----\n"; - public static final X509Certificate CLIENT_CERT = loadCertificate(CLIENT_CERT_STR); - - private static final byte[] FAKE_RSA_KEY_1 = new byte[] { - (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x02, (byte) 0x01, - (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, - (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, - (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82, - (byte) 0x02, (byte) 0x62, (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5e, - (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81, - (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6, (byte) 0x5b, - (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c, (byte) 0x66, - (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86, (byte) 0x8a, - (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3, (byte) 0x02, - (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08, (byte) 0xf3, - (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04, (byte) 0x6d, - (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f, (byte) 0x67, - (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c, (byte) 0xcb, - (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30, (byte) 0xe2, - (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5, (byte) 0x79, - (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b, (byte) 0xce, - (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb, (byte) 0x08, - (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff, (byte) 0x3b, - (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9, (byte) 0xc4, - (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29, (byte) 0x0d, - (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b, (byte) 0x23, - (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78, (byte) 0x08, - (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5, (byte) 0xf1, - (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19, (byte) 0xb4, - (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03, (byte) 0x16, - (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce, (byte) 0x9e, - (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03, (byte) 0x01, - (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x16, - (byte) 0x59, (byte) 0xc3, (byte) 0x24, (byte) 0x1d, (byte) 0x33, (byte) 0x98, - (byte) 0x9c, (byte) 0xc9, (byte) 0xc8, (byte) 0x2c, (byte) 0x88, (byte) 0xbf, - (byte) 0x0a, (byte) 0x01, (byte) 0xce, (byte) 0xfb, (byte) 0x34, (byte) 0x7a, - (byte) 0x58, (byte) 0x7a, (byte) 0xb0, (byte) 0xbf, (byte) 0xa6, (byte) 0xb2, - (byte) 0x60, (byte) 0xbe, (byte) 0x70, (byte) 0x21, (byte) 0xf5, (byte) 0xfc, - (byte) 0x85, (byte) 0x0d, (byte) 0x33, (byte) 0x58, (byte) 0xa1, (byte) 0xe5, - (byte) 0x09, (byte) 0x36, (byte) 0x84, (byte) 0xb2, (byte) 0x04, (byte) 0x0a, - (byte) 0x02, (byte) 0xd3, (byte) 0x88, (byte) 0x1f, (byte) 0x0c, (byte) 0x2b, - (byte) 0x1d, (byte) 0xe9, (byte) 0x3d, (byte) 0xe7, (byte) 0x79, (byte) 0xf9, - (byte) 0x32, (byte) 0x5c, (byte) 0x8a, (byte) 0x75, (byte) 0x49, (byte) 0x12, - (byte) 0xe4, (byte) 0x05, (byte) 0x26, (byte) 0xd4, (byte) 0x2e, (byte) 0x9e, - (byte) 0x1f, (byte) 0xcc, (byte) 0x54, (byte) 0xad, (byte) 0x33, (byte) 0x8d, - (byte) 0x99, (byte) 0x00, (byte) 0xdc, (byte) 0xf5, (byte) 0xb4, (byte) 0xa2, - (byte) 0x2f, (byte) 0xba, (byte) 0xe5, (byte) 0x62, (byte) 0x30, (byte) 0x6d, - (byte) 0xe6, (byte) 0x3d, (byte) 0xeb, (byte) 0x24, (byte) 0xc2, (byte) 0xdc, - (byte) 0x5f, (byte) 0xb7, (byte) 0x16, (byte) 0x35, (byte) 0xa3, (byte) 0x98, - (byte) 0x98, (byte) 0xa8, (byte) 0xef, (byte) 0xe8, (byte) 0xc4, (byte) 0x96, - (byte) 0x6d, (byte) 0x38, (byte) 0xab, (byte) 0x26, (byte) 0x6d, (byte) 0x30, - (byte) 0xc2, (byte) 0xa0, (byte) 0x44, (byte) 0xe4, (byte) 0xff, (byte) 0x7e, - (byte) 0xbe, (byte) 0x7c, (byte) 0x33, (byte) 0xa5, (byte) 0x10, (byte) 0xad, - (byte) 0xd7, (byte) 0x1e, (byte) 0x13, (byte) 0x20, (byte) 0xb3, (byte) 0x1f, - (byte) 0x41, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xf1, (byte) 0x89, - (byte) 0x07, (byte) 0x0f, (byte) 0xe8, (byte) 0xcf, (byte) 0xab, (byte) 0x13, - (byte) 0x2a, (byte) 0x8f, (byte) 0x88, (byte) 0x80, (byte) 0x11, (byte) 0x9a, - (byte) 0x79, (byte) 0xb6, (byte) 0x59, (byte) 0x3a, (byte) 0x50, (byte) 0x6e, - (byte) 0x57, (byte) 0x37, (byte) 0xab, (byte) 0x2a, (byte) 0xd2, (byte) 0xaa, - (byte) 0xd9, (byte) 0x72, (byte) 0x73, (byte) 0xff, (byte) 0x8b, (byte) 0x47, - (byte) 0x76, (byte) 0xdd, (byte) 0xdc, (byte) 0xf5, (byte) 0x97, (byte) 0x44, - (byte) 0x3a, (byte) 0x78, (byte) 0xbe, (byte) 0x17, (byte) 0xb4, (byte) 0x22, - (byte) 0x6f, (byte) 0xe5, (byte) 0x23, (byte) 0x70, (byte) 0x1d, (byte) 0x10, - (byte) 0x5d, (byte) 0xba, (byte) 0x16, (byte) 0x81, (byte) 0xf1, (byte) 0x45, - (byte) 0xce, (byte) 0x30, (byte) 0xb4, (byte) 0xab, (byte) 0x80, (byte) 0xe4, - (byte) 0x98, (byte) 0x31, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xda, - (byte) 0x82, (byte) 0x9d, (byte) 0x3f, (byte) 0xca, (byte) 0x2f, (byte) 0xe1, - (byte) 0xd4, (byte) 0x86, (byte) 0x77, (byte) 0x48, (byte) 0xa6, (byte) 0xab, - (byte) 0xab, (byte) 0x1c, (byte) 0x42, (byte) 0x5c, (byte) 0xd5, (byte) 0xc7, - (byte) 0x46, (byte) 0x59, (byte) 0x91, (byte) 0x3f, (byte) 0xfc, (byte) 0xcc, - (byte) 0xec, (byte) 0xc2, (byte) 0x40, (byte) 0x12, (byte) 0x2c, (byte) 0x8d, - (byte) 0x1f, (byte) 0xa2, (byte) 0x18, (byte) 0x88, (byte) 0xee, (byte) 0x82, - (byte) 0x4a, (byte) 0x5a, (byte) 0x5e, (byte) 0x88, (byte) 0x20, (byte) 0xe3, - (byte) 0x7b, (byte) 0xe0, (byte) 0xd8, (byte) 0x3a, (byte) 0x52, (byte) 0x9a, - (byte) 0x26, (byte) 0x6a, (byte) 0x04, (byte) 0xec, (byte) 0xe8, (byte) 0xb9, - (byte) 0x48, (byte) 0x40, (byte) 0xe1, (byte) 0xe1, (byte) 0x83, (byte) 0xa6, - (byte) 0x67, (byte) 0xa6, (byte) 0xfd, (byte) 0x02, (byte) 0x41, (byte) 0x00, - (byte) 0x89, (byte) 0x72, (byte) 0x3e, (byte) 0xb0, (byte) 0x90, (byte) 0xfd, - (byte) 0x4c, (byte) 0x0e, (byte) 0xd6, (byte) 0x13, (byte) 0x63, (byte) 0xcb, - (byte) 0xed, (byte) 0x38, (byte) 0x88, (byte) 0xb6, (byte) 0x79, (byte) 0xc4, - (byte) 0x33, (byte) 0x6c, (byte) 0xf6, (byte) 0xf8, (byte) 0xd8, (byte) 0xd0, - (byte) 0xbf, (byte) 0x9d, (byte) 0x35, (byte) 0xac, (byte) 0x69, (byte) 0xd2, - (byte) 0x2b, (byte) 0xc1, (byte) 0xf9, (byte) 0x24, (byte) 0x7b, (byte) 0xce, - (byte) 0xcd, (byte) 0xcb, (byte) 0xa7, (byte) 0xb2, (byte) 0x7a, (byte) 0x0a, - (byte) 0x27, (byte) 0x19, (byte) 0xc9, (byte) 0xaf, (byte) 0x0d, (byte) 0x21, - (byte) 0x89, (byte) 0x88, (byte) 0x7c, (byte) 0xad, (byte) 0x9e, (byte) 0x8d, - (byte) 0x47, (byte) 0x6d, (byte) 0x3f, (byte) 0xce, (byte) 0x7b, (byte) 0xa1, - (byte) 0x74, (byte) 0xf1, (byte) 0xa0, (byte) 0xa1, (byte) 0x02, (byte) 0x41, - (byte) 0x00, (byte) 0xd9, (byte) 0xa8, (byte) 0xf5, (byte) 0xfe, (byte) 0xce, - (byte) 0xe6, (byte) 0x77, (byte) 0x6b, (byte) 0xfe, (byte) 0x2d, (byte) 0xe0, - (byte) 0x1e, (byte) 0xb6, (byte) 0x2e, (byte) 0x12, (byte) 0x4e, (byte) 0x40, - (byte) 0xaf, (byte) 0x6a, (byte) 0x7b, (byte) 0x37, (byte) 0x49, (byte) 0x2a, - (byte) 0x96, (byte) 0x25, (byte) 0x83, (byte) 0x49, (byte) 0xd4, (byte) 0x0c, - (byte) 0xc6, (byte) 0x78, (byte) 0x25, (byte) 0x24, (byte) 0x90, (byte) 0x90, - (byte) 0x06, (byte) 0x15, (byte) 0x9e, (byte) 0xfe, (byte) 0xf9, (byte) 0xdf, - (byte) 0x5b, (byte) 0xf3, (byte) 0x7e, (byte) 0x38, (byte) 0x70, (byte) 0xeb, - (byte) 0x57, (byte) 0xd0, (byte) 0xd9, (byte) 0xa7, (byte) 0x0e, (byte) 0x14, - (byte) 0xf7, (byte) 0x95, (byte) 0x68, (byte) 0xd5, (byte) 0xc8, (byte) 0xab, - (byte) 0x9d, (byte) 0x3a, (byte) 0x2b, (byte) 0x51, (byte) 0xf9, (byte) 0x02, - (byte) 0x41, (byte) 0x00, (byte) 0x96, (byte) 0xdf, (byte) 0xe9, (byte) 0x67, - (byte) 0x6c, (byte) 0xdc, (byte) 0x90, (byte) 0x14, (byte) 0xb4, (byte) 0x1d, - (byte) 0x22, (byte) 0x33, (byte) 0x4a, (byte) 0x31, (byte) 0xc1, (byte) 0x9d, - (byte) 0x2e, (byte) 0xff, (byte) 0x9a, (byte) 0x2a, (byte) 0x95, (byte) 0x4b, - (byte) 0x27, (byte) 0x74, (byte) 0xcb, (byte) 0x21, (byte) 0xc3, (byte) 0xd2, - (byte) 0x0b, (byte) 0xb2, (byte) 0x46, (byte) 0x87, (byte) 0xf8, (byte) 0x28, - (byte) 0x01, (byte) 0x8b, (byte) 0xd8, (byte) 0xb9, (byte) 0x4b, (byte) 0xcd, - (byte) 0x9a, (byte) 0x96, (byte) 0x41, (byte) 0x0e, (byte) 0x36, (byte) 0x6d, - (byte) 0x40, (byte) 0x42, (byte) 0xbc, (byte) 0xd9, (byte) 0xd3, (byte) 0x7b, - (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1, - (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51 - }; - public static final PrivateKey RSA_KEY1 = loadPrivateRSAKey(FAKE_RSA_KEY_1); - - private static X509Certificate loadCertificate(String blob) { - try { - final CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); - InputStream stream = new ByteArrayInputStream(blob.getBytes(StandardCharsets.UTF_8)); - - return (X509Certificate) certFactory.generateCertificate(stream); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - private static PrivateKey loadPrivateRSAKey(byte[] fakeKey) { - try { - KeyFactory kf = KeyFactory.getInstance("RSA"); - return kf.generatePrivate(new PKCS8EncodedKeySpec(fakeKey)); - } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { - return null; - } - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/MulticastLockTest.java b/tests/cts/net/src/android/net/wifi/cts/MulticastLockTest.java deleted file mode 100644 index 71f04a33c1..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/MulticastLockTest.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2019 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.wifi.cts; - -import android.content.Context; -import android.net.wifi.WifiManager; -import android.net.wifi.WifiManager.MulticastLock; -import android.platform.test.annotations.AppModeFull; -import android.test.AndroidTestCase; - -@AppModeFull(reason = "Cannot get WifiManager in instant app mode") -public class MulticastLockTest extends AndroidTestCase { - - private static final String WIFI_TAG = "MulticastLockTest"; - - /** - * Verify acquire and release of Multicast locks - */ - public void testMulticastLock() { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - WifiManager wm = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); - MulticastLock mcl = wm.createMulticastLock(WIFI_TAG); - - mcl.setReferenceCounted(true); - assertFalse(mcl.isHeld()); - mcl.acquire(); - assertTrue(mcl.isHeld()); - mcl.release(); - assertFalse(mcl.isHeld()); - mcl.acquire(); - mcl.acquire(); - assertTrue(mcl.isHeld()); - mcl.release(); - assertTrue(mcl.isHeld()); - mcl.release(); - assertFalse(mcl.isHeld()); - assertNotNull(mcl.toString()); - try { - mcl.release(); - fail("should throw out exception because release is called" - +" a greater number of times than acquire"); - } catch (RuntimeException e) { - // expected - } - - mcl = wm.createMulticastLock(WIFI_TAG); - mcl.setReferenceCounted(false); - assertFalse(mcl.isHeld()); - mcl.acquire(); - assertTrue(mcl.isHeld()); - mcl.release(); - assertFalse(mcl.isHeld()); - mcl.acquire(); - mcl.acquire(); - assertTrue(mcl.isHeld()); - mcl.release(); - assertFalse(mcl.isHeld()); - assertNotNull(mcl.toString()); - // releasing again after release: but ignored for non-referenced locks - mcl.release(); - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java deleted file mode 100644 index f2a2b48267..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java +++ /dev/null @@ -1,592 +0,0 @@ -/* - * Copyright (C) 2012 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.wifi.cts; - -import android.content.Context; -import android.net.nsd.NsdManager; -import android.net.nsd.NsdServiceInfo; -import android.platform.test.annotations.AppModeFull; -import android.test.AndroidTestCase; -import android.util.Log; - -import java.io.IOException; -import java.net.ServerSocket; -import java.util.Arrays; -import java.util.Random; -import java.util.List; -import java.util.ArrayList; - -@AppModeFull(reason = "Socket cannot bind in instant app mode") -public class NsdManagerTest extends AndroidTestCase { - - private static final String TAG = "NsdManagerTest"; - private static final String SERVICE_TYPE = "_nmt._tcp"; - private static final int TIMEOUT = 2000; - - private static final boolean DBG = false; - - NsdManager mNsdManager; - - NsdManager.RegistrationListener mRegistrationListener; - NsdManager.DiscoveryListener mDiscoveryListener; - NsdManager.ResolveListener mResolveListener; - private NsdServiceInfo mResolvedService; - - public NsdManagerTest() { - initRegistrationListener(); - initDiscoveryListener(); - initResolveListener(); - } - - private void initRegistrationListener() { - mRegistrationListener = new NsdManager.RegistrationListener() { - @Override - public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) { - setEvent("onRegistrationFailed", errorCode); - } - - @Override - public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) { - setEvent("onUnregistrationFailed", errorCode); - } - - @Override - public void onServiceRegistered(NsdServiceInfo serviceInfo) { - setEvent("onServiceRegistered", serviceInfo); - } - - @Override - public void onServiceUnregistered(NsdServiceInfo serviceInfo) { - setEvent("onServiceUnregistered", serviceInfo); - } - }; - } - - private void initDiscoveryListener() { - mDiscoveryListener = new NsdManager.DiscoveryListener() { - @Override - public void onStartDiscoveryFailed(String serviceType, int errorCode) { - setEvent("onStartDiscoveryFailed", errorCode); - } - - @Override - public void onStopDiscoveryFailed(String serviceType, int errorCode) { - setEvent("onStopDiscoveryFailed", errorCode); - } - - @Override - public void onDiscoveryStarted(String serviceType) { - NsdServiceInfo info = new NsdServiceInfo(); - info.setServiceType(serviceType); - setEvent("onDiscoveryStarted", info); - } - - @Override - public void onDiscoveryStopped(String serviceType) { - NsdServiceInfo info = new NsdServiceInfo(); - info.setServiceType(serviceType); - setEvent("onDiscoveryStopped", info); - } - - @Override - public void onServiceFound(NsdServiceInfo serviceInfo) { - setEvent("onServiceFound", serviceInfo); - } - - @Override - public void onServiceLost(NsdServiceInfo serviceInfo) { - setEvent("onServiceLost", serviceInfo); - } - }; - } - - private void initResolveListener() { - mResolveListener = new NsdManager.ResolveListener() { - @Override - public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { - setEvent("onResolveFailed", errorCode); - } - - @Override - public void onServiceResolved(NsdServiceInfo serviceInfo) { - mResolvedService = serviceInfo; - setEvent("onServiceResolved", serviceInfo); - } - }; - } - - - - private final class EventData { - EventData(String callbackName, NsdServiceInfo info) { - mCallbackName = callbackName; - mSucceeded = true; - mErrorCode = 0; - mInfo = info; - } - EventData(String callbackName, int errorCode) { - mCallbackName = callbackName; - mSucceeded = false; - mErrorCode = errorCode; - mInfo = null; - } - private final String mCallbackName; - private final boolean mSucceeded; - private final int mErrorCode; - private final NsdServiceInfo mInfo; - } - - private final List mEventCache = new ArrayList(); - - private void setEvent(String callbackName, int errorCode) { - if (DBG) Log.d(TAG, callbackName + " failed with " + String.valueOf(errorCode)); - EventData eventData = new EventData(callbackName, errorCode); - synchronized (mEventCache) { - mEventCache.add(eventData); - mEventCache.notify(); - } - } - - private void setEvent(String callbackName, NsdServiceInfo info) { - if (DBG) Log.d(TAG, "Received event " + callbackName + " for " + info.getServiceName()); - EventData eventData = new EventData(callbackName, info); - synchronized (mEventCache) { - mEventCache.add(eventData); - mEventCache.notify(); - } - } - - void clearEventCache() { - synchronized(mEventCache) { - mEventCache.clear(); - } - } - - int eventCacheSize() { - synchronized(mEventCache) { - return mEventCache.size(); - } - } - - private int mWaitId = 0; - private EventData waitForCallback(String callbackName) { - - synchronized(mEventCache) { - - mWaitId ++; - if (DBG) Log.d(TAG, "Waiting for " + callbackName + ", id=" + String.valueOf(mWaitId)); - - try { - long startTime = android.os.SystemClock.uptimeMillis(); - long elapsedTime = 0; - int index = 0; - while (elapsedTime < TIMEOUT ) { - // first check if we've received that event - for (; index < mEventCache.size(); index++) { - EventData e = mEventCache.get(index); - if (e.mCallbackName.equals(callbackName)) { - if (DBG) Log.d(TAG, "exiting wait id=" + String.valueOf(mWaitId)); - return e; - } - } - - // Not yet received, just wait - mEventCache.wait(TIMEOUT - elapsedTime); - elapsedTime = android.os.SystemClock.uptimeMillis() - startTime; - } - // we exited the loop because of TIMEOUT; fail the call - if (DBG) Log.d(TAG, "timed out waiting id=" + String.valueOf(mWaitId)); - return null; - } catch (InterruptedException e) { - return null; // wait timed out! - } - } - } - - private EventData waitForNewEvents() throws InterruptedException { - if (DBG) Log.d(TAG, "Waiting for a bit, id=" + String.valueOf(mWaitId)); - - long startTime = android.os.SystemClock.uptimeMillis(); - long elapsedTime = 0; - synchronized (mEventCache) { - int index = mEventCache.size(); - while (elapsedTime < TIMEOUT ) { - // first check if we've received that event - for (; index < mEventCache.size(); index++) { - EventData e = mEventCache.get(index); - return e; - } - - // Not yet received, just wait - mEventCache.wait(TIMEOUT - elapsedTime); - elapsedTime = android.os.SystemClock.uptimeMillis() - startTime; - } - } - - return null; - } - - private String mServiceName; - - @Override - public void setUp() { - if (DBG) Log.d(TAG, "Setup test ..."); - mNsdManager = (NsdManager) getContext().getSystemService(Context.NSD_SERVICE); - - Random rand = new Random(); - mServiceName = new String("NsdTest"); - for (int i = 0; i < 4; i++) { - mServiceName = mServiceName + String.valueOf(rand.nextInt(10)); - } - } - - @Override - public void tearDown() { - if (DBG) Log.d(TAG, "Tear down test ..."); - } - - public void testNDSManager() throws Exception { - EventData lastEvent = null; - - if (DBG) Log.d(TAG, "Starting test ..."); - - NsdServiceInfo si = new NsdServiceInfo(); - si.setServiceType(SERVICE_TYPE); - si.setServiceName(mServiceName); - - byte testByteArray[] = new byte[] {-128, 127, 2, 1, 0, 1, 2}; - String String256 = "1_________2_________3_________4_________5_________6_________" + - "7_________8_________9_________10________11________12________13________" + - "14________15________16________17________18________19________20________" + - "21________22________23________24________25________123456"; - - // Illegal attributes - try { - si.setAttribute(null, (String) null); - fail("Could set null key"); - } catch (IllegalArgumentException e) { - // expected - } - - try { - si.setAttribute("", (String) null); - fail("Could set empty key"); - } catch (IllegalArgumentException e) { - // expected - } - - try { - si.setAttribute(String256, (String) null); - fail("Could set key with 255 characters"); - } catch (IllegalArgumentException e) { - // expected - } - - try { - si.setAttribute("key", String256.substring(3)); - fail("Could set key+value combination with more than 255 characters"); - } catch (IllegalArgumentException e) { - // expected - } - - try { - si.setAttribute("key", String256.substring(4)); - fail("Could set key+value combination with 255 characters"); - } catch (IllegalArgumentException e) { - // expected - } - - try { - si.setAttribute(new String(new byte[]{0x19}), (String) null); - fail("Could set key with invalid character"); - } catch (IllegalArgumentException e) { - // expected - } - - try { - si.setAttribute("=", (String) null); - fail("Could set key with invalid character"); - } catch (IllegalArgumentException e) { - // expected - } - - try { - si.setAttribute(new String(new byte[]{0x7F}), (String) null); - fail("Could set key with invalid character"); - } catch (IllegalArgumentException e) { - // expected - } - - // Allowed attributes - si.setAttribute("booleanAttr", (String) null); - si.setAttribute("keyValueAttr", "value"); - si.setAttribute("keyEqualsAttr", "="); - si.setAttribute(" whiteSpaceKeyValueAttr ", " value "); - si.setAttribute("binaryDataAttr", testByteArray); - si.setAttribute("nullBinaryDataAttr", (byte[]) null); - si.setAttribute("emptyBinaryDataAttr", new byte[]{}); - si.setAttribute("longkey", String256.substring(9)); - - ServerSocket socket; - int localPort; - - try { - socket = new ServerSocket(0); - localPort = socket.getLocalPort(); - si.setPort(localPort); - } catch (IOException e) { - if (DBG) Log.d(TAG, "Could not open a local socket"); - assertTrue(false); - return; - } - - if (DBG) Log.d(TAG, "Port = " + String.valueOf(localPort)); - - clearEventCache(); - - mNsdManager.registerService(si, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener); - lastEvent = waitForCallback("onServiceRegistered"); // id = 1 - assertTrue(lastEvent != null); - assertTrue(lastEvent.mSucceeded); - assertTrue(eventCacheSize() == 1); - - // We may not always get the name that we tried to register; - // This events tells us the name that was registered. - String registeredName = lastEvent.mInfo.getServiceName(); - si.setServiceName(registeredName); - - clearEventCache(); - - mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, - mDiscoveryListener); - - // Expect discovery started - lastEvent = waitForCallback("onDiscoveryStarted"); // id = 2 - - assertTrue(lastEvent != null); - assertTrue(lastEvent.mSucceeded); - - // Remove this event, so accounting becomes easier later - synchronized (mEventCache) { - mEventCache.remove(lastEvent); - } - - // Expect a service record to be discovered (and filter the ones - // that are unrelated to this test) - boolean found = false; - for (int i = 0; i < 32; i++) { - - lastEvent = waitForCallback("onServiceFound"); // id = 3 - if (lastEvent == null) { - // no more onServiceFound events are being reported! - break; - } - - assertTrue(lastEvent.mSucceeded); - - if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": ServiceName = " + - lastEvent.mInfo.getServiceName()); - - if (lastEvent.mInfo.getServiceName().equals(registeredName)) { - // Save it, as it will get overwritten with new serviceFound events - si = lastEvent.mInfo; - found = true; - } - - // Remove this event from the event cache, so it won't be found by subsequent - // calls to waitForCallback - synchronized (mEventCache) { - mEventCache.remove(lastEvent); - } - } - - assertTrue(found); - - // We've removed all serviceFound events, and we've removed the discoveryStarted - // event as well, so now the event cache should be empty! - assertTrue(eventCacheSize() == 0); - - // Resolve the service - clearEventCache(); - mNsdManager.resolveService(si, mResolveListener); - lastEvent = waitForCallback("onServiceResolved"); // id = 4 - - assertNotNull(mResolvedService); - - // Check Txt attributes - assertEquals(8, mResolvedService.getAttributes().size()); - assertTrue(mResolvedService.getAttributes().containsKey("booleanAttr")); - assertNull(mResolvedService.getAttributes().get("booleanAttr")); - assertEquals("value", new String(mResolvedService.getAttributes().get("keyValueAttr"))); - assertEquals("=", new String(mResolvedService.getAttributes().get("keyEqualsAttr"))); - assertEquals(" value ", new String(mResolvedService.getAttributes() - .get(" whiteSpaceKeyValueAttr "))); - assertEquals(String256.substring(9), new String(mResolvedService.getAttributes() - .get("longkey"))); - assertTrue(Arrays.equals(testByteArray, - mResolvedService.getAttributes().get("binaryDataAttr"))); - assertTrue(mResolvedService.getAttributes().containsKey("nullBinaryDataAttr")); - assertNull(mResolvedService.getAttributes().get("nullBinaryDataAttr")); - assertTrue(mResolvedService.getAttributes().containsKey("emptyBinaryDataAttr")); - assertNull(mResolvedService.getAttributes().get("emptyBinaryDataAttr")); - - assertTrue(lastEvent != null); - assertTrue(lastEvent.mSucceeded); - - if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": Port = " + - String.valueOf(lastEvent.mInfo.getPort())); - - assertTrue(lastEvent.mInfo.getPort() == localPort); - assertTrue(eventCacheSize() == 1); - - checkForAdditionalEvents(); - clearEventCache(); - - // Unregister the service - mNsdManager.unregisterService(mRegistrationListener); - lastEvent = waitForCallback("onServiceUnregistered"); // id = 5 - - assertTrue(lastEvent != null); - assertTrue(lastEvent.mSucceeded); - - // Expect a callback for service lost - lastEvent = waitForCallback("onServiceLost"); // id = 6 - - assertTrue(lastEvent != null); - assertTrue(lastEvent.mInfo.getServiceName().equals(registeredName)); - - // Register service again to see if we discover it - checkForAdditionalEvents(); - clearEventCache(); - - si = new NsdServiceInfo(); - si.setServiceType(SERVICE_TYPE); - si.setServiceName(mServiceName); - si.setPort(localPort); - - // Create a new registration listener and register same service again - initRegistrationListener(); - - mNsdManager.registerService(si, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener); - - lastEvent = waitForCallback("onServiceRegistered"); // id = 7 - - assertTrue(lastEvent != null); - assertTrue(lastEvent.mSucceeded); - - registeredName = lastEvent.mInfo.getServiceName(); - - // Expect a record to be discovered - // Expect a service record to be discovered (and filter the ones - // that are unrelated to this test) - found = false; - for (int i = 0; i < 32; i++) { - - lastEvent = waitForCallback("onServiceFound"); // id = 8 - if (lastEvent == null) { - // no more onServiceFound events are being reported! - break; - } - - assertTrue(lastEvent.mSucceeded); - - if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": ServiceName = " + - lastEvent.mInfo.getServiceName()); - - if (lastEvent.mInfo.getServiceName().equals(registeredName)) { - // Save it, as it will get overwritten with new serviceFound events - si = lastEvent.mInfo; - found = true; - } - - // Remove this event from the event cache, so it won't be found by subsequent - // calls to waitForCallback - synchronized (mEventCache) { - mEventCache.remove(lastEvent); - } - } - - assertTrue(found); - - // Resolve the service - clearEventCache(); - mNsdManager.resolveService(si, mResolveListener); - lastEvent = waitForCallback("onServiceResolved"); // id = 9 - - assertTrue(lastEvent != null); - assertTrue(lastEvent.mSucceeded); - - if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": ServiceName = " + - lastEvent.mInfo.getServiceName()); - - assertTrue(lastEvent.mInfo.getServiceName().equals(registeredName)); - - assertNotNull(mResolvedService); - - // Check that we don't have any TXT records - assertEquals(0, mResolvedService.getAttributes().size()); - - checkForAdditionalEvents(); - clearEventCache(); - - mNsdManager.stopServiceDiscovery(mDiscoveryListener); - lastEvent = waitForCallback("onDiscoveryStopped"); // id = 10 - assertTrue(lastEvent != null); - assertTrue(lastEvent.mSucceeded); - assertTrue(checkCacheSize(1)); - - checkForAdditionalEvents(); - clearEventCache(); - - mNsdManager.unregisterService(mRegistrationListener); - - lastEvent = waitForCallback("onServiceUnregistered"); // id = 11 - assertTrue(lastEvent != null); - assertTrue(lastEvent.mSucceeded); - assertTrue(checkCacheSize(1)); - } - - boolean checkCacheSize(int size) { - synchronized (mEventCache) { - int cacheSize = mEventCache.size(); - if (cacheSize != size) { - Log.d(TAG, "id = " + mWaitId + ": event cache size = " + cacheSize); - for (int i = 0; i < cacheSize; i++) { - EventData e = mEventCache.get(i); - String sname = (e.mInfo != null) ? "(" + e.mInfo.getServiceName() + ")" : ""; - Log.d(TAG, "eventName is " + e.mCallbackName + sname); - } - } - return (cacheSize == size); - } - } - - boolean checkForAdditionalEvents() { - try { - EventData e = waitForNewEvents(); - if (e != null) { - String sname = (e.mInfo != null) ? "(" + e.mInfo.getServiceName() + ")" : ""; - Log.d(TAG, "ignoring unexpected event " + e.mCallbackName + sname); - } - return (e == null); - } - catch (InterruptedException ex) { - return false; - } - } -} - diff --git a/tests/cts/net/src/android/net/wifi/cts/PpsMoParserTest.java b/tests/cts/net/src/android/net/wifi/cts/PpsMoParserTest.java deleted file mode 100644 index feafd434a7..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/PpsMoParserTest.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2017 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.wifi.cts; - -import android.net.wifi.hotspot2.PasspointConfiguration; -import android.net.wifi.hotspot2.omadm.PpsMoParser; -import android.net.wifi.hotspot2.pps.Credential; -import android.net.wifi.hotspot2.pps.HomeSp; -import android.test.AndroidTestCase; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * CTS tests for PPS MO (PerProviderSubscription Management Object) XML string parsing API. - */ -public class PpsMoParserTest extends AndroidTestCase { - private static final String PPS_MO_XML_FILE = "assets/PerProviderSubscription.xml"; - - /** - * Read the content of the given resource file into a String. - * - * @param filename String name of the file - * @return String - * @throws IOException - */ - private String loadResourceFile(String filename) throws IOException { - InputStream in = getClass().getClassLoader().getResourceAsStream(filename); - BufferedReader reader = new BufferedReader(new InputStreamReader(in)); - StringBuilder builder = new StringBuilder(); - String line; - while ((line = reader.readLine()) != null) { - builder.append(line).append("\n"); - } - return builder.toString(); - } - - /** - * Generate a {@link PasspointConfiguration} that matches the configuration specified in the - * XML file {@link #PPS_MO_XML_FILE}. - * - * @return {@link PasspointConfiguration} - */ - private PasspointConfiguration generateConfigurationFromPPSMOTree() throws Exception { - DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); - byte[] certFingerprint = new byte[32]; - Arrays.fill(certFingerprint, (byte) 0x1f); - - PasspointConfiguration config = new PasspointConfiguration(); - - // HomeSP configuration. - HomeSp homeSp = new HomeSp(); - homeSp.setFriendlyName("Century House"); - assertEquals("Century House", homeSp.getFriendlyName()); - homeSp.setFqdn("mi6.co.uk"); - assertEquals("mi6.co.uk", homeSp.getFqdn()); - homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L}); - assertTrue(Arrays.equals(new long[] {0x112233L, 0x445566L}, - homeSp.getRoamingConsortiumOis())); - config.setHomeSp(homeSp); - assertEquals(homeSp, config.getHomeSp()); - - // Credential configuration. - Credential credential = new Credential(); - credential.setRealm("shaken.stirred.com"); - assertEquals("shaken.stirred.com", credential.getRealm()); - Credential.UserCredential userCredential = new Credential.UserCredential(); - userCredential.setUsername("james"); - assertEquals("james", userCredential.getUsername()); - userCredential.setPassword("Ym9uZDAwNw=="); - assertEquals("Ym9uZDAwNw==", userCredential.getPassword()); - userCredential.setEapType(21); - assertEquals(21, userCredential.getEapType()); - userCredential.setNonEapInnerMethod("MS-CHAP-V2"); - assertEquals("MS-CHAP-V2", userCredential.getNonEapInnerMethod()); - credential.setUserCredential(userCredential); - assertEquals(userCredential, credential.getUserCredential()); - Credential.CertificateCredential certCredential = new Credential.CertificateCredential(); - certCredential.setCertType("x509v3"); - assertEquals("x509v3", certCredential.getCertType()); - certCredential.setCertSha256Fingerprint(certFingerprint); - assertTrue(Arrays.equals(certFingerprint, certCredential.getCertSha256Fingerprint())); - credential.setCertCredential(certCredential); - assertEquals(certCredential, credential.getCertCredential()); - Credential.SimCredential simCredential = new Credential.SimCredential(); - simCredential.setImsi("imsi"); - assertEquals("imsi", simCredential.getImsi()); - simCredential.setEapType(24); - assertEquals(24, simCredential.getEapType()); - credential.setSimCredential(simCredential); - assertEquals(simCredential, credential.getSimCredential()); - config.setCredential(credential); - assertEquals(credential, config.getCredential()); - return config; - } - - /** - * Parse and verify all supported fields under PPS MO tree. - * - * @throws Exception - */ - public void testParsePPSMOTree() throws Exception { - String ppsMoTree = loadResourceFile(PPS_MO_XML_FILE); - PasspointConfiguration expectedConfig = generateConfigurationFromPPSMOTree(); - PasspointConfiguration actualConfig = PpsMoParser.parseMoText(ppsMoTree); - assertTrue(actualConfig.equals(expectedConfig)); - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java deleted file mode 100644 index 9bd1226f52..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright (C) 2008 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.wifi.cts; - -import java.util.List; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.wifi.ScanResult; -import android.net.wifi.WifiInfo; -import android.net.wifi.WifiManager; -import android.net.wifi.WifiManager.WifiLock; -import android.platform.test.annotations.AppModeFull; -import android.test.AndroidTestCase; -import android.util.Log; - -import com.android.compatibility.common.util.SystemUtil; - -@AppModeFull(reason = "Cannot get WifiManager in instant app mode") -public class ScanResultTest extends AndroidTestCase { - private static class MySync { - int expectedState = STATE_NULL; - } - - private WifiManager mWifiManager; - private WifiLock mWifiLock; - private static MySync mMySync; - - private static final int STATE_NULL = 0; - private static final int STATE_WIFI_CHANGING = 1; - private static final int STATE_WIFI_CHANGED = 2; - private static final int STATE_START_SCAN = 3; - private static final int STATE_SCAN_RESULTS_AVAILABLE = 4; - private static final int STATE_SCAN_FAILURE = 5; - - private static final String TAG = "WifiInfoTest"; - private static final int TIMEOUT_MSEC = 6000; - private static final int WAIT_MSEC = 60; - private static final int ENABLE_WAIT_MSEC = 10000; - private static final int SCAN_WAIT_MSEC = 10000; - private static final int SCAN_MAX_RETRY_COUNT = 6; - private static final int SCAN_FIND_BSSID_MAX_RETRY_COUNT = 5; - private static final long SCAN_FIND_BSSID_WAIT_MSEC = 5_000L; - private IntentFilter mIntentFilter; - private final BroadcastReceiver mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - final String action = intent.getAction(); - if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) { - synchronized (mMySync) { - mMySync.expectedState = STATE_WIFI_CHANGED; - mMySync.notify(); - } - } else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { - synchronized (mMySync) { - if (intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)) { - mMySync.expectedState = STATE_SCAN_RESULTS_AVAILABLE; - } else { - mMySync.expectedState = STATE_SCAN_FAILURE; - } - mMySync.notify(); - } - } - } - }; - - @Override - protected void setUp() throws Exception { - super.setUp(); - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - mMySync = new MySync(); - mIntentFilter = new IntentFilter(); - mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); - mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); - mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.ACTION_PICK_WIFI_NETWORK); - - mContext.registerReceiver(mReceiver, mIntentFilter); - mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); - assertNotNull(mWifiManager); - mWifiLock = mWifiManager.createWifiLock(TAG); - mWifiLock.acquire(); - if (!mWifiManager.isWifiEnabled()) - setWifiEnabled(true); - Thread.sleep(ENABLE_WAIT_MSEC); - assertTrue(mWifiManager.isWifiEnabled()); - mMySync.expectedState = STATE_NULL; - } - - @Override - protected void tearDown() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - super.tearDown(); - return; - } - mWifiLock.release(); - mContext.unregisterReceiver(mReceiver); - if (!mWifiManager.isWifiEnabled()) - setWifiEnabled(true); - Thread.sleep(ENABLE_WAIT_MSEC); - super.tearDown(); - } - - private void setWifiEnabled(boolean enable) throws Exception { - synchronized (mMySync) { - mMySync.expectedState = STATE_WIFI_CHANGING; - if (enable) { - SystemUtil.runShellCommand("svc wifi enable"); - } else { - SystemUtil.runShellCommand("svc wifi disable"); - } - waitForBroadcast(TIMEOUT_MSEC, STATE_WIFI_CHANGED); - } - } - - private boolean waitForBroadcast(long timeout, int expectedState) throws Exception { - long waitTime = System.currentTimeMillis() + timeout; - while (System.currentTimeMillis() < waitTime - && mMySync.expectedState != expectedState) - mMySync.wait(WAIT_MSEC); - return mMySync.expectedState == expectedState; - } - - public void testScanResultProperties() { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - List scanResults = mWifiManager.getScanResults(); - // this test case should in Wifi environment - for (int i = 0; i < scanResults.size(); i++) { - ScanResult mScanResult = scanResults.get(i); - assertNotNull(mScanResult.toString()); - } - } - - /* Multiple scans to ensure bssid is updated */ - private void scanAndWait() throws Exception { - synchronized (mMySync) { - for (int retry = 0; retry < SCAN_MAX_RETRY_COUNT; retry++) { - mMySync.expectedState = STATE_START_SCAN; - mWifiManager.startScan(); - if (waitForBroadcast(SCAN_WAIT_MSEC, STATE_SCAN_RESULTS_AVAILABLE)) { - break; - } - } - } - } - - public void testScanResultTimeStamp() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - - long timestamp = 0; - String BSSID = null; - - scanAndWait(); - - List scanResults = mWifiManager.getScanResults(); - for (ScanResult result : scanResults) { - BSSID = result.BSSID; - timestamp = result.timestamp; - assertTrue(timestamp != 0); - break; - } - - scanAndWait(); - - scanResults = mWifiManager.getScanResults(); - for (ScanResult result : scanResults) { - if (result.BSSID.equals(BSSID)) { - long timeDiff = (result.timestamp - timestamp) / 1000; - assertTrue (timeDiff > 0); - assertTrue (timeDiff < 6 * SCAN_WAIT_MSEC); - } - } - - } - - public void testScanResultMatchesWifiInfo() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - - // This test case should run while connected to Wifi - final WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); - assertNotNull(wifiInfo); - - ScanResult currentNetwork = null; - for (int i = 0; i < SCAN_FIND_BSSID_MAX_RETRY_COUNT; i++) { - scanAndWait(); - final List scanResults = mWifiManager.getScanResults(); - currentNetwork = scanResults.stream().filter(r -> r.BSSID.equals(wifiInfo.getBSSID())) - .findAny().orElse(null); - - if (currentNetwork != null) { - break; - } - Thread.sleep(SCAN_FIND_BSSID_WAIT_MSEC); - } - assertNotNull("Current network not found in scan results", currentNetwork); - - assertEquals(wifiInfo.getWifiSsid(), currentNetwork.wifiSsid); - assertEquals(wifiInfo.getFrequency(), currentNetwork.frequency); - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java b/tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java deleted file mode 100644 index 11edf7395b..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2008 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.wifi.cts; - -import android.net.wifi.SupplicantState; -import android.test.AndroidTestCase; - -public class SupplicantStateTest extends AndroidTestCase { - - public void testIsValidState() { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - assertTrue(SupplicantState.isValidState(SupplicantState.DISCONNECTED)); - assertTrue(SupplicantState.isValidState(SupplicantState.INACTIVE)); - assertTrue(SupplicantState.isValidState(SupplicantState.SCANNING)); - assertTrue(SupplicantState.isValidState(SupplicantState.ASSOCIATING)); - assertTrue(SupplicantState.isValidState(SupplicantState.ASSOCIATED)); - assertTrue(SupplicantState.isValidState(SupplicantState.FOUR_WAY_HANDSHAKE)); - assertTrue(SupplicantState.isValidState(SupplicantState.GROUP_HANDSHAKE)); - assertTrue(SupplicantState.isValidState(SupplicantState.COMPLETED)); - assertTrue(SupplicantState.isValidState(SupplicantState.DORMANT)); - assertFalse(SupplicantState.isValidState(SupplicantState.UNINITIALIZED)); - assertFalse(SupplicantState.isValidState(SupplicantState.INVALID)); - } - -} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java deleted file mode 100644 index a59c85e5ab..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2008 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.wifi.cts; - -import java.util.List; - -import android.content.Context; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiManager; -import android.platform.test.annotations.AppModeFull; -import android.test.AndroidTestCase; - -@AppModeFull(reason = "Cannot get WifiManager in instant app mode") -public class WifiConfigurationTest extends AndroidTestCase { - private WifiManager mWifiManager; - @Override - protected void setUp() throws Exception { - super.setUp(); - mWifiManager = (WifiManager) mContext - .getSystemService(Context.WIFI_SERVICE); - } - - public void testWifiConfiguration() { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - List wifiConfigurations = mWifiManager.getConfiguredNetworks(); - if (wifiConfigurations != null) { - for (int i = 0; i < wifiConfigurations.size(); i++) { - WifiConfiguration wifiConfiguration = wifiConfigurations.get(i); - assertNotNull(wifiConfiguration); - assertNotNull(wifiConfiguration.toString()); - } - } - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java deleted file mode 100644 index e4c4b006dc..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java +++ /dev/null @@ -1,796 +0,0 @@ -/* - * Copyright (C) 2013 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.wifi.cts; - -import android.content.Context; -import android.content.pm.PackageManager; -import android.net.wifi.WifiEnterpriseConfig; -import android.net.wifi.WifiEnterpriseConfig.Eap; -import android.net.wifi.WifiEnterpriseConfig.Phase2; -import android.net.wifi.WifiManager; -import android.platform.test.annotations.AppModeFull; -import android.test.AndroidTestCase; - -import com.android.compatibility.common.util.SystemUtil; - -import java.io.ByteArrayInputStream; -import java.security.KeyFactory; -import java.security.PrivateKey; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.security.spec.PKCS8EncodedKeySpec; - -@AppModeFull(reason = "Cannot get WifiManager in instant app mode") -public class WifiEnterpriseConfigTest extends AndroidTestCase { - private WifiManager mWifiManager; - - private static final String SSID = "\"TestSSID\""; - private static final String IDENTITY = "identity"; - private static final String PASSWORD = "password"; - private static final String SUBJECT_MATCH = "subjectmatch"; - private static final String ALT_SUBJECT_MATCH = "altsubjectmatch"; - private static final String DOM_SUBJECT_MATCH = "domsubjectmatch"; - private static final String PLMN = "plmn"; - private static final String REALM = "realm"; - private static final String ANON_IDENTITY = "anonidentity"; - private static final int ENABLE_DELAY = 10000; - - /* - * The keys and certificates below are generated with: - * - * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem - * openssl ecparam -name prime256v1 -out ecparam.pem - * openssl req -newkey ec:ecparam.pem -keyout userkey.pem -nodes -days 3650 -out userkey.req - * mkdir -p demoCA/newcerts - * touch demoCA/index.txt - * echo "01" > demoCA/serial - * openssl ca -out usercert.pem -in userkey.req -cert cacert.pem -keyfile cakey.pem -days 3650 - */ - - /** - * Generated from above and converted with: - * - * openssl x509 -outform d -in cacert.pem | xxd -i | sed 's/0x/(byte) 0x/g' - */ - - private static final byte[] FAKE_EC_1 = { - (byte) 0x30, (byte) 0x82, (byte) 0x04, (byte) 0x2f, (byte) 0x30, (byte) 0x82, - (byte) 0x03, (byte) 0x17, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01, - (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0xa7, (byte) 0xe4, - (byte) 0x70, (byte) 0x50, (byte) 0x9b, (byte) 0xd2, (byte) 0x68, (byte) 0x68, - (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, - (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, - (byte) 0x0b, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0xad, - (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41, - (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, - (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, - (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, - (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x12, - (byte) 0x30, (byte) 0x10, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, - (byte) 0x07, (byte) 0x0c, (byte) 0x09, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, - (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x69, (byte) 0x74, (byte) 0x79, - (byte) 0x31, (byte) 0x15, (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, (byte) 0x53, - (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x6f, - (byte) 0x6d, (byte) 0x70, (byte) 0x61, (byte) 0x6e, (byte) 0x79, (byte) 0x31, - (byte) 0x10, (byte) 0x30, (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x07, (byte) 0x53, (byte) 0x65, - (byte) 0x63, (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x31, - (byte) 0x21, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x18, (byte) 0x57, (byte) 0x69, - (byte) 0x66, (byte) 0x69, (byte) 0x45, (byte) 0x6e, (byte) 0x74, (byte) 0x65, - (byte) 0x72, (byte) 0x70, (byte) 0x72, (byte) 0x69, (byte) 0x73, (byte) 0x65, - (byte) 0x43, (byte) 0x6f, (byte) 0x6e, (byte) 0x66, (byte) 0x69, (byte) 0x67, - (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x31, (byte) 0x29, - (byte) 0x30, (byte) 0x27, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, - (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x09, - (byte) 0x01, (byte) 0x16, (byte) 0x1a, (byte) 0x61, (byte) 0x6e, (byte) 0x2d, - (byte) 0x65, (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6c, (byte) 0x2d, - (byte) 0x61, (byte) 0x64, (byte) 0x72, (byte) 0x65, (byte) 0x73, (byte) 0x73, - (byte) 0x40, (byte) 0x64, (byte) 0x6f, (byte) 0x6d, (byte) 0x61, (byte) 0x69, - (byte) 0x6e, (byte) 0x2e, (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, - (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x31, (byte) 0x36, (byte) 0x30, - (byte) 0x31, (byte) 0x31, (byte) 0x35, (byte) 0x31, (byte) 0x31, (byte) 0x31, - (byte) 0x38, (byte) 0x35, (byte) 0x31, (byte) 0x5a, (byte) 0x17, (byte) 0x0d, - (byte) 0x32, (byte) 0x36, (byte) 0x30, (byte) 0x31, (byte) 0x31, (byte) 0x32, - (byte) 0x31, (byte) 0x31, (byte) 0x31, (byte) 0x38, (byte) 0x35, (byte) 0x31, - (byte) 0x5a, (byte) 0x30, (byte) 0x81, (byte) 0xad, (byte) 0x31, (byte) 0x0b, - (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, - (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41, (byte) 0x55, (byte) 0x31, - (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x53, (byte) 0x6f, - (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x74, (byte) 0x61, - (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x12, (byte) 0x30, (byte) 0x10, - (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x0c, - (byte) 0x09, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, - (byte) 0x43, (byte) 0x69, (byte) 0x74, (byte) 0x79, (byte) 0x31, (byte) 0x15, - (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, - (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, - (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x6f, (byte) 0x6d, (byte) 0x70, - (byte) 0x61, (byte) 0x6e, (byte) 0x79, (byte) 0x31, (byte) 0x10, (byte) 0x30, - (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0b, - (byte) 0x0c, (byte) 0x07, (byte) 0x53, (byte) 0x65, (byte) 0x63, (byte) 0x74, - (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x31, (byte) 0x21, (byte) 0x30, - (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03, - (byte) 0x0c, (byte) 0x18, (byte) 0x57, (byte) 0x69, (byte) 0x66, (byte) 0x69, - (byte) 0x45, (byte) 0x6e, (byte) 0x74, (byte) 0x65, (byte) 0x72, (byte) 0x70, - (byte) 0x72, (byte) 0x69, (byte) 0x73, (byte) 0x65, (byte) 0x43, (byte) 0x6f, - (byte) 0x6e, (byte) 0x66, (byte) 0x69, (byte) 0x67, (byte) 0x54, (byte) 0x65, - (byte) 0x73, (byte) 0x74, (byte) 0x31, (byte) 0x29, (byte) 0x30, (byte) 0x27, - (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, - (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x09, (byte) 0x01, (byte) 0x16, - (byte) 0x1a, (byte) 0x61, (byte) 0x6e, (byte) 0x2d, (byte) 0x65, (byte) 0x6d, - (byte) 0x61, (byte) 0x69, (byte) 0x6c, (byte) 0x2d, (byte) 0x61, (byte) 0x64, - (byte) 0x72, (byte) 0x65, (byte) 0x73, (byte) 0x73, (byte) 0x40, (byte) 0x64, - (byte) 0x6f, (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6e, (byte) 0x2e, - (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, (byte) 0x82, (byte) 0x01, - (byte) 0x22, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, - (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, - (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x82, - (byte) 0x01, (byte) 0x0f, (byte) 0x00, (byte) 0x30, (byte) 0x82, (byte) 0x01, - (byte) 0x0a, (byte) 0x02, (byte) 0x82, (byte) 0x01, (byte) 0x01, (byte) 0x00, - (byte) 0xb4, (byte) 0x6e, (byte) 0x66, (byte) 0x24, (byte) 0xe7, (byte) 0x5c, - (byte) 0xd8, (byte) 0x6f, (byte) 0x08, (byte) 0xd3, (byte) 0x80, (byte) 0xa3, - (byte) 0xb9, (byte) 0xaf, (byte) 0x90, (byte) 0xef, (byte) 0x1c, (byte) 0x2a, - (byte) 0x5f, (byte) 0x39, (byte) 0x0b, (byte) 0xbd, (byte) 0x75, (byte) 0x0d, - (byte) 0x3e, (byte) 0x19, (byte) 0x2e, (byte) 0x47, (byte) 0x1e, (byte) 0x14, - (byte) 0xc2, (byte) 0x1a, (byte) 0x59, (byte) 0xcc, (byte) 0x1b, (byte) 0xb6, - (byte) 0x9b, (byte) 0x46, (byte) 0x1f, (byte) 0x7f, (byte) 0x71, (byte) 0xdd, - (byte) 0x38, (byte) 0xbe, (byte) 0x89, (byte) 0x30, (byte) 0xba, (byte) 0x88, - (byte) 0xfb, (byte) 0x3f, (byte) 0x57, (byte) 0x35, (byte) 0xe7, (byte) 0xa7, - (byte) 0x2f, (byte) 0x2c, (byte) 0x8d, (byte) 0x7c, (byte) 0xe2, (byte) 0xd8, - (byte) 0x0c, (byte) 0x0a, (byte) 0xe6, (byte) 0x62, (byte) 0x46, (byte) 0x8c, - (byte) 0xf4, (byte) 0x51, (byte) 0xfc, (byte) 0x6a, (byte) 0x79, (byte) 0xdd, - (byte) 0x0a, (byte) 0x41, (byte) 0x23, (byte) 0xd3, (byte) 0xe9, (byte) 0x5e, - (byte) 0x91, (byte) 0xcd, (byte) 0xbd, (byte) 0x55, (byte) 0x28, (byte) 0x71, - (byte) 0xec, (byte) 0x52, (byte) 0x19, (byte) 0x85, (byte) 0x0c, (byte) 0x1b, - (byte) 0xfa, (byte) 0xbf, (byte) 0xfe, (byte) 0xae, (byte) 0x5c, (byte) 0x3b, - (byte) 0x99, (byte) 0x42, (byte) 0xd4, (byte) 0xe7, (byte) 0x17, (byte) 0xec, - (byte) 0x41, (byte) 0x22, (byte) 0x2c, (byte) 0x1e, (byte) 0x7b, (byte) 0x53, - (byte) 0xad, (byte) 0x02, (byte) 0xfd, (byte) 0xf6, (byte) 0x4a, (byte) 0xb1, - (byte) 0x6e, (byte) 0x6c, (byte) 0x87, (byte) 0xf5, (byte) 0x7d, (byte) 0x9b, - (byte) 0x34, (byte) 0x0e, (byte) 0x3b, (byte) 0x0e, (byte) 0xaa, (byte) 0xc5, - (byte) 0xc4, (byte) 0xef, (byte) 0xf2, (byte) 0x5a, (byte) 0xa9, (byte) 0xac, - (byte) 0x19, (byte) 0xce, (byte) 0x5f, (byte) 0xc5, (byte) 0xcc, (byte) 0x0d, - (byte) 0xee, (byte) 0x7f, (byte) 0x32, (byte) 0xb4, (byte) 0xfe, (byte) 0xc1, - (byte) 0xca, (byte) 0x9b, (byte) 0x3f, (byte) 0xad, (byte) 0x2c, (byte) 0x7a, - (byte) 0xc5, (byte) 0x8d, (byte) 0x48, (byte) 0xa1, (byte) 0xc9, (byte) 0x74, - (byte) 0xfe, (byte) 0x8a, (byte) 0xe3, (byte) 0xb0, (byte) 0x92, (byte) 0xee, - (byte) 0x73, (byte) 0x09, (byte) 0x0a, (byte) 0xbc, (byte) 0xc8, (byte) 0x63, - (byte) 0xba, (byte) 0x0e, (byte) 0x26, (byte) 0xab, (byte) 0x1e, (byte) 0xff, - (byte) 0xbc, (byte) 0x24, (byte) 0x12, (byte) 0x26, (byte) 0x11, (byte) 0xe0, - (byte) 0x04, (byte) 0xcb, (byte) 0x96, (byte) 0x7d, (byte) 0x41, (byte) 0xf7, - (byte) 0x79, (byte) 0x32, (byte) 0x05, (byte) 0x33, (byte) 0x19, (byte) 0x6e, - (byte) 0xb9, (byte) 0x75, (byte) 0xf3, (byte) 0x50, (byte) 0xa4, (byte) 0xc3, - (byte) 0x55, (byte) 0x9d, (byte) 0x8f, (byte) 0xb6, (byte) 0xab, (byte) 0x97, - (byte) 0xe7, (byte) 0xe2, (byte) 0xe8, (byte) 0x15, (byte) 0xfc, (byte) 0x35, - (byte) 0xbd, (byte) 0xce, (byte) 0x17, (byte) 0xbe, (byte) 0xe3, (byte) 0x73, - (byte) 0xd4, (byte) 0x88, (byte) 0x39, (byte) 0x27, (byte) 0x7e, (byte) 0x6d, - (byte) 0xa2, (byte) 0x27, (byte) 0xfa, (byte) 0x96, (byte) 0xe3, (byte) 0x38, - (byte) 0xc0, (byte) 0xa1, (byte) 0x55, (byte) 0xc6, (byte) 0xf3, (byte) 0x20, - (byte) 0xea, (byte) 0x50, (byte) 0x8d, (byte) 0x6c, (byte) 0x94, (byte) 0x9a, - (byte) 0x43, (byte) 0x74, (byte) 0xc0, (byte) 0xfa, (byte) 0xef, (byte) 0xe0, - (byte) 0xb1, (byte) 0x1c, (byte) 0x6d, (byte) 0x5e, (byte) 0x44, (byte) 0x08, - (byte) 0xef, (byte) 0xd5, (byte) 0x80, (byte) 0xad, (byte) 0x02, (byte) 0x03, - (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3, (byte) 0x50, (byte) 0x30, - (byte) 0x4e, (byte) 0x30, (byte) 0x1d, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16, (byte) 0x04, (byte) 0x14, - (byte) 0xe9, (byte) 0xd0, (byte) 0x9e, (byte) 0x0e, (byte) 0x62, (byte) 0x31, - (byte) 0x02, (byte) 0x9a, (byte) 0x33, (byte) 0xd7, (byte) 0x4a, (byte) 0x93, - (byte) 0x0d, (byte) 0xf3, (byte) 0xd6, (byte) 0x74, (byte) 0xce, (byte) 0x69, - (byte) 0xe1, (byte) 0xef, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04, (byte) 0x18, (byte) 0x30, - (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0xe9, (byte) 0xd0, (byte) 0x9e, - (byte) 0x0e, (byte) 0x62, (byte) 0x31, (byte) 0x02, (byte) 0x9a, (byte) 0x33, - (byte) 0xd7, (byte) 0x4a, (byte) 0x93, (byte) 0x0d, (byte) 0xf3, (byte) 0xd6, - (byte) 0x74, (byte) 0xce, (byte) 0x69, (byte) 0xe1, (byte) 0xef, (byte) 0x30, - (byte) 0x0c, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13, - (byte) 0x04, (byte) 0x05, (byte) 0x30, (byte) 0x03, (byte) 0x01, (byte) 0x01, - (byte) 0xff, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, - (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, - (byte) 0x01, (byte) 0x0b, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x82, - (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x52, (byte) 0x70, (byte) 0xb6, - (byte) 0x10, (byte) 0x7f, (byte) 0xaa, (byte) 0x86, (byte) 0x8f, (byte) 0x02, - (byte) 0xb0, (byte) 0x97, (byte) 0x89, (byte) 0xb9, (byte) 0x04, (byte) 0x1d, - (byte) 0x79, (byte) 0xa3, (byte) 0x74, (byte) 0x7c, (byte) 0xdf, (byte) 0xad, - (byte) 0x87, (byte) 0xe4, (byte) 0x00, (byte) 0xd3, (byte) 0x3a, (byte) 0x5c, - (byte) 0x48, (byte) 0x3b, (byte) 0xfe, (byte) 0x77, (byte) 0xfd, (byte) 0xbe, - (byte) 0xce, (byte) 0x5b, (byte) 0xd2, (byte) 0xea, (byte) 0x3e, (byte) 0x7f, - (byte) 0xef, (byte) 0x20, (byte) 0x0d, (byte) 0x0b, (byte) 0xc7, (byte) 0xc4, - (byte) 0x25, (byte) 0x20, (byte) 0xe1, (byte) 0x8f, (byte) 0xc5, (byte) 0x19, - (byte) 0x37, (byte) 0x9c, (byte) 0xa0, (byte) 0x9d, (byte) 0x02, (byte) 0x30, - (byte) 0x5f, (byte) 0x49, (byte) 0x4e, (byte) 0x56, (byte) 0xc4, (byte) 0xab, - (byte) 0xcb, (byte) 0x5c, (byte) 0xe6, (byte) 0x40, (byte) 0x93, (byte) 0x92, - (byte) 0xee, (byte) 0xa1, (byte) 0x69, (byte) 0x7d, (byte) 0x10, (byte) 0x6b, - (byte) 0xd4, (byte) 0xf7, (byte) 0xec, (byte) 0xd9, (byte) 0xa5, (byte) 0x29, - (byte) 0x63, (byte) 0x29, (byte) 0xd9, (byte) 0x27, (byte) 0x2d, (byte) 0x5e, - (byte) 0x34, (byte) 0x37, (byte) 0xa9, (byte) 0xba, (byte) 0x0a, (byte) 0x7b, - (byte) 0x99, (byte) 0x1a, (byte) 0x7d, (byte) 0xa7, (byte) 0xa7, (byte) 0xf0, - (byte) 0xbf, (byte) 0x40, (byte) 0x29, (byte) 0x5d, (byte) 0x2f, (byte) 0x2e, - (byte) 0x0f, (byte) 0x35, (byte) 0x90, (byte) 0xb5, (byte) 0xc3, (byte) 0xfd, - (byte) 0x1e, (byte) 0xe2, (byte) 0xb3, (byte) 0xae, (byte) 0xf9, (byte) 0xde, - (byte) 0x9d, (byte) 0x76, (byte) 0xe1, (byte) 0x20, (byte) 0xf5, (byte) 0x1c, - (byte) 0x30, (byte) 0x42, (byte) 0x80, (byte) 0x2a, (byte) 0x4f, (byte) 0x85, - (byte) 0x5c, (byte) 0xb4, (byte) 0x49, (byte) 0x68, (byte) 0x6c, (byte) 0x7c, - (byte) 0x2a, (byte) 0xc8, (byte) 0xbc, (byte) 0x15, (byte) 0xed, (byte) 0x88, - (byte) 0xfd, (byte) 0x8a, (byte) 0x63, (byte) 0xe0, (byte) 0x93, (byte) 0xfd, - (byte) 0x86, (byte) 0xab, (byte) 0xa9, (byte) 0xf6, (byte) 0x63, (byte) 0xa5, - (byte) 0x29, (byte) 0xaf, (byte) 0xdc, (byte) 0x8f, (byte) 0xca, (byte) 0xc2, - (byte) 0x28, (byte) 0xe7, (byte) 0x26, (byte) 0x89, (byte) 0x75, (byte) 0xf1, - (byte) 0x3e, (byte) 0x2e, (byte) 0x86, (byte) 0x11, (byte) 0x8b, (byte) 0xfa, - (byte) 0xf5, (byte) 0xb4, (byte) 0xb4, (byte) 0x04, (byte) 0x02, (byte) 0xa3, - (byte) 0x85, (byte) 0x81, (byte) 0xad, (byte) 0xb3, (byte) 0xec, (byte) 0x2d, - (byte) 0x4b, (byte) 0x40, (byte) 0x59, (byte) 0x61, (byte) 0x0d, (byte) 0x59, - (byte) 0x09, (byte) 0x09, (byte) 0xee, (byte) 0xc7, (byte) 0x51, (byte) 0xef, - (byte) 0x6f, (byte) 0xd6, (byte) 0x9a, (byte) 0xa5, (byte) 0x45, (byte) 0xa2, - (byte) 0x89, (byte) 0xc2, (byte) 0x97, (byte) 0x93, (byte) 0xbc, (byte) 0x5b, - (byte) 0x37, (byte) 0x55, (byte) 0x73, (byte) 0x55, (byte) 0x0c, (byte) 0x9c, - (byte) 0xcb, (byte) 0x10, (byte) 0xec, (byte) 0x76, (byte) 0xfe, (byte) 0xa7, - (byte) 0x70, (byte) 0x4e, (byte) 0x9a, (byte) 0xa2, (byte) 0xf9, (byte) 0x40, - (byte) 0xdd, (byte) 0x96, (byte) 0x7d, (byte) 0x67, (byte) 0x5c, (byte) 0x8e, - (byte) 0x43, (byte) 0x1a, (byte) 0x26, (byte) 0xaa, (byte) 0xee, (byte) 0x38, - (byte) 0x11, (byte) 0x26, (byte) 0x3d, (byte) 0x69, (byte) 0xc7, (byte) 0x6a, - (byte) 0xe7, (byte) 0xbd, (byte) 0x67, (byte) 0x70, (byte) 0x35, (byte) 0xff, - (byte) 0x72, (byte) 0x2c, (byte) 0x87, (byte) 0x82, (byte) 0x68, (byte) 0x3f, - (byte) 0x8d - }; - - private static final byte[] FAKE_EC_2 = { - (byte) 0x30, (byte) 0x82, (byte) 0x04, (byte) 0x4f, (byte) 0x30, (byte) 0x82, - (byte) 0x03, (byte) 0x37, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01, - (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0xd9, (byte) 0xc4, - (byte) 0xe1, (byte) 0xfc, (byte) 0x3d, (byte) 0x02, (byte) 0x21, (byte) 0x1f, - (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, - (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, - (byte) 0x0b, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0xbd, - (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41, - (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, - (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, - (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, - (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x12, - (byte) 0x30, (byte) 0x10, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, - (byte) 0x07, (byte) 0x0c, (byte) 0x09, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, - (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x69, (byte) 0x74, (byte) 0x79, - (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x12, (byte) 0x53, - (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x4f, (byte) 0x74, - (byte) 0x68, (byte) 0x65, (byte) 0x72, (byte) 0x2d, (byte) 0x43, (byte) 0x6f, - (byte) 0x6d, (byte) 0x70, (byte) 0x61, (byte) 0x6e, (byte) 0x79, (byte) 0x31, - (byte) 0x15, (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x0c, (byte) 0x53, (byte) 0x6f, - (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x65, (byte) 0x63, - (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x31, (byte) 0x21, - (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, - (byte) 0x03, (byte) 0x0c, (byte) 0x18, (byte) 0x57, (byte) 0x69, (byte) 0x66, - (byte) 0x69, (byte) 0x45, (byte) 0x6e, (byte) 0x74, (byte) 0x65, (byte) 0x72, - (byte) 0x70, (byte) 0x72, (byte) 0x69, (byte) 0x73, (byte) 0x65, (byte) 0x43, - (byte) 0x6f, (byte) 0x6e, (byte) 0x66, (byte) 0x69, (byte) 0x67, (byte) 0x54, - (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x31, (byte) 0x2e, (byte) 0x30, - (byte) 0x2c, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, - (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x09, (byte) 0x01, - (byte) 0x16, (byte) 0x1f, (byte) 0x61, (byte) 0x6e, (byte) 0x2d, (byte) 0x65, - (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6c, (byte) 0x2d, (byte) 0x61, - (byte) 0x64, (byte) 0x72, (byte) 0x65, (byte) 0x73, (byte) 0x73, (byte) 0x40, - (byte) 0x73, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x64, - (byte) 0x6f, (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6e, (byte) 0x2e, - (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, (byte) 0x1e, (byte) 0x17, - (byte) 0x0d, (byte) 0x31, (byte) 0x36, (byte) 0x30, (byte) 0x31, (byte) 0x31, - (byte) 0x35, (byte) 0x31, (byte) 0x31, (byte) 0x33, (byte) 0x32, (byte) 0x34, - (byte) 0x36, (byte) 0x5a, (byte) 0x17, (byte) 0x0d, (byte) 0x32, (byte) 0x36, - (byte) 0x30, (byte) 0x31, (byte) 0x31, (byte) 0x32, (byte) 0x31, (byte) 0x31, - (byte) 0x33, (byte) 0x32, (byte) 0x34, (byte) 0x36, (byte) 0x5a, (byte) 0x30, - (byte) 0x81, (byte) 0xbd, (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, - (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, - (byte) 0x02, (byte) 0x41, (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30, - (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, - (byte) 0x0c, (byte) 0x0a, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, - (byte) 0x2d, (byte) 0x53, (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65, - (byte) 0x31, (byte) 0x12, (byte) 0x30, (byte) 0x10, (byte) 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x0c, (byte) 0x09, (byte) 0x53, - (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x69, - (byte) 0x74, (byte) 0x79, (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, - (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, - (byte) 0x12, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, - (byte) 0x4f, (byte) 0x74, (byte) 0x68, (byte) 0x65, (byte) 0x72, (byte) 0x2d, - (byte) 0x43, (byte) 0x6f, (byte) 0x6d, (byte) 0x70, (byte) 0x61, (byte) 0x6e, - (byte) 0x79, (byte) 0x31, (byte) 0x15, (byte) 0x30, (byte) 0x13, (byte) 0x06, - (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x0c, - (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, - (byte) 0x65, (byte) 0x63, (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e, - (byte) 0x31, (byte) 0x21, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x18, (byte) 0x57, - (byte) 0x69, (byte) 0x66, (byte) 0x69, (byte) 0x45, (byte) 0x6e, (byte) 0x74, - (byte) 0x65, (byte) 0x72, (byte) 0x70, (byte) 0x72, (byte) 0x69, (byte) 0x73, - (byte) 0x65, (byte) 0x43, (byte) 0x6f, (byte) 0x6e, (byte) 0x66, (byte) 0x69, - (byte) 0x67, (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x31, - (byte) 0x2e, (byte) 0x30, (byte) 0x2c, (byte) 0x06, (byte) 0x09, (byte) 0x2a, - (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, - (byte) 0x09, (byte) 0x01, (byte) 0x16, (byte) 0x1f, (byte) 0x61, (byte) 0x6e, - (byte) 0x2d, (byte) 0x65, (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6c, - (byte) 0x2d, (byte) 0x61, (byte) 0x64, (byte) 0x72, (byte) 0x65, (byte) 0x73, - (byte) 0x73, (byte) 0x40, (byte) 0x73, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, - (byte) 0x2d, (byte) 0x64, (byte) 0x6f, (byte) 0x6d, (byte) 0x61, (byte) 0x69, - (byte) 0x6e, (byte) 0x2e, (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, - (byte) 0x82, (byte) 0x01, (byte) 0x22, (byte) 0x30, (byte) 0x0d, (byte) 0x06, - (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, - (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, - (byte) 0x03, (byte) 0x82, (byte) 0x01, (byte) 0x0f, (byte) 0x00, (byte) 0x30, - (byte) 0x82, (byte) 0x01, (byte) 0x0a, (byte) 0x02, (byte) 0x82, (byte) 0x01, - (byte) 0x01, (byte) 0x00, (byte) 0xa9, (byte) 0xa3, (byte) 0x21, (byte) 0xfd, - (byte) 0xa6, (byte) 0xc1, (byte) 0x04, (byte) 0x48, (byte) 0xc2, (byte) 0xc8, - (byte) 0x44, (byte) 0x50, (byte) 0xc4, (byte) 0x6d, (byte) 0x35, (byte) 0x24, - (byte) 0xf0, (byte) 0x6d, (byte) 0x69, (byte) 0xfb, (byte) 0xd1, (byte) 0xfc, - (byte) 0xde, (byte) 0xe9, (byte) 0xdb, (byte) 0xca, (byte) 0xee, (byte) 0x24, - (byte) 0x3d, (byte) 0x85, (byte) 0x8d, (byte) 0x84, (byte) 0xb4, (byte) 0x73, - (byte) 0xd1, (byte) 0x09, (byte) 0x37, (byte) 0x16, (byte) 0x80, (byte) 0x70, - (byte) 0x6b, (byte) 0x61, (byte) 0xcc, (byte) 0xf2, (byte) 0x98, (byte) 0xbd, - (byte) 0x53, (byte) 0x3a, (byte) 0x68, (byte) 0x60, (byte) 0x02, (byte) 0xba, - (byte) 0x0c, (byte) 0x53, (byte) 0x96, (byte) 0xfb, (byte) 0x80, (byte) 0xd1, - (byte) 0x5b, (byte) 0xc3, (byte) 0xcb, (byte) 0x7a, (byte) 0x81, (byte) 0x00, - (byte) 0x5d, (byte) 0x20, (byte) 0x72, (byte) 0xc0, (byte) 0xe4, (byte) 0x48, - (byte) 0x0e, (byte) 0xa2, (byte) 0xcd, (byte) 0xa2, (byte) 0x63, (byte) 0x8c, - (byte) 0x05, (byte) 0x7c, (byte) 0x63, (byte) 0x5b, (byte) 0xda, (byte) 0x0e, - (byte) 0xa7, (byte) 0x05, (byte) 0x09, (byte) 0x6d, (byte) 0xd5, (byte) 0xe4, - (byte) 0x3a, (byte) 0x4e, (byte) 0xa1, (byte) 0xf5, (byte) 0xfd, (byte) 0x47, - (byte) 0xee, (byte) 0x7b, (byte) 0xa3, (byte) 0x4c, (byte) 0x8c, (byte) 0xd3, - (byte) 0xbb, (byte) 0x58, (byte) 0x0f, (byte) 0x1c, (byte) 0x56, (byte) 0x80, - (byte) 0x80, (byte) 0xb5, (byte) 0xf9, (byte) 0x80, (byte) 0xc2, (byte) 0xd1, - (byte) 0x1d, (byte) 0x3f, (byte) 0xe8, (byte) 0x2a, (byte) 0x63, (byte) 0x0b, - (byte) 0x54, (byte) 0x5f, (byte) 0xd4, (byte) 0xcb, (byte) 0xb7, (byte) 0x94, - (byte) 0xe2, (byte) 0x35, (byte) 0x65, (byte) 0x59, (byte) 0xd1, (byte) 0x72, - (byte) 0xa4, (byte) 0xb8, (byte) 0xee, (byte) 0x82, (byte) 0x11, (byte) 0x7a, - (byte) 0x4c, (byte) 0x26, (byte) 0x66, (byte) 0x9b, (byte) 0x27, (byte) 0x3d, - (byte) 0x14, (byte) 0x4b, (byte) 0x4b, (byte) 0xc8, (byte) 0xf0, (byte) 0x6e, - (byte) 0x43, (byte) 0x8f, (byte) 0xee, (byte) 0x1f, (byte) 0xeb, (byte) 0x20, - (byte) 0xe2, (byte) 0x4c, (byte) 0x79, (byte) 0xbf, (byte) 0x21, (byte) 0x0d, - (byte) 0x36, (byte) 0xed, (byte) 0x5f, (byte) 0xcc, (byte) 0x70, (byte) 0x68, - (byte) 0x8a, (byte) 0x05, (byte) 0x7c, (byte) 0x2f, (byte) 0x1b, (byte) 0xe9, - (byte) 0xec, (byte) 0x83, (byte) 0x6e, (byte) 0x9a, (byte) 0x78, (byte) 0x31, - (byte) 0x3d, (byte) 0xf4, (byte) 0xde, (byte) 0x1b, (byte) 0xd2, (byte) 0x76, - (byte) 0x32, (byte) 0x6c, (byte) 0x1e, (byte) 0xc9, (byte) 0x90, (byte) 0x7f, - (byte) 0xc4, (byte) 0x30, (byte) 0xc0, (byte) 0xae, (byte) 0xab, (byte) 0x70, - (byte) 0x08, (byte) 0x78, (byte) 0xbf, (byte) 0x2e, (byte) 0x8b, (byte) 0x07, - (byte) 0xab, (byte) 0x8f, (byte) 0x03, (byte) 0xc5, (byte) 0xd3, (byte) 0xeb, - (byte) 0x98, (byte) 0x19, (byte) 0x50, (byte) 0x83, (byte) 0x52, (byte) 0xf7, - (byte) 0xff, (byte) 0xf5, (byte) 0x89, (byte) 0xe6, (byte) 0xe7, (byte) 0xa7, - (byte) 0xcb, (byte) 0xdf, (byte) 0x96, (byte) 0x9d, (byte) 0x14, (byte) 0x04, - (byte) 0x5e, (byte) 0x45, (byte) 0x82, (byte) 0xf7, (byte) 0x23, (byte) 0x1a, - (byte) 0xb6, (byte) 0x64, (byte) 0x57, (byte) 0xe8, (byte) 0x7e, (byte) 0xa1, - (byte) 0xaf, (byte) 0x58, (byte) 0x68, (byte) 0x70, (byte) 0xc5, (byte) 0x0f, - (byte) 0x8d, (byte) 0x54, (byte) 0xf3, (byte) 0x49, (byte) 0xa3, (byte) 0x97, - (byte) 0x32, (byte) 0xa7, (byte) 0x2a, (byte) 0x79, (byte) 0xbe, (byte) 0xcd, - (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3, - (byte) 0x50, (byte) 0x30, (byte) 0x4e, (byte) 0x30, (byte) 0x1d, (byte) 0x06, - (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16, - (byte) 0x04, (byte) 0x14, (byte) 0xac, (byte) 0xf3, (byte) 0x73, (byte) 0x9a, - (byte) 0x25, (byte) 0x08, (byte) 0x01, (byte) 0x07, (byte) 0x86, (byte) 0x8b, - (byte) 0xc4, (byte) 0xed, (byte) 0xb1, (byte) 0x6b, (byte) 0x53, (byte) 0xa3, - (byte) 0x21, (byte) 0xb4, (byte) 0xb4, (byte) 0x46, (byte) 0x30, (byte) 0x1f, - (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04, - (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0xac, - (byte) 0xf3, (byte) 0x73, (byte) 0x9a, (byte) 0x25, (byte) 0x08, (byte) 0x01, - (byte) 0x07, (byte) 0x86, (byte) 0x8b, (byte) 0xc4, (byte) 0xed, (byte) 0xb1, - (byte) 0x6b, (byte) 0x53, (byte) 0xa3, (byte) 0x21, (byte) 0xb4, (byte) 0xb4, - (byte) 0x46, (byte) 0x30, (byte) 0x0c, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x1d, (byte) 0x13, (byte) 0x04, (byte) 0x05, (byte) 0x30, (byte) 0x03, - (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x30, (byte) 0x0d, (byte) 0x06, - (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, - (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x0b, (byte) 0x05, (byte) 0x00, - (byte) 0x03, (byte) 0x82, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x16, - (byte) 0xf6, (byte) 0xd0, (byte) 0xe1, (byte) 0x14, (byte) 0x2d, (byte) 0x52, - (byte) 0x47, (byte) 0xa2, (byte) 0x89, (byte) 0xe6, (byte) 0x7f, (byte) 0xac, - (byte) 0x88, (byte) 0x04, (byte) 0x15, (byte) 0x21, (byte) 0x00, (byte) 0x72, - (byte) 0xf9, (byte) 0xee, (byte) 0xb2, (byte) 0x1b, (byte) 0x8e, (byte) 0x46, - (byte) 0x8b, (byte) 0x90, (byte) 0x20, (byte) 0x4f, (byte) 0xa7, (byte) 0xae, - (byte) 0x30, (byte) 0xb6, (byte) 0x24, (byte) 0xc5, (byte) 0x54, (byte) 0xaf, - (byte) 0x6c, (byte) 0x1e, (byte) 0xd6, (byte) 0x73, (byte) 0x22, (byte) 0x48, - (byte) 0x07, (byte) 0xb5, (byte) 0x13, (byte) 0x35, (byte) 0xbb, (byte) 0x9e, - (byte) 0xd9, (byte) 0x19, (byte) 0x79, (byte) 0xda, (byte) 0x76, (byte) 0x7f, - (byte) 0xf7, (byte) 0x87, (byte) 0xc9, (byte) 0xc3, (byte) 0x0b, (byte) 0x38, - (byte) 0x20, (byte) 0x26, (byte) 0xfc, (byte) 0x7f, (byte) 0x32, (byte) 0x2a, - (byte) 0xd5, (byte) 0x09, (byte) 0x87, (byte) 0xda, (byte) 0x23, (byte) 0x1f, - (byte) 0x71, (byte) 0x83, (byte) 0x00, (byte) 0x17, (byte) 0xf6, (byte) 0xb9, - (byte) 0x57, (byte) 0x21, (byte) 0xdf, (byte) 0x29, (byte) 0xcc, (byte) 0xdb, - (byte) 0xe9, (byte) 0x2c, (byte) 0xba, (byte) 0x86, (byte) 0x34, (byte) 0x53, - (byte) 0x29, (byte) 0x09, (byte) 0xc7, (byte) 0x3c, (byte) 0x8e, (byte) 0xa3, - (byte) 0x86, (byte) 0x81, (byte) 0x26, (byte) 0x7b, (byte) 0xa1, (byte) 0xbe, - (byte) 0xbc, (byte) 0xc9, (byte) 0x83, (byte) 0xb5, (byte) 0x36, (byte) 0x65, - (byte) 0x51, (byte) 0xb4, (byte) 0x41, (byte) 0xf0, (byte) 0x05, (byte) 0x78, - (byte) 0x3a, (byte) 0xa6, (byte) 0xad, (byte) 0x4b, (byte) 0x08, (byte) 0xd1, - (byte) 0xe4, (byte) 0xf1, (byte) 0x2e, (byte) 0xc7, (byte) 0x23, (byte) 0x6d, - (byte) 0xf0, (byte) 0x9d, (byte) 0x60, (byte) 0x6d, (byte) 0xe7, (byte) 0x11, - (byte) 0xaf, (byte) 0x41, (byte) 0x68, (byte) 0xee, (byte) 0x06, (byte) 0x76, - (byte) 0x82, (byte) 0x48, (byte) 0xee, (byte) 0x41, (byte) 0xc4, (byte) 0xf8, - (byte) 0xe1, (byte) 0x83, (byte) 0xbc, (byte) 0xa8, (byte) 0xbd, (byte) 0x9c, - (byte) 0x17, (byte) 0x45, (byte) 0xf4, (byte) 0x36, (byte) 0x67, (byte) 0x47, - (byte) 0x0e, (byte) 0x32, (byte) 0x13, (byte) 0x6e, (byte) 0xc1, (byte) 0x1e, - (byte) 0x08, (byte) 0xef, (byte) 0x10, (byte) 0xdf, (byte) 0x45, (byte) 0xbf, - (byte) 0x5a, (byte) 0xc4, (byte) 0x44, (byte) 0x4c, (byte) 0xd0, (byte) 0xd5, - (byte) 0x23, (byte) 0xde, (byte) 0xd7, (byte) 0x83, (byte) 0x1e, (byte) 0xb0, - (byte) 0x27, (byte) 0x4d, (byte) 0x57, (byte) 0xa3, (byte) 0xe8, (byte) 0x36, - (byte) 0x52, (byte) 0x1c, (byte) 0x48, (byte) 0x0a, (byte) 0xc4, (byte) 0xd8, - (byte) 0x32, (byte) 0xfc, (byte) 0xd0, (byte) 0x26, (byte) 0x6f, (byte) 0xa4, - (byte) 0x61, (byte) 0x2c, (byte) 0x3a, (byte) 0xa9, (byte) 0xfe, (byte) 0xa4, - (byte) 0x7a, (byte) 0x58, (byte) 0x54, (byte) 0x58, (byte) 0x96, (byte) 0x2b, - (byte) 0x6e, (byte) 0x9c, (byte) 0xc9, (byte) 0x00, (byte) 0xda, (byte) 0xc6, - (byte) 0xbb, (byte) 0x97, (byte) 0xc4, (byte) 0x95, (byte) 0x32, (byte) 0x6b, - (byte) 0x03, (byte) 0x6f, (byte) 0x33, (byte) 0x59, (byte) 0xd4, (byte) 0xa4, - (byte) 0x4a, (byte) 0x29, (byte) 0x29, (byte) 0x9a, (byte) 0xf4, (byte) 0x87, - (byte) 0x26, (byte) 0xe6, (byte) 0xee, (byte) 0x5c, (byte) 0x0b, (byte) 0xe9, - (byte) 0x98, (byte) 0x5d, (byte) 0xab, (byte) 0x31, (byte) 0xa1, (byte) 0x63, - (byte) 0xaa, (byte) 0x1a, (byte) 0xea, (byte) 0x61, (byte) 0x27, (byte) 0x5e, - (byte) 0x9e, (byte) 0x34, (byte) 0x73 - }; - - /** - * Client certificate generated from above and converted with: - * - * openssl x509 -outform d -in usercert.pem | xxd -i | sed 's/0x/(byte) 0x/g' - */ - private static final byte[] FAKE_EC_3 = { - (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0xdf, (byte) 0x30, (byte) 0x82, - (byte) 0x01, (byte) 0xc7, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01, - (byte) 0x02, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x30, (byte) 0x0d, - (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, - (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x0b, (byte) 0x05, - (byte) 0x00, (byte) 0x30, (byte) 0x64, (byte) 0x31, (byte) 0x0b, (byte) 0x30, - (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06, - (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x0b, - (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, - (byte) 0x08, (byte) 0x0c, (byte) 0x02, (byte) 0x43, (byte) 0x41, (byte) 0x31, - (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x04, (byte) 0x07, (byte) 0x0c, (byte) 0x0d, (byte) 0x4d, (byte) 0x6f, - (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6e, - (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77, (byte) 0x31, - (byte) 0x0f, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x06, (byte) 0x47, (byte) 0x6f, - (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, (byte) 0x31, (byte) 0x10, - (byte) 0x30, (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, - (byte) 0x0b, (byte) 0x0c, (byte) 0x07, (byte) 0x41, (byte) 0x6e, (byte) 0x64, - (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x31, (byte) 0x0d, - (byte) 0x30, (byte) 0x0b, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, - (byte) 0x03, (byte) 0x0c, (byte) 0x04, (byte) 0x54, (byte) 0x45, (byte) 0x53, - (byte) 0x54, (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x31, - (byte) 0x37, (byte) 0x30, (byte) 0x31, (byte) 0x32, (byte) 0x37, (byte) 0x31, - (byte) 0x37, (byte) 0x35, (byte) 0x38, (byte) 0x31, (byte) 0x32, (byte) 0x5a, - (byte) 0x17, (byte) 0x0d, (byte) 0x32, (byte) 0x37, (byte) 0x30, (byte) 0x31, - (byte) 0x32, (byte) 0x35, (byte) 0x31, (byte) 0x37, (byte) 0x35, (byte) 0x38, - (byte) 0x31, (byte) 0x32, (byte) 0x5a, (byte) 0x30, (byte) 0x50, (byte) 0x31, - (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, - (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x02, (byte) 0x43, - (byte) 0x41, (byte) 0x31, (byte) 0x0f, (byte) 0x30, (byte) 0x0d, (byte) 0x06, - (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x06, - (byte) 0x47, (byte) 0x6f, (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, - (byte) 0x31, (byte) 0x10, (byte) 0x30, (byte) 0x0e, (byte) 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x07, (byte) 0x41, - (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, - (byte) 0x31, (byte) 0x11, (byte) 0x30, (byte) 0x0f, (byte) 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x08, (byte) 0x54, - (byte) 0x45, (byte) 0x53, (byte) 0x54, (byte) 0x2d, (byte) 0x55, (byte) 0x53, - (byte) 0x52, (byte) 0x30, (byte) 0x59, (byte) 0x30, (byte) 0x13, (byte) 0x06, - (byte) 0x07, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, - (byte) 0x02, (byte) 0x01, (byte) 0x06, (byte) 0x08, (byte) 0x2a, (byte) 0x86, - (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x03, (byte) 0x01, (byte) 0x07, - (byte) 0x03, (byte) 0x42, (byte) 0x00, (byte) 0x04, (byte) 0x4a, (byte) 0xb8, - (byte) 0x60, (byte) 0x17, (byte) 0x40, (byte) 0x91, (byte) 0x30, (byte) 0xf7, - (byte) 0xdf, (byte) 0x36, (byte) 0x83, (byte) 0x31, (byte) 0xb5, (byte) 0x3a, - (byte) 0xf4, (byte) 0xd4, (byte) 0xa1, (byte) 0xce, (byte) 0xd5, (byte) 0x54, - (byte) 0x97, (byte) 0x93, (byte) 0x7e, (byte) 0x7b, (byte) 0x08, (byte) 0x63, - (byte) 0x37, (byte) 0x62, (byte) 0xf1, (byte) 0x4e, (byte) 0x6a, (byte) 0x2e, - (byte) 0x35, (byte) 0x4e, (byte) 0x9f, (byte) 0x48, (byte) 0xcd, (byte) 0x09, - (byte) 0x17, (byte) 0xb3, (byte) 0xc1, (byte) 0x58, (byte) 0x02, (byte) 0x49, - (byte) 0x7b, (byte) 0x4c, (byte) 0xf7, (byte) 0x9b, (byte) 0xbb, (byte) 0x1b, - (byte) 0x2b, (byte) 0x9c, (byte) 0xe9, (byte) 0x36, (byte) 0xc4, (byte) 0x00, - (byte) 0x81, (byte) 0x2c, (byte) 0x28, (byte) 0xd9, (byte) 0x6b, (byte) 0xad, - (byte) 0xe3, (byte) 0xe8, (byte) 0xa3, (byte) 0x7b, (byte) 0x30, (byte) 0x79, - (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, - (byte) 0x13, (byte) 0x04, (byte) 0x02, (byte) 0x30, (byte) 0x00, (byte) 0x30, - (byte) 0x2c, (byte) 0x06, (byte) 0x09, (byte) 0x60, (byte) 0x86, (byte) 0x48, - (byte) 0x01, (byte) 0x86, (byte) 0xf8, (byte) 0x42, (byte) 0x01, (byte) 0x0d, - (byte) 0x04, (byte) 0x1f, (byte) 0x16, (byte) 0x1d, (byte) 0x4f, (byte) 0x70, - (byte) 0x65, (byte) 0x6e, (byte) 0x53, (byte) 0x53, (byte) 0x4c, (byte) 0x20, - (byte) 0x47, (byte) 0x65, (byte) 0x6e, (byte) 0x65, (byte) 0x72, (byte) 0x61, - (byte) 0x74, (byte) 0x65, (byte) 0x64, (byte) 0x20, (byte) 0x43, (byte) 0x65, - (byte) 0x72, (byte) 0x74, (byte) 0x69, (byte) 0x66, (byte) 0x69, (byte) 0x63, - (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x30, (byte) 0x1d, (byte) 0x06, - (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16, - (byte) 0x04, (byte) 0x14, (byte) 0xef, (byte) 0xf0, (byte) 0x15, (byte) 0xd7, - (byte) 0xc9, (byte) 0x3e, (byte) 0x9a, (byte) 0x73, (byte) 0xfa, (byte) 0x38, - (byte) 0xc5, (byte) 0x81, (byte) 0x84, (byte) 0x74, (byte) 0xd3, (byte) 0x83, - (byte) 0x74, (byte) 0x26, (byte) 0xf1, (byte) 0x0b, (byte) 0x30, (byte) 0x1f, - (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04, - (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0x38, - (byte) 0x6a, (byte) 0x9b, (byte) 0xf8, (byte) 0x3c, (byte) 0x0d, (byte) 0x54, - (byte) 0x9f, (byte) 0xdf, (byte) 0xf8, (byte) 0x53, (byte) 0x32, (byte) 0xa8, - (byte) 0xf7, (byte) 0x09, (byte) 0x15, (byte) 0x08, (byte) 0x76, (byte) 0xab, - (byte) 0x8d, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, - (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, - (byte) 0x01, (byte) 0x0b, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x82, - (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0xa6, (byte) 0x6c, (byte) 0x18, - (byte) 0xa9, (byte) 0x67, (byte) 0x16, (byte) 0x6a, (byte) 0x9e, (byte) 0x23, - (byte) 0xb3, (byte) 0x2a, (byte) 0xb8, (byte) 0x16, (byte) 0x7b, (byte) 0xb4, - (byte) 0xc8, (byte) 0xbc, (byte) 0x51, (byte) 0xe0, (byte) 0x6f, (byte) 0x05, - (byte) 0x66, (byte) 0xa1, (byte) 0x6f, (byte) 0x96, (byte) 0xde, (byte) 0x5b, - (byte) 0x41, (byte) 0x60, (byte) 0xe5, (byte) 0x29, (byte) 0x99, (byte) 0x12, - (byte) 0xfc, (byte) 0xa9, (byte) 0x91, (byte) 0x23, (byte) 0xb7, (byte) 0x9e, - (byte) 0x00, (byte) 0x5f, (byte) 0x93, (byte) 0xd4, (byte) 0xf7, (byte) 0x27, - (byte) 0x29, (byte) 0x77, (byte) 0xfb, (byte) 0x53, (byte) 0x09, (byte) 0xdc, - (byte) 0xe9, (byte) 0xd0, (byte) 0x5c, (byte) 0x92, (byte) 0x6d, (byte) 0xb7, - (byte) 0xcf, (byte) 0x04, (byte) 0xab, (byte) 0xf1, (byte) 0x39, (byte) 0xb9, - (byte) 0x49, (byte) 0x23, (byte) 0x7c, (byte) 0x0f, (byte) 0x15, (byte) 0x27, - (byte) 0xcd, (byte) 0x65, (byte) 0x3c, (byte) 0x6b, (byte) 0x91, (byte) 0x42, - (byte) 0x5a, (byte) 0xfe, (byte) 0xbe, (byte) 0xb8, (byte) 0xa2, (byte) 0xfd, - (byte) 0x67, (byte) 0x43, (byte) 0x4b, (byte) 0xc9, (byte) 0x28, (byte) 0x65, - (byte) 0x1b, (byte) 0x82, (byte) 0x5b, (byte) 0x25, (byte) 0x20, (byte) 0x9b, - (byte) 0xea, (byte) 0x99, (byte) 0xbb, (byte) 0x66, (byte) 0xc1, (byte) 0x8e, - (byte) 0x46, (byte) 0x0b, (byte) 0x4e, (byte) 0x06, (byte) 0xdd, (byte) 0x50, - (byte) 0x51, (byte) 0x64, (byte) 0xe8, (byte) 0x83, (byte) 0x99, (byte) 0x8e, - (byte) 0x53, (byte) 0xe9, (byte) 0x48, (byte) 0x47, (byte) 0x0e, (byte) 0x08, - (byte) 0x5e, (byte) 0x0d, (byte) 0x4a, (byte) 0x54, (byte) 0x17, (byte) 0xc1, - (byte) 0xf8, (byte) 0xcf, (byte) 0xba, (byte) 0x5c, (byte) 0x38, (byte) 0x70, - (byte) 0x33, (byte) 0x31, (byte) 0x22, (byte) 0x03, (byte) 0x6f, (byte) 0x54, - (byte) 0x3c, (byte) 0x41, (byte) 0xf0, (byte) 0x89, (byte) 0x85, (byte) 0xbc, - (byte) 0x77, (byte) 0x3c, (byte) 0xe8, (byte) 0xec, (byte) 0xb4, (byte) 0x35, - (byte) 0x7a, (byte) 0xcc, (byte) 0x8c, (byte) 0x5f, (byte) 0xa1, (byte) 0xed, - (byte) 0xa6, (byte) 0x28, (byte) 0x14, (byte) 0xc7, (byte) 0x8a, (byte) 0xef, - (byte) 0x56, (byte) 0x26, (byte) 0x35, (byte) 0x46, (byte) 0xab, (byte) 0xb0, - (byte) 0x97, (byte) 0xd2, (byte) 0xbd, (byte) 0xa9, (byte) 0x6a, (byte) 0xe4, - (byte) 0x3e, (byte) 0x87, (byte) 0xfb, (byte) 0xe1, (byte) 0x09, (byte) 0x8d, - (byte) 0x33, (byte) 0x12, (byte) 0xcf, (byte) 0xf0, (byte) 0xc0, (byte) 0xb8, - (byte) 0x9b, (byte) 0x9f, (byte) 0xb1, (byte) 0xcb, (byte) 0xac, (byte) 0x76, - (byte) 0xa8, (byte) 0x05, (byte) 0x6b, (byte) 0xcc, (byte) 0x41, (byte) 0xd2, - (byte) 0x26, (byte) 0x73, (byte) 0xfa, (byte) 0x69, (byte) 0xd3, (byte) 0x1f, - (byte) 0xa9, (byte) 0x0c, (byte) 0x6a, (byte) 0xd6, (byte) 0xc9, (byte) 0x35, - (byte) 0xc5, (byte) 0xad, (byte) 0xa1, (byte) 0x98, (byte) 0xc9, (byte) 0x78, - (byte) 0xa0, (byte) 0xe8, (byte) 0x02, (byte) 0x69, (byte) 0x80, (byte) 0x44, - (byte) 0xd9, (byte) 0xe6, (byte) 0xe5, (byte) 0x26, (byte) 0x4f, (byte) 0xcf, - (byte) 0x38, (byte) 0xcb, (byte) 0x55, (byte) 0x8c, (byte) 0x7d, (byte) 0x3c, - (byte) 0xa8, (byte) 0x82, (byte) 0x69, (byte) 0xa3, (byte) 0xdf, (byte) 0x0a, - (byte) 0x79, (byte) 0x7b, (byte) 0xdd, (byte) 0x24, (byte) 0x6a, (byte) 0x21, - (byte) 0x7b, (byte) 0x20, (byte) 0x94, (byte) 0xcd, (byte) 0x15, (byte) 0x92, - (byte) 0xad, (byte) 0x4a, (byte) 0x72, (byte) 0x0b, (byte) 0x0e, (byte) 0xb2, - (byte) 0xc9 - }; - - private static final byte[] FAKE_KEY_3 = { - (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x02, (byte) 0x01, - (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, - (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, - (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82, - (byte) 0x02, (byte) 0x62, (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5e, - (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81, - (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6, (byte) 0x5b, - (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c, (byte) 0x66, - (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86, (byte) 0x8a, - (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3, (byte) 0x02, - (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08, (byte) 0xf3, - (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04, (byte) 0x6d, - (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f, (byte) 0x67, - (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c, (byte) 0xcb, - (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30, (byte) 0xe2, - (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5, (byte) 0x79, - (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b, (byte) 0xce, - (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb, (byte) 0x08, - (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff, (byte) 0x3b, - (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9, (byte) 0xc4, - (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29, (byte) 0x0d, - (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b, (byte) 0x23, - (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78, (byte) 0x08, - (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5, (byte) 0xf1, - (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19, (byte) 0xb4, - (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03, (byte) 0x16, - (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce, (byte) 0x9e, - (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03, (byte) 0x01, - (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x16, - (byte) 0x59, (byte) 0xc3, (byte) 0x24, (byte) 0x1d, (byte) 0x33, (byte) 0x98, - (byte) 0x9c, (byte) 0xc9, (byte) 0xc8, (byte) 0x2c, (byte) 0x88, (byte) 0xbf, - (byte) 0x0a, (byte) 0x01, (byte) 0xce, (byte) 0xfb, (byte) 0x34, (byte) 0x7a, - (byte) 0x58, (byte) 0x7a, (byte) 0xb0, (byte) 0xbf, (byte) 0xa6, (byte) 0xb2, - (byte) 0x60, (byte) 0xbe, (byte) 0x70, (byte) 0x21, (byte) 0xf5, (byte) 0xfc, - (byte) 0x85, (byte) 0x0d, (byte) 0x33, (byte) 0x58, (byte) 0xa1, (byte) 0xe5, - (byte) 0x09, (byte) 0x36, (byte) 0x84, (byte) 0xb2, (byte) 0x04, (byte) 0x0a, - (byte) 0x02, (byte) 0xd3, (byte) 0x88, (byte) 0x1f, (byte) 0x0c, (byte) 0x2b, - (byte) 0x1d, (byte) 0xe9, (byte) 0x3d, (byte) 0xe7, (byte) 0x79, (byte) 0xf9, - (byte) 0x32, (byte) 0x5c, (byte) 0x8a, (byte) 0x75, (byte) 0x49, (byte) 0x12, - (byte) 0xe4, (byte) 0x05, (byte) 0x26, (byte) 0xd4, (byte) 0x2e, (byte) 0x9e, - (byte) 0x1f, (byte) 0xcc, (byte) 0x54, (byte) 0xad, (byte) 0x33, (byte) 0x8d, - (byte) 0x99, (byte) 0x00, (byte) 0xdc, (byte) 0xf5, (byte) 0xb4, (byte) 0xa2, - (byte) 0x2f, (byte) 0xba, (byte) 0xe5, (byte) 0x62, (byte) 0x30, (byte) 0x6d, - (byte) 0xe6, (byte) 0x3d, (byte) 0xeb, (byte) 0x24, (byte) 0xc2, (byte) 0xdc, - (byte) 0x5f, (byte) 0xb7, (byte) 0x16, (byte) 0x35, (byte) 0xa3, (byte) 0x98, - (byte) 0x98, (byte) 0xa8, (byte) 0xef, (byte) 0xe8, (byte) 0xc4, (byte) 0x96, - (byte) 0x6d, (byte) 0x38, (byte) 0xab, (byte) 0x26, (byte) 0x6d, (byte) 0x30, - (byte) 0xc2, (byte) 0xa0, (byte) 0x44, (byte) 0xe4, (byte) 0xff, (byte) 0x7e, - (byte) 0xbe, (byte) 0x7c, (byte) 0x33, (byte) 0xa5, (byte) 0x10, (byte) 0xad, - (byte) 0xd7, (byte) 0x1e, (byte) 0x13, (byte) 0x20, (byte) 0xb3, (byte) 0x1f, - (byte) 0x41, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xf1, (byte) 0x89, - (byte) 0x07, (byte) 0x0f, (byte) 0xe8, (byte) 0xcf, (byte) 0xab, (byte) 0x13, - (byte) 0x2a, (byte) 0x8f, (byte) 0x88, (byte) 0x80, (byte) 0x11, (byte) 0x9a, - (byte) 0x79, (byte) 0xb6, (byte) 0x59, (byte) 0x3a, (byte) 0x50, (byte) 0x6e, - (byte) 0x57, (byte) 0x37, (byte) 0xab, (byte) 0x2a, (byte) 0xd2, (byte) 0xaa, - (byte) 0xd9, (byte) 0x72, (byte) 0x73, (byte) 0xff, (byte) 0x8b, (byte) 0x47, - (byte) 0x76, (byte) 0xdd, (byte) 0xdc, (byte) 0xf5, (byte) 0x97, (byte) 0x44, - (byte) 0x3a, (byte) 0x78, (byte) 0xbe, (byte) 0x17, (byte) 0xb4, (byte) 0x22, - (byte) 0x6f, (byte) 0xe5, (byte) 0x23, (byte) 0x70, (byte) 0x1d, (byte) 0x10, - (byte) 0x5d, (byte) 0xba, (byte) 0x16, (byte) 0x81, (byte) 0xf1, (byte) 0x45, - (byte) 0xce, (byte) 0x30, (byte) 0xb4, (byte) 0xab, (byte) 0x80, (byte) 0xe4, - (byte) 0x98, (byte) 0x31, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xda, - (byte) 0x82, (byte) 0x9d, (byte) 0x3f, (byte) 0xca, (byte) 0x2f, (byte) 0xe1, - (byte) 0xd4, (byte) 0x86, (byte) 0x77, (byte) 0x48, (byte) 0xa6, (byte) 0xab, - (byte) 0xab, (byte) 0x1c, (byte) 0x42, (byte) 0x5c, (byte) 0xd5, (byte) 0xc7, - (byte) 0x46, (byte) 0x59, (byte) 0x91, (byte) 0x3f, (byte) 0xfc, (byte) 0xcc, - (byte) 0xec, (byte) 0xc2, (byte) 0x40, (byte) 0x12, (byte) 0x2c, (byte) 0x8d, - (byte) 0x1f, (byte) 0xa2, (byte) 0x18, (byte) 0x88, (byte) 0xee, (byte) 0x82, - (byte) 0x4a, (byte) 0x5a, (byte) 0x5e, (byte) 0x88, (byte) 0x20, (byte) 0xe3, - (byte) 0x7b, (byte) 0xe0, (byte) 0xd8, (byte) 0x3a, (byte) 0x52, (byte) 0x9a, - (byte) 0x26, (byte) 0x6a, (byte) 0x04, (byte) 0xec, (byte) 0xe8, (byte) 0xb9, - (byte) 0x48, (byte) 0x40, (byte) 0xe1, (byte) 0xe1, (byte) 0x83, (byte) 0xa6, - (byte) 0x67, (byte) 0xa6, (byte) 0xfd, (byte) 0x02, (byte) 0x41, (byte) 0x00, - (byte) 0x89, (byte) 0x72, (byte) 0x3e, (byte) 0xb0, (byte) 0x90, (byte) 0xfd, - (byte) 0x4c, (byte) 0x0e, (byte) 0xd6, (byte) 0x13, (byte) 0x63, (byte) 0xcb, - (byte) 0xed, (byte) 0x38, (byte) 0x88, (byte) 0xb6, (byte) 0x79, (byte) 0xc4, - (byte) 0x33, (byte) 0x6c, (byte) 0xf6, (byte) 0xf8, (byte) 0xd8, (byte) 0xd0, - (byte) 0xbf, (byte) 0x9d, (byte) 0x35, (byte) 0xac, (byte) 0x69, (byte) 0xd2, - (byte) 0x2b, (byte) 0xc1, (byte) 0xf9, (byte) 0x24, (byte) 0x7b, (byte) 0xce, - (byte) 0xcd, (byte) 0xcb, (byte) 0xa7, (byte) 0xb2, (byte) 0x7a, (byte) 0x0a, - (byte) 0x27, (byte) 0x19, (byte) 0xc9, (byte) 0xaf, (byte) 0x0d, (byte) 0x21, - (byte) 0x89, (byte) 0x88, (byte) 0x7c, (byte) 0xad, (byte) 0x9e, (byte) 0x8d, - (byte) 0x47, (byte) 0x6d, (byte) 0x3f, (byte) 0xce, (byte) 0x7b, (byte) 0xa1, - (byte) 0x74, (byte) 0xf1, (byte) 0xa0, (byte) 0xa1, (byte) 0x02, (byte) 0x41, - (byte) 0x00, (byte) 0xd9, (byte) 0xa8, (byte) 0xf5, (byte) 0xfe, (byte) 0xce, - (byte) 0xe6, (byte) 0x77, (byte) 0x6b, (byte) 0xfe, (byte) 0x2d, (byte) 0xe0, - (byte) 0x1e, (byte) 0xb6, (byte) 0x2e, (byte) 0x12, (byte) 0x4e, (byte) 0x40, - (byte) 0xaf, (byte) 0x6a, (byte) 0x7b, (byte) 0x37, (byte) 0x49, (byte) 0x2a, - (byte) 0x96, (byte) 0x25, (byte) 0x83, (byte) 0x49, (byte) 0xd4, (byte) 0x0c, - (byte) 0xc6, (byte) 0x78, (byte) 0x25, (byte) 0x24, (byte) 0x90, (byte) 0x90, - (byte) 0x06, (byte) 0x15, (byte) 0x9e, (byte) 0xfe, (byte) 0xf9, (byte) 0xdf, - (byte) 0x5b, (byte) 0xf3, (byte) 0x7e, (byte) 0x38, (byte) 0x70, (byte) 0xeb, - (byte) 0x57, (byte) 0xd0, (byte) 0xd9, (byte) 0xa7, (byte) 0x0e, (byte) 0x14, - (byte) 0xf7, (byte) 0x95, (byte) 0x68, (byte) 0xd5, (byte) 0xc8, (byte) 0xab, - (byte) 0x9d, (byte) 0x3a, (byte) 0x2b, (byte) 0x51, (byte) 0xf9, (byte) 0x02, - (byte) 0x41, (byte) 0x00, (byte) 0x96, (byte) 0xdf, (byte) 0xe9, (byte) 0x67, - (byte) 0x6c, (byte) 0xdc, (byte) 0x90, (byte) 0x14, (byte) 0xb4, (byte) 0x1d, - (byte) 0x22, (byte) 0x33, (byte) 0x4a, (byte) 0x31, (byte) 0xc1, (byte) 0x9d, - (byte) 0x2e, (byte) 0xff, (byte) 0x9a, (byte) 0x2a, (byte) 0x95, (byte) 0x4b, - (byte) 0x27, (byte) 0x74, (byte) 0xcb, (byte) 0x21, (byte) 0xc3, (byte) 0xd2, - (byte) 0x0b, (byte) 0xb2, (byte) 0x46, (byte) 0x87, (byte) 0xf8, (byte) 0x28, - (byte) 0x01, (byte) 0x8b, (byte) 0xd8, (byte) 0xb9, (byte) 0x4b, (byte) 0xcd, - (byte) 0x9a, (byte) 0x96, (byte) 0x41, (byte) 0x0e, (byte) 0x36, (byte) 0x6d, - (byte) 0x40, (byte) 0x42, (byte) 0xbc, (byte) 0xd9, (byte) 0xd3, (byte) 0x7b, - (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1, - (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51 - }; - - private boolean hasWifi() { - return getContext().getPackageManager().hasSystemFeature( - PackageManager.FEATURE_WIFI); - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - if(!hasWifi()) { - return; - } - mWifiManager = (WifiManager) mContext - .getSystemService(Context.WIFI_SERVICE); - assertNotNull(mWifiManager); - SystemUtil.runShellCommand("svc wifi enable"); - Thread.sleep(ENABLE_DELAY); - if (hasWifi()) { - assertTrue(mWifiManager.isWifiEnabled()); - } - } - - public void testSettersAndGetters() throws Exception { - if (!hasWifi()) { - return; - } - - WifiEnterpriseConfig config = new WifiEnterpriseConfig(); - assertTrue(config.getEapMethod() == Eap.NONE); - config.setEapMethod(Eap.PEAP); - assertTrue(config.getEapMethod() == Eap.PEAP); - config.setEapMethod(Eap.PWD); - assertTrue(config.getEapMethod() == Eap.PWD); - config.setEapMethod(Eap.TLS); - assertTrue(config.getEapMethod() == Eap.TLS); - config.setEapMethod(Eap.TTLS); - assertTrue(config.getEapMethod() == Eap.TTLS); - assertTrue(config.getPhase2Method() == Phase2.NONE); - config.setPhase2Method(Phase2.PAP); - assertTrue(config.getPhase2Method() == Phase2.PAP); - config.setPhase2Method(Phase2.MSCHAP); - assertTrue(config.getPhase2Method() == Phase2.MSCHAP); - config.setPhase2Method(Phase2.MSCHAPV2); - assertTrue(config.getPhase2Method() == Phase2.MSCHAPV2); - config.setPhase2Method(Phase2.GTC); - assertTrue(config.getPhase2Method() == Phase2.GTC); - config.setIdentity(IDENTITY); - assertTrue(config.getIdentity().equals(IDENTITY)); - config.setAnonymousIdentity(ANON_IDENTITY); - assertTrue(config.getAnonymousIdentity().equals(ANON_IDENTITY)); - config.setPassword(PASSWORD); - assertTrue(config.getPassword().equals(PASSWORD)); - CertificateFactory factory = CertificateFactory.getInstance("X.509"); - X509Certificate cert1 = (X509Certificate) factory.generateCertificate( - new ByteArrayInputStream(FAKE_EC_1)); - X509Certificate cert2 = (X509Certificate) factory.generateCertificate( - new ByteArrayInputStream(FAKE_EC_2)); - config.setCaCertificate(cert1); - assertTrue(config.getCaCertificate().getSerialNumber().equals(cert1.getSerialNumber())); - config.setCaCertificates(new X509Certificate[]{cert1, cert2}); - X509Certificate[] certs = config.getCaCertificates(); - assertTrue(cert1.getSerialNumber().equals(certs[0].getSerialNumber())); - assertTrue(cert2.getSerialNumber().equals(certs[1].getSerialNumber())); - - X509Certificate clientCert = (X509Certificate) factory.generateCertificate( - new ByteArrayInputStream(FAKE_EC_3)); - KeyFactory kf = KeyFactory.getInstance("RSA"); - PrivateKey clientKey = kf.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_3)); - - config.setClientKeyEntry(clientKey, clientCert); - X509Certificate testClientCert = config.getClientCertificate(); - X509Certificate[] testClientCertChain = config.getClientCertificateChain(); - assertTrue(clientCert.getSerialNumber().equals(testClientCert.getSerialNumber())); - assertTrue(testClientCertChain.length == 1); - assertTrue(testClientCertChain[0] == testClientCert); - - config.setClientKeyEntry(null, null); - assertTrue(config.getClientCertificate() == null); - assertTrue(config.getClientCertificateChain() == null); - - config.setClientKeyEntryWithCertificateChain(clientKey, - new X509Certificate[]{clientCert, cert1}); - testClientCert = config.getClientCertificate(); - testClientCertChain = config.getClientCertificateChain(); - assertTrue(clientCert.getSerialNumber().equals(testClientCert.getSerialNumber())); - assertTrue(testClientCertChain.length == 2); - assertTrue(testClientCertChain[0] == testClientCert); - assertTrue(testClientCertChain[1] == cert1); - - config.setSubjectMatch(SUBJECT_MATCH); - assertTrue(config.getSubjectMatch().equals(SUBJECT_MATCH)); - // Hotspot 2.0 related attributes - config.setPlmn(PLMN); - assertTrue(config.getPlmn().equals(PLMN)); - config.setRealm(REALM); - assertTrue(config.getRealm().equals(REALM)); - config.setAltSubjectMatch(ALT_SUBJECT_MATCH); - assertTrue(config.getAltSubjectMatch().equals(ALT_SUBJECT_MATCH)); - config.setDomainSuffixMatch(DOM_SUBJECT_MATCH); - assertTrue(config.getDomainSuffixMatch().equals(DOM_SUBJECT_MATCH)); - } - - public void testEnterpriseConfigDoesNotPrintPassword() { - if(!hasWifi()) { - return; - } - WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); - final String identity = "IdentityIsOkayToBeDisplayedHere"; - final String password = "PasswordIsNotOkayToBeDisplayedHere"; - enterpriseConfig.setIdentity(identity); - enterpriseConfig.setPassword(password); - final String stringRepresentation = enterpriseConfig.toString(); - assertTrue(stringRepresentation.contains(identity)); - assertFalse(stringRepresentation.contains(password)); - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiFeature.java b/tests/cts/net/src/android/net/wifi/cts/WifiFeature.java deleted file mode 100644 index 63fa1dd94c..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/WifiFeature.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2012 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.wifi.cts; - -import android.content.Context; -import android.content.pm.PackageManager; - -public class WifiFeature { - static boolean isWifiSupported(Context context) { - PackageManager packageManager = context.getPackageManager(); - return packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI); - } - - static boolean isP2pSupported(Context context) { - PackageManager packageManager = context.getPackageManager(); - return packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT); - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java deleted file mode 100644 index 9d9b2a3902..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2008 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.wifi.cts; - - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.wifi.SupplicantState; -import android.net.wifi.WifiInfo; -import android.net.wifi.WifiManager; -import android.net.wifi.WifiManager.WifiLock; -import android.net.wifi.WifiSsid; -import android.platform.test.annotations.AppModeFull; -import android.test.AndroidTestCase; - -import com.android.compatibility.common.util.PollingCheck; -import com.android.compatibility.common.util.SystemUtil; - -import java.util.concurrent.Callable; - -@AppModeFull(reason = "Cannot get WifiManager in instant app mode") -public class WifiInfoTest extends AndroidTestCase { - private static class MySync { - int expectedState = STATE_NULL; - } - - private WifiManager mWifiManager; - private WifiLock mWifiLock; - private static MySync mMySync; - - private static final int STATE_NULL = 0; - private static final int STATE_WIFI_CHANGING = 1; - private static final int STATE_WIFI_CHANGED = 2; - - private static final String TAG = "WifiInfoTest"; - private static final int TIMEOUT_MSEC = 6000; - private static final int WAIT_MSEC = 60; - private static final int DURATION = 10000; - private IntentFilter mIntentFilter; - private final BroadcastReceiver mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - final String action = intent.getAction(); - if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { - synchronized (mMySync) { - mMySync.expectedState = STATE_WIFI_CHANGED; - mMySync.notify(); - } - } - } - }; - - @Override - protected void setUp() throws Exception { - super.setUp(); - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - mMySync = new MySync(); - mIntentFilter = new IntentFilter(); - mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); - - mContext.registerReceiver(mReceiver, mIntentFilter); - mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); - assertNotNull(mWifiManager); - mWifiLock = mWifiManager.createWifiLock(TAG); - mWifiLock.acquire(); - if (!mWifiManager.isWifiEnabled()) - setWifiEnabled(true); - Thread.sleep(DURATION); - assertTrue(mWifiManager.isWifiEnabled()); - mMySync.expectedState = STATE_NULL; - } - - @Override - protected void tearDown() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - super.tearDown(); - return; - } - mWifiLock.release(); - mContext.unregisterReceiver(mReceiver); - if (!mWifiManager.isWifiEnabled()) - setWifiEnabled(true); - Thread.sleep(DURATION); - super.tearDown(); - } - - private void setWifiEnabled(boolean enable) throws Exception { - synchronized (mMySync) { - mMySync.expectedState = STATE_WIFI_CHANGING; - if (enable) { - SystemUtil.runShellCommand("svc wifi enable"); - } else { - SystemUtil.runShellCommand("svc wifi disable"); - } - long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; - while (System.currentTimeMillis() < timeout - && mMySync.expectedState == STATE_WIFI_CHANGING) - mMySync.wait(WAIT_MSEC); - } - } - - public void testWifiInfoProperties() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - // this test case should in Wifi environment - WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); - - assertNotNull(wifiInfo); - assertNotNull(wifiInfo.toString()); - SupplicantState.isValidState(wifiInfo.getSupplicantState()); - WifiInfo.getDetailedStateOf(SupplicantState.DISCONNECTED); - String ssid = wifiInfo.getSSID(); - if (!ssid.startsWith("0x") && !ssid.equals(WifiSsid.NONE)) { - // Non-hex string should be quoted - assertTrue(ssid.charAt(0) == '"'); - assertTrue(ssid.charAt(ssid.length() - 1) == '"'); - } - - wifiInfo.getBSSID(); - wifiInfo.getFrequency(); - wifiInfo.getIpAddress(); - wifiInfo.getLinkSpeed(); - wifiInfo.getPasspointFqdn(); - wifiInfo.getPasspointProviderFriendlyName(); - wifiInfo.getTxLinkSpeedMbps(); - wifiInfo.getRxLinkSpeedMbps(); - wifiInfo.getRssi(); - wifiInfo.getHiddenSSID(); - wifiInfo.getMacAddress(); - setWifiEnabled(false); - - PollingCheck.check("getNetworkId not -1", 20000, new Callable() { - @Override - public Boolean call() throws Exception { - WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); - return wifiInfo.getNetworkId() == -1; - } - }); - - PollingCheck.check("getWifiState not disabled", 20000, new Callable() { - @Override - public Boolean call() throws Exception { - return mWifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLED; - } - }); - } - -} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiLockTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiLockTest.java deleted file mode 100644 index 6ac92d409c..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/WifiLockTest.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2008 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.wifi.cts; - -import android.content.Context; -import android.net.wifi.WifiManager; -import android.net.wifi.WifiManager.WifiLock; -import android.platform.test.annotations.AppModeFull; -import android.test.AndroidTestCase; - -@AppModeFull(reason = "Cannot get WifiManager in instant app mode") -public class WifiLockTest extends AndroidTestCase { - - private static final String WIFI_TAG = "WifiLockTest"; - - /** - * Verify acquire and release of High Performance wifi locks - */ - public void testHiPerfWifiLock() { - testWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF); - } - - /** - * Verify acquire and release of Low latency wifi locks - */ - public void testLowLatencyWifiLock() { - testWifiLock(WifiManager.WIFI_MODE_FULL_LOW_LATENCY); - } - - private void testWifiLock(int lockType) { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - WifiManager wm = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); - WifiLock wl = wm.createWifiLock(lockType, WIFI_TAG); - - wl.setReferenceCounted(true); - assertFalse(wl.isHeld()); - wl.acquire(); - assertTrue(wl.isHeld()); - wl.release(); - assertFalse(wl.isHeld()); - wl.acquire(); - wl.acquire(); - assertTrue(wl.isHeld()); - wl.release(); - assertTrue(wl.isHeld()); - wl.release(); - assertFalse(wl.isHeld()); - assertNotNull(wl.toString()); - try { - wl.release(); - fail("should throw out exception because release is called" - +" a greater number of times than acquire"); - } catch (RuntimeException e) { - // expected - } - - wl = wm.createWifiLock(lockType, WIFI_TAG); - wl.setReferenceCounted(false); - assertFalse(wl.isHeld()); - wl.acquire(); - assertTrue(wl.isHeld()); - wl.release(); - assertFalse(wl.isHeld()); - wl.acquire(); - wl.acquire(); - assertTrue(wl.isHeld()); - wl.release(); - assertFalse(wl.isHeld()); - assertNotNull(wl.toString()); - // releasing again after release: but ignored for non-referenced locks - wl.release(); - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java deleted file mode 100644 index 5b8a8d5cc4..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ /dev/null @@ -1,1056 +0,0 @@ -/* - * Copyright (C) 2009 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.wifi.cts; - - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.net.wifi.ScanResult; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiManager; -import android.net.wifi.WifiManager.TxPacketCountListener; -import android.net.wifi.WifiManager.WifiLock; -import android.net.wifi.hotspot2.PasspointConfiguration; -import android.net.wifi.hotspot2.pps.Credential; -import android.net.wifi.hotspot2.pps.HomeSp; -import android.os.Process; -import android.os.SystemClock; -import android.os.UserHandle; -import android.platform.test.annotations.AppModeFull; -import android.provider.Settings; -import android.support.test.uiautomator.UiDevice; -import android.test.AndroidTestCase; -import android.text.TextUtils; -import android.util.ArraySet; -import android.util.Log; - -import androidx.test.InstrumentationRegistry; - -import com.android.compatibility.common.util.SystemUtil; - -import java.lang.StringBuilder; -import java.net.HttpURLConnection; -import java.net.URL; -import java.security.MessageDigest; -import java.security.cert.X509Certificate; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; - -@AppModeFull(reason = "Cannot get WifiManager in instant app mode") -public class WifiManagerTest extends AndroidTestCase { - private static class MySync { - int expectedState = STATE_NULL; - } - - private WifiManager mWifiManager; - private WifiLock mWifiLock; - private static MySync mMySync; - private List mScanResults = null; - private NetworkInfo mNetworkInfo; - private Object mLOHSLock = new Object(); - private UiDevice mUiDevice; - - // Please refer to WifiManager - private static final int MIN_RSSI = -100; - private static final int MAX_RSSI = -55; - - private static final int STATE_NULL = 0; - private static final int STATE_WIFI_CHANGING = 1; - private static final int STATE_WIFI_ENABLED = 2; - private static final int STATE_WIFI_DISABLED = 3; - private static final int STATE_SCANNING = 4; - private static final int STATE_SCAN_DONE = 5; - - private static final String TAG = "WifiManagerTest"; - private static final String SSID1 = "\"WifiManagerTest\""; - // A full single scan duration is about 6-7 seconds if country code is set - // to US. If country code is set to world mode (00), we would expect a scan - // duration of roughly 8 seconds. So we set scan timeout as 9 seconds here. - private static final int SCAN_TIMEOUT_MSEC = 9000; - private static final int TIMEOUT_MSEC = 6000; - private static final int WAIT_MSEC = 60; - private static final int DURATION = 10000; - private static final int DURATION_SCREEN_TOGGLE = 2000; - private static final int WIFI_SCAN_TEST_INTERVAL_MILLIS = 60 * 1000; - private static final int WIFI_SCAN_TEST_CACHE_DELAY_MILLIS = 3 * 60 * 1000; - private static final int WIFI_SCAN_TEST_ITERATIONS = 5; - - private static final int ENFORCED_NUM_NETWORK_SUGGESTIONS_PER_APP = 50; - - private static final String TEST_PAC_URL = "http://www.example.com/proxy.pac"; - private static final String MANAGED_PROVISIONING_PACKAGE_NAME - = "com.android.managedprovisioning"; - - private IntentFilter mIntentFilter; - private final BroadcastReceiver mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - final String action = intent.getAction(); - if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { - - synchronized (mMySync) { - if (intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)) { - mScanResults = mWifiManager.getScanResults(); - } else { - mScanResults = null; - } - mMySync.expectedState = STATE_SCAN_DONE; - mMySync.notifyAll(); - } - } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { - int newState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, - WifiManager.WIFI_STATE_UNKNOWN); - synchronized (mMySync) { - if (newState == WifiManager.WIFI_STATE_ENABLED) { - Log.d(TAG, "*** New WiFi state is ENABLED ***"); - mMySync.expectedState = STATE_WIFI_ENABLED; - mMySync.notifyAll(); - } else if (newState == WifiManager.WIFI_STATE_DISABLED) { - Log.d(TAG, "*** New WiFi state is DISABLED ***"); - mMySync.expectedState = STATE_WIFI_DISABLED; - mMySync.notifyAll(); - } - } - } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { - synchronized (mMySync) { - mNetworkInfo = - (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); - if (mNetworkInfo.getState() == NetworkInfo.State.CONNECTED) - mMySync.notifyAll(); - } - } - } - }; - - @Override - protected void setUp() throws Exception { - super.setUp(); - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - mMySync = new MySync(); - mIntentFilter = new IntentFilter(); - mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); - mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); - mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.ACTION_PICK_WIFI_NETWORK); - - mContext.registerReceiver(mReceiver, mIntentFilter); - mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); - assertNotNull(mWifiManager); - mWifiLock = mWifiManager.createWifiLock(TAG); - mWifiLock.acquire(); - if (!mWifiManager.isWifiEnabled()) - setWifiEnabled(true); - mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); - turnScreenOnNoDelay(); - Thread.sleep(DURATION); - assertTrue(mWifiManager.isWifiEnabled()); - synchronized (mMySync) { - mMySync.expectedState = STATE_NULL; - } - } - - @Override - protected void tearDown() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - super.tearDown(); - return; - } - if (!mWifiManager.isWifiEnabled()) - setWifiEnabled(true); - mWifiLock.release(); - mContext.unregisterReceiver(mReceiver); - Thread.sleep(DURATION); - super.tearDown(); - } - - private void setWifiEnabled(boolean enable) throws Exception { - synchronized (mMySync) { - if (mWifiManager.isWifiEnabled() != enable) { - // the new state is different, we expect it to change - mMySync.expectedState = STATE_WIFI_CHANGING; - } else { - mMySync.expectedState = (enable ? STATE_WIFI_ENABLED : STATE_WIFI_DISABLED); - } - // now trigger the change using shell commands. - SystemUtil.runShellCommand("svc wifi " + (enable ? "enable" : "disable")); - waitForExpectedWifiState(enable); - } - } - - private void waitForExpectedWifiState(boolean enabled) throws InterruptedException { - synchronized (mMySync) { - long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; - int expected = (enabled ? STATE_WIFI_ENABLED : STATE_WIFI_DISABLED); - while (System.currentTimeMillis() < timeout - && mMySync.expectedState != expected) { - mMySync.wait(WAIT_MSEC); - } - } - } - - // Get the current scan status from sticky broadcast. - private boolean isScanCurrentlyAvailable() { - boolean isAvailable = false; - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(WifiManager.WIFI_SCAN_AVAILABLE); - Intent intent = mContext.registerReceiver(null, intentFilter); - assertNotNull(intent); - if (intent.getAction().equals(WifiManager.WIFI_SCAN_AVAILABLE)) { - int state = intent.getIntExtra( - WifiManager.EXTRA_SCAN_AVAILABLE, WifiManager.WIFI_STATE_UNKNOWN); - if (state == WifiManager.WIFI_STATE_ENABLED) { - isAvailable = true; - } else if (state == WifiManager.WIFI_STATE_DISABLED) { - isAvailable = false; - } - } - return isAvailable; - } - - private void startScan() throws Exception { - synchronized (mMySync) { - mMySync.expectedState = STATE_SCANNING; - mScanResults = null; - assertTrue(mWifiManager.startScan()); - long timeout = System.currentTimeMillis() + SCAN_TIMEOUT_MSEC; - while (System.currentTimeMillis() < timeout && mMySync.expectedState == STATE_SCANNING) - mMySync.wait(WAIT_MSEC); - } - } - - private void connectWifi() throws Exception { - synchronized (mMySync) { - if (mNetworkInfo.getState() == NetworkInfo.State.CONNECTED) return; - long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; - while (System.currentTimeMillis() < timeout - && mNetworkInfo.getState() != NetworkInfo.State.CONNECTED) - mMySync.wait(WAIT_MSEC); - assertTrue(mNetworkInfo.getState() == NetworkInfo.State.CONNECTED); - } - } - - private boolean existSSID(String ssid) { - for (final WifiConfiguration w : mWifiManager.getConfiguredNetworks()) { - if (w.SSID.equals(ssid)) - return true; - } - return false; - } - - private int findConfiguredNetworks(String SSID, List networks) { - for (final WifiConfiguration w : networks) { - if (w.SSID.equals(SSID)) - return networks.indexOf(w); - } - return -1; - } - - /** - * Test creation of WifiManager Lock. - */ - public void testWifiManagerLock() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - final String TAG = "Test"; - assertNotNull(mWifiManager.createWifiLock(TAG)); - assertNotNull(mWifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, TAG)); - } - - /** - * Test wifi scanning when location scan is turned off. - */ - public void testWifiManagerScanWhenWifiOffLocationTurnedOn() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - if (!hasLocationFeature()) { - Log.d(TAG, "Skipping test as location is not supported"); - return; - } - if (!isLocationEnabled()) { - fail("Please enable location for this test - since Marshmallow WiFi scan results are" - + " empty when location is disabled!"); - } - setWifiEnabled(false); - Thread.sleep(DURATION); - startScan(); - if (mWifiManager.isScanAlwaysAvailable() && isScanCurrentlyAvailable()) { - // Make sure at least one AP is found. - assertNotNull("mScanResult should not be null!", mScanResults); - assertFalse("empty scan results!", mScanResults.isEmpty()); - } else { - // Make sure no scan results are available. - assertNull("mScanResult should be null!", mScanResults); - } - final String TAG = "Test"; - assertNotNull(mWifiManager.createWifiLock(TAG)); - assertNotNull(mWifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, TAG)); - } - - /** - * test point of wifiManager properties: - * 1.enable properties - * 2.DhcpInfo properties - * 3.wifi state - * 4.ConnectionInfo - */ - public void testWifiManagerProperties() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - setWifiEnabled(true); - assertTrue(mWifiManager.isWifiEnabled()); - assertNotNull(mWifiManager.getDhcpInfo()); - assertEquals(WifiManager.WIFI_STATE_ENABLED, mWifiManager.getWifiState()); - mWifiManager.getConnectionInfo(); - setWifiEnabled(false); - assertFalse(mWifiManager.isWifiEnabled()); - } - - /** - * Test WiFi scan timestamp - fails when WiFi scan timestamps are inconsistent with - * {@link SystemClock#elapsedRealtime()} on device.

    - * To run this test in cts-tradefed: - * run cts --class android.net.wifi.cts.WifiManagerTest --method testWifiScanTimestamp - */ - public void testWifiScanTimestamp() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - Log.d(TAG, "Skipping test as WiFi is not supported"); - return; - } - if (!hasLocationFeature()) { - Log.d(TAG, "Skipping test as location is not supported"); - return; - } - if (!isLocationEnabled()) { - fail("Please enable location for this test - since Marshmallow WiFi scan results are" - + " empty when location is disabled!"); - } - if (!mWifiManager.isWifiEnabled()) { - setWifiEnabled(true); - } - // Scan multiple times to make sure scan timestamps increase with device timestamp. - for (int i = 0; i < WIFI_SCAN_TEST_ITERATIONS; ++i) { - startScan(); - // Make sure at least one AP is found. - assertTrue("mScanResult should not be null. This may be due to a scan timeout", - mScanResults != null); - assertFalse("empty scan results!", mScanResults.isEmpty()); - long nowMillis = SystemClock.elapsedRealtime(); - // Keep track of how many APs are fresh in one scan. - int numFreshAps = 0; - for (ScanResult result : mScanResults) { - long scanTimeMillis = TimeUnit.MICROSECONDS.toMillis(result.timestamp); - if (Math.abs(nowMillis - scanTimeMillis) < WIFI_SCAN_TEST_CACHE_DELAY_MILLIS) { - numFreshAps++; - } - } - // At least half of the APs in the scan should be fresh. - int numTotalAps = mScanResults.size(); - String msg = "Stale AP count: " + (numTotalAps - numFreshAps) + ", fresh AP count: " - + numFreshAps; - assertTrue(msg, numFreshAps * 2 >= mScanResults.size()); - if (i < WIFI_SCAN_TEST_ITERATIONS - 1) { - // Wait before running next iteration. - Thread.sleep(WIFI_SCAN_TEST_INTERVAL_MILLIS); - } - } - } - - // Return true if location is enabled. - private boolean isLocationEnabled() { - return Settings.Secure.getInt(getContext().getContentResolver(), - Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF) != - Settings.Secure.LOCATION_MODE_OFF; - } - - // Returns true if the device has location feature. - private boolean hasLocationFeature() { - return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION); - } - - private boolean hasAutomotiveFeature() { - return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); - } - - public void testSignal() { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - final int numLevels = 9; - int expectLevel = 0; - assertEquals(expectLevel, WifiManager.calculateSignalLevel(MIN_RSSI, numLevels)); - assertEquals(numLevels - 1, WifiManager.calculateSignalLevel(MAX_RSSI, numLevels)); - expectLevel = 4; - assertEquals(expectLevel, WifiManager.calculateSignalLevel((MIN_RSSI + MAX_RSSI) / 2, - numLevels)); - int rssiA = 4; - int rssiB = 5; - assertTrue(WifiManager.compareSignalLevel(rssiA, rssiB) < 0); - rssiB = 4; - assertTrue(WifiManager.compareSignalLevel(rssiA, rssiB) == 0); - rssiA = 5; - rssiB = 4; - assertTrue(WifiManager.compareSignalLevel(rssiA, rssiB) > 0); - } - - private int getTxPacketCount() throws Exception { - final AtomicInteger ret = new AtomicInteger(-1); - - mWifiManager.getTxPacketCount(new TxPacketCountListener() { - @Override - public void onSuccess(int count) { - ret.set(count); - } - @Override - public void onFailure(int reason) { - ret.set(0); - } - }); - - long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; - while (ret.get() < 0 && System.currentTimeMillis() < timeout) - Thread.sleep(WAIT_MSEC); - assertTrue(ret.get() >= 0); - return ret.get(); - } - - /** - * The new WiFi watchdog requires kernel/driver to export some packet loss - * counters. This CTS tests whether those counters are correctly exported. - * To pass this CTS test, a connected WiFi link is required. - */ - public void testWifiWatchdog() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - // Make sure WiFi is enabled - if (!mWifiManager.isWifiEnabled()) { - setWifiEnabled(true); - Thread.sleep(DURATION); - } - assertTrue(mWifiManager.isWifiEnabled()); - - // give the test a chance to autoconnect - Thread.sleep(DURATION); - if (mNetworkInfo.getState() != NetworkInfo.State.CONNECTED) { - // this test requires a connectable network be configured - fail("This test requires a wifi network connection."); - } - - // This will generate a distinct stack trace if the initial connection fails. - connectWifi(); - - int i = 0; - for (; i < 15; i++) { - // Wait for a WiFi connection - connectWifi(); - - // Read TX packet counter - int txcount1 = getTxPacketCount(); - - // Do some network operations - HttpURLConnection connection = null; - try { - URL url = new URL("http://www.google.com/"); - connection = (HttpURLConnection) url.openConnection(); - connection.setInstanceFollowRedirects(false); - connection.setConnectTimeout(TIMEOUT_MSEC); - connection.setReadTimeout(TIMEOUT_MSEC); - connection.setUseCaches(false); - connection.getInputStream(); - } catch (Exception e) { - // ignore - } finally { - if (connection != null) connection.disconnect(); - } - - // Read TX packet counter again and make sure it increases - int txcount2 = getTxPacketCount(); - - if (txcount2 > txcount1) { - break; - } else { - Thread.sleep(DURATION); - } - } - assertTrue(i < 15); - } - - public class TestLocalOnlyHotspotCallback extends WifiManager.LocalOnlyHotspotCallback { - Object hotspotLock; - WifiManager.LocalOnlyHotspotReservation reservation = null; - boolean onStartedCalled = false; - boolean onStoppedCalled = false; - boolean onFailedCalled = false; - int failureReason = -1; - - TestLocalOnlyHotspotCallback(Object lock) { - hotspotLock = lock; - } - - @Override - public void onStarted(WifiManager.LocalOnlyHotspotReservation r) { - synchronized (hotspotLock) { - reservation = r; - onStartedCalled = true; - hotspotLock.notify(); - } - } - - @Override - public void onStopped() { - synchronized (hotspotLock) { - onStoppedCalled = true; - hotspotLock.notify(); - } - } - - @Override - public void onFailed(int reason) { - synchronized (hotspotLock) { - onFailedCalled = true; - failureReason = reason; - hotspotLock.notify(); - } - } - } - - private TestLocalOnlyHotspotCallback startLocalOnlyHotspot() { - // Location mode must be enabled for this test - if (!isLocationEnabled()) { - fail("Please enable location for this test"); - } - - TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(mLOHSLock); - synchronized (mLOHSLock) { - try { - mWifiManager.startLocalOnlyHotspot(callback, null); - // now wait for callback - mLOHSLock.wait(DURATION); - } catch (InterruptedException e) { - } - // check if we got the callback - assertTrue(callback.onStartedCalled); - assertNotNull(callback.reservation.getWifiConfiguration()); - if (!hasAutomotiveFeature()) { - assertEquals( - WifiConfiguration.AP_BAND_2GHZ, - callback.reservation.getWifiConfiguration().apBand); - } - assertFalse(callback.onFailedCalled); - assertFalse(callback.onStoppedCalled); - } - return callback; - } - - private void stopLocalOnlyHotspot(TestLocalOnlyHotspotCallback callback, boolean wifiEnabled) { - synchronized (mMySync) { - // we are expecting a new state - mMySync.expectedState = STATE_WIFI_CHANGING; - - // now shut down LocalOnlyHotspot - callback.reservation.close(); - - try { - waitForExpectedWifiState(wifiEnabled); - } catch (InterruptedException e) {} - } - } - - /** - * Verify that calls to startLocalOnlyHotspot succeed with proper permissions. - * - * Note: Location mode must be enabled for this test. - */ - public void testStartLocalOnlyHotspotSuccess() { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - // check that softap mode is supported by the device - if (!mWifiManager.isPortableHotspotSupported()) { - return; - } - - boolean wifiEnabled = mWifiManager.isWifiEnabled(); - - TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot(); - - // add sleep to avoid calling stopLocalOnlyHotspot before TetherController initialization. - // TODO: remove this sleep as soon as b/124330089 is fixed. - try { - Log.d(TAG, "Sleep for 2 seconds"); - Thread.sleep(2000); - } catch (InterruptedException e) { - Log.d(TAG, "Thread InterruptedException!"); - } - - stopLocalOnlyHotspot(callback, wifiEnabled); - - // wifi should either stay on, or come back on - assertEquals(wifiEnabled, mWifiManager.isWifiEnabled()); - } - - /** - * Verify calls to deprecated API's all fail for non-settings apps targeting >= Q SDK. - */ - public void testDeprecatedApis() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - setWifiEnabled(true); - connectWifi(); // ensures that there is at-least 1 saved network on the device. - - WifiConfiguration wifiConfiguration = new WifiConfiguration(); - wifiConfiguration.SSID = SSID1; - wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); - - assertEquals(WifiConfiguration.INVALID_NETWORK_ID, - mWifiManager.addNetwork(wifiConfiguration)); - assertEquals(WifiConfiguration.INVALID_NETWORK_ID, - mWifiManager.updateNetwork(wifiConfiguration)); - assertFalse(mWifiManager.enableNetwork(0, true)); - assertFalse(mWifiManager.disableNetwork(0)); - assertFalse(mWifiManager.removeNetwork(0)); - assertFalse(mWifiManager.disconnect()); - assertFalse(mWifiManager.reconnect()); - assertFalse(mWifiManager.reassociate()); - assertTrue(mWifiManager.getConfiguredNetworks().isEmpty()); - - boolean wifiEnabled = mWifiManager.isWifiEnabled(); - // now we should fail to toggle wifi state. - assertFalse(mWifiManager.setWifiEnabled(!wifiEnabled)); - Thread.sleep(DURATION); - assertEquals(wifiEnabled, mWifiManager.isWifiEnabled()); - } - - /** - * Verify that applications can only have one registered LocalOnlyHotspot request at a time. - * - * Note: Location mode must be enabled for this test. - */ - public void testStartLocalOnlyHotspotSingleRequestByApps() { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - // check that softap mode is supported by the device - if (!mWifiManager.isPortableHotspotSupported()) { - return; - } - - boolean caughtException = false; - - boolean wifiEnabled = mWifiManager.isWifiEnabled(); - - TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot(); - - // now make a second request - this should fail. - TestLocalOnlyHotspotCallback callback2 = new TestLocalOnlyHotspotCallback(mLOHSLock); - try { - mWifiManager.startLocalOnlyHotspot(callback2, null); - } catch (IllegalStateException e) { - Log.d(TAG, "Caught the IllegalStateException we expected: called startLOHS twice"); - caughtException = true; - } - if (!caughtException) { - // second start did not fail, should clean up the hotspot. - stopLocalOnlyHotspot(callback2, wifiEnabled); - } - assertTrue(caughtException); - - // add sleep to avoid calling stopLocalOnlyHotspot before TetherController initialization. - // TODO: remove this sleep as soon as b/124330089 is fixed. - try { - Log.d(TAG, "Sleep for 2 seconds"); - Thread.sleep(2000); - } catch (InterruptedException e) { - Log.d(TAG, "Thread InterruptedException!"); - } - - stopLocalOnlyHotspot(callback, wifiEnabled); - } - - /** - * Verify that the {@link android.Manifest.permission#NETWORK_STACK} permission is never held by - * any package. - *

    - * No apps should ever attempt to acquire this permission, since it would give those - * apps extremely broad access to connectivity functionality. - */ - public void testNetworkStackPermission() { - final PackageManager pm = getContext().getPackageManager(); - - final List holding = pm.getPackagesHoldingPermissions(new String[] { - android.Manifest.permission.NETWORK_STACK - }, PackageManager.MATCH_UNINSTALLED_PACKAGES); - for (PackageInfo pi : holding) { - fail("The NETWORK_STACK permission must not be held by " + pi.packageName - + " and must be revoked for security reasons"); - } - } - - /** - * Verify that the {@link android.Manifest.permission#NETWORK_SETTINGS} permission is - * never held by any package. - *

    - * Only Settings, SysUi, NetworkStack and shell apps should ever attempt to acquire - * this permission, since it would give those apps extremely broad access to connectivity - * functionality. The permission is intended to be granted to only those apps with direct user - * access and no others. - */ - public void testNetworkSettingsPermission() { - final PackageManager pm = getContext().getPackageManager(); - - final ArraySet allowedPackages = new ArraySet(); - final ArraySet allowedUIDs = new ArraySet(); - // explicitly add allowed UIDs - allowedUIDs.add(Process.SYSTEM_UID); - allowedUIDs.add(Process.SHELL_UID); - allowedUIDs.add(Process.PHONE_UID); - allowedUIDs.add(Process.NETWORK_STACK_UID); - allowedUIDs.add(Process.NFC_UID); - - // only quick settings is allowed to bind to the BIND_QUICK_SETTINGS_TILE permission, using - // this fact to determined allowed package name for sysui. This is a signature permission, - // so allow any package with this permission. - final List sysuiPackages = pm.getPackagesHoldingPermissions(new String[] { - android.Manifest.permission.BIND_QUICK_SETTINGS_TILE - }, PackageManager.MATCH_UNINSTALLED_PACKAGES); - for (PackageInfo info : sysuiPackages) { - allowedPackages.add(info.packageName); - } - - // the captive portal flow also currently holds the NETWORK_SETTINGS permission - final Intent intent = new Intent(ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN); - final ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DISABLED_COMPONENTS); - if (ri != null) { - allowedPackages.add(ri.activityInfo.packageName); - } - - final List holding = pm.getPackagesHoldingPermissions(new String[] { - android.Manifest.permission.NETWORK_SETTINGS - }, PackageManager.MATCH_UNINSTALLED_PACKAGES); - StringBuilder stringBuilder = new StringBuilder(); - for (PackageInfo pi : holding) { - String packageName = pi.packageName; - - // this is an explicitly allowed package - if (allowedPackages.contains(packageName)) continue; - - // now check if the packages are from allowed UIDs - int uid = -1; - try { - uid = pm.getPackageUidAsUser(packageName, UserHandle.USER_SYSTEM); - } catch (PackageManager.NameNotFoundException e) { - continue; - } - if (!allowedUIDs.contains(uid)) { - stringBuilder.append("The NETWORK_SETTINGS permission must not be held by " - + packageName + ":" + uid + " and must be revoked for security reasons\n"); - } - } - if (stringBuilder.length() > 0) { - fail(stringBuilder.toString()); - } - } - - /** - * Verify that the {@link android.Manifest.permission#NETWORK_SETUP_WIZARD} permission is - * only held by the device setup wizard application. - *

    - * Only the SetupWizard app should ever attempt to acquire this - * permission, since it would give those apps extremely broad access to connectivity - * functionality. The permission is intended to be granted to only the device setup wizard. - */ - public void testNetworkSetupWizardPermission() { - final ArraySet allowedPackages = new ArraySet(); - - final PackageManager pm = getContext().getPackageManager(); - - final Intent intent = new Intent(Intent.ACTION_MAIN); - intent.addCategory(Intent.CATEGORY_SETUP_WIZARD); - final ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DISABLED_COMPONENTS); - String validPkg = ""; - if (ri != null) { - allowedPackages.add(ri.activityInfo.packageName); - validPkg = ri.activityInfo.packageName; - } - - final Intent preIntent = new Intent("com.android.setupwizard.OEM_PRE_SETUP"); - preIntent.addCategory(Intent.CATEGORY_DEFAULT); - final ResolveInfo preRi = pm - .resolveActivity(preIntent, PackageManager.MATCH_DISABLED_COMPONENTS); - String prePackageName = ""; - if (null != preRi) { - prePackageName = preRi.activityInfo.packageName; - } - - final Intent postIntent = new Intent("com.android.setupwizard.OEM_POST_SETUP"); - postIntent.addCategory(Intent.CATEGORY_DEFAULT); - final ResolveInfo postRi = pm - .resolveActivity(postIntent, PackageManager.MATCH_DISABLED_COMPONENTS); - String postPackageName = ""; - if (null != postRi) { - postPackageName = postRi.activityInfo.packageName; - } - if (!TextUtils.isEmpty(prePackageName) && !TextUtils.isEmpty(postPackageName) - && prePackageName.equals(postPackageName)) { - allowedPackages.add(prePackageName); - } - - final List holding = pm.getPackagesHoldingPermissions(new String[]{ - android.Manifest.permission.NETWORK_SETUP_WIZARD - }, PackageManager.MATCH_UNINSTALLED_PACKAGES); - for (PackageInfo pi : holding) { - if (!allowedPackages.contains(pi.packageName)) { - fail("The NETWORK_SETUP_WIZARD permission must not be held by " + pi.packageName - + " and must be revoked for security reasons [" + validPkg + "]"); - } - } - } - - /** - * Verify that the {@link android.Manifest.permission#NETWORK_MANAGED_PROVISIONING} permission - * is only held by the device managed provisioning application. - *

    - * Only the ManagedProvisioning app should ever attempt to acquire this - * permission, since it would give those apps extremely broad access to connectivity - * functionality. The permission is intended to be granted to only the device managed - * provisioning. - */ - public void testNetworkManagedProvisioningPermission() { - final PackageManager pm = getContext().getPackageManager(); - - // TODO(b/115980767): Using hardcoded package name. Need a better mechanism to find the - // managed provisioning app. - // Ensure that the package exists. - final Intent intent = new Intent(Intent.ACTION_MAIN); - intent.setPackage(MANAGED_PROVISIONING_PACKAGE_NAME); - final ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DISABLED_COMPONENTS); - String validPkg = ""; - if (ri != null) { - validPkg = ri.activityInfo.packageName; - } - - final List holding = pm.getPackagesHoldingPermissions(new String[] { - android.Manifest.permission.NETWORK_MANAGED_PROVISIONING - }, PackageManager.MATCH_UNINSTALLED_PACKAGES); - for (PackageInfo pi : holding) { - if (!Objects.equals(pi.packageName, validPkg)) { - fail("The NETWORK_MANAGED_PROVISIONING permission must not be held by " - + pi.packageName + " and must be revoked for security reasons [" - + validPkg +"]"); - } - } - } - - /** - * Verify that the {@link android.Manifest.permission#WIFI_SET_DEVICE_MOBILITY_STATE} permission - * is held by at most one application. - */ - public void testWifiSetDeviceMobilityStatePermission() { - final PackageManager pm = getContext().getPackageManager(); - - final List holding = pm.getPackagesHoldingPermissions(new String[] { - android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE - }, PackageManager.MATCH_UNINSTALLED_PACKAGES); - - List uniquePackageNames = holding - .stream() - .map(pi -> pi.packageName) - .distinct() - .collect(Collectors.toList()); - - if (uniquePackageNames.size() > 1) { - fail("The WIFI_SET_DEVICE_MOBILITY_STATE permission must not be held by more than one " - + "application, but is held by " + uniquePackageNames.size() + " applications: " - + String.join(", ", uniquePackageNames)); - } - } - - /** - * Verify that the {@link android.Manifest.permission#NETWORK_CARRIER_PROVISIONING} permission - * is held by at most one application. - */ - public void testNetworkCarrierProvisioningPermission() { - final PackageManager pm = getContext().getPackageManager(); - - final List holding = pm.getPackagesHoldingPermissions(new String[] { - android.Manifest.permission.NETWORK_CARRIER_PROVISIONING - }, PackageManager.MATCH_UNINSTALLED_PACKAGES); - - List uniquePackageNames = holding - .stream() - .map(pi -> pi.packageName) - .distinct() - .collect(Collectors.toList()); - - if (uniquePackageNames.size() > 2) { - fail("The NETWORK_CARRIER_PROVISIONING permission must not be held by more than two " - + "applications, but is held by " + uniquePackageNames.size() + " applications: " - + String.join(", ", uniquePackageNames)); - } - } - - /** - * Verify that the {@link android.Manifest.permission#WIFI_UPDATE_USABILITY_STATS_SCORE} - * permission is held by at most one application. - */ - public void testUpdateWifiUsabilityStatsScorePermission() { - final PackageManager pm = getContext().getPackageManager(); - - final List holding = pm.getPackagesHoldingPermissions(new String[] { - android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE - }, PackageManager.MATCH_UNINSTALLED_PACKAGES); - - List uniquePackageNames = holding - .stream() - .map(pi -> pi.packageName) - .distinct() - .collect(Collectors.toList()); - - if (uniquePackageNames.size() > 1) { - fail("The WIFI_UPDATE_USABILITY_STATS_SCORE permission must not be held by more than " - + "one application, but is held by " + uniquePackageNames.size() + " applications: " - + String.join(", ", uniquePackageNames)); - } - } - - private void turnScreenOnNoDelay() throws Exception { - mUiDevice.executeShellCommand("input keyevent KEYCODE_WAKEUP"); - mUiDevice.executeShellCommand("wm dismiss-keyguard"); - } - - private void turnScreenOn() throws Exception { - turnScreenOnNoDelay(); - // Since the screen on/off intent is ordered, they will not be sent right now. - Thread.sleep(DURATION_SCREEN_TOGGLE); - } - - private void turnScreenOff() throws Exception { - mUiDevice.executeShellCommand("input keyevent KEYCODE_SLEEP"); - // Since the screen on/off intent is ordered, they will not be sent right now. - Thread.sleep(DURATION_SCREEN_TOGGLE); - } - - /** - * Verify that Wi-Fi scanning is not turned off when the screen turns off while wifi is disabled - * but location is on. - * @throws Exception - */ - public void testScreenOffDoesNotTurnOffWifiScanningWhenWifiDisabled() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - if (!hasLocationFeature()) { - // skip the test if location is not supported - return; - } - if (!isLocationEnabled()) { - fail("Please enable location for this test - since Marshmallow WiFi scan results are" - + " empty when location is disabled!"); - } - if(!mWifiManager.isScanAlwaysAvailable()) { - fail("Please enable Wi-Fi scanning for this test!"); - } - setWifiEnabled(false); - turnScreenOn(); - assertWifiScanningIsOn(); - // Toggle screen and verify Wi-Fi scanning is still on. - turnScreenOff(); - assertWifiScanningIsOn(); - turnScreenOn(); - assertWifiScanningIsOn(); - } - - /** - * Verify that Wi-Fi scanning is not turned off when the screen turns off while wifi is enabled. - * @throws Exception - */ - public void testScreenOffDoesNotTurnOffWifiScanningWhenWifiEnabled() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - if (!hasLocationFeature()) { - // skip the test if location is not supported - return; - } - if (!isLocationEnabled()) { - fail("Please enable location for this test - since Marshmallow WiFi scan results are" - + " empty when location is disabled!"); - } - if(!mWifiManager.isScanAlwaysAvailable()) { - fail("Please enable Wi-Fi scanning for this test!"); - } - setWifiEnabled(true); - turnScreenOn(); - assertWifiScanningIsOn(); - // Toggle screen and verify Wi-Fi scanning is still on. - turnScreenOff(); - assertWifiScanningIsOn(); - turnScreenOn(); - assertWifiScanningIsOn(); - } - - /** - * Verify that the platform supports a reasonable number of suggestions per app. - * @throws Exception - */ - public void testMaxNumberOfNetworkSuggestionsPerApp() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - assertTrue(mWifiManager.getMaxNumberOfNetworkSuggestionsPerApp() - > ENFORCED_NUM_NETWORK_SUGGESTIONS_PER_APP); - } - - private void assertWifiScanningIsOn() { - if(!mWifiManager.isScanAlwaysAvailable()) { - fail("Wi-Fi scanning should be on."); - } - } -} diff --git a/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pConfigTest.java b/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pConfigTest.java deleted file mode 100644 index 639db8a7c3..0000000000 --- a/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pConfigTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2019 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.wifi.p2p.cts; - -import android.net.MacAddress; -import android.net.wifi.p2p.WifiP2pConfig; -import android.net.wifi.p2p.WifiP2pGroup; -import android.test.AndroidTestCase; - -public class WifiP2pConfigTest extends AndroidTestCase { - static final String TEST_NETWORK_NAME = "DIRECT-xy-Hello"; - static final String TEST_PASSPHRASE = "8etterW0r1d"; - static final int TEST_OWNER_BAND = WifiP2pConfig.GROUP_OWNER_BAND_5GHZ; - static final int TEST_OWNER_FREQ = 2447; - static final String TEST_DEVICE_ADDRESS = "aa:bb:cc:dd:ee:ff"; - - public void testWifiP2pConfigBuilderForPersist() { - WifiP2pConfig.Builder builder = new WifiP2pConfig.Builder(); - builder.setNetworkName(TEST_NETWORK_NAME) - .setPassphrase(TEST_PASSPHRASE) - .setGroupOperatingBand(TEST_OWNER_BAND) - .setDeviceAddress(MacAddress.fromString(TEST_DEVICE_ADDRESS)) - .enablePersistentMode(true); - WifiP2pConfig config = builder.build(); - - assertTrue(config.deviceAddress.equals(TEST_DEVICE_ADDRESS)); - assertTrue(config.networkName.equals(TEST_NETWORK_NAME)); - assertTrue(config.passphrase.equals(TEST_PASSPHRASE)); - assertEquals(config.groupOwnerBand, TEST_OWNER_BAND); - assertEquals(config.netId, WifiP2pGroup.PERSISTENT_NET_ID); - } - - public void testWifiP2pConfigBuilderForNonPersist() { - WifiP2pConfig.Builder builder = new WifiP2pConfig.Builder(); - builder.setNetworkName(TEST_NETWORK_NAME) - .setPassphrase(TEST_PASSPHRASE) - .setGroupOperatingFrequency(TEST_OWNER_FREQ) - .setDeviceAddress(MacAddress.fromString(TEST_DEVICE_ADDRESS)) - .enablePersistentMode(false); - WifiP2pConfig config = builder.build(); - - assertTrue(config.deviceAddress.equals(TEST_DEVICE_ADDRESS)); - assertTrue(config.networkName.equals(TEST_NETWORK_NAME)); - assertTrue(config.passphrase.equals(TEST_PASSPHRASE)); - assertEquals(config.groupOwnerBand, TEST_OWNER_FREQ); - assertEquals(config.netId, WifiP2pGroup.TEMPORARY_NET_ID); - } -} diff --git a/tests/cts/net/src/android/net/wifi/rtt/cts/TestBase.java b/tests/cts/net/src/android/net/wifi/rtt/cts/TestBase.java deleted file mode 100644 index 07d5718044..0000000000 --- a/tests/cts/net/src/android/net/wifi/rtt/cts/TestBase.java +++ /dev/null @@ -1,237 +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.wifi.rtt.cts; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.location.LocationManager; -import android.net.wifi.ScanResult; -import android.net.wifi.WifiManager; -import android.net.wifi.rtt.RangingResult; -import android.net.wifi.rtt.RangingResultCallback; -import android.net.wifi.rtt.WifiRttManager; -import android.os.Handler; -import android.os.HandlerExecutor; -import android.os.HandlerThread; -import android.test.AndroidTestCase; - -import com.android.compatibility.common.util.SystemUtil; - -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executor; -import java.util.concurrent.TimeUnit; - -/** - * Base class for Wi-Fi RTT CTS test cases. Provides a uniform configuration and event management - * facility. - */ -public class TestBase extends AndroidTestCase { - protected static final String TAG = "WifiRttCtsTests"; - - // wait for Wi-Fi RTT to become available - private static final int WAIT_FOR_RTT_CHANGE_SECS = 10; - - // wait for Wi-Fi scan results to become available - private static final int WAIT_FOR_SCAN_RESULTS_SECS = 20; - - protected WifiRttManager mWifiRttManager; - protected WifiManager mWifiManager; - private LocationManager mLocationManager; - private WifiManager.WifiLock mWifiLock; - - private final HandlerThread mHandlerThread = new HandlerThread("SingleDeviceTest"); - protected final Executor mExecutor; - { - mHandlerThread.start(); - mExecutor = new HandlerExecutor(new Handler(mHandlerThread.getLooper())); - } - - /** - * Returns a flag indicating whether or not Wi-Fi RTT should be tested. Wi-Fi RTT - * should be tested if the feature is supported on the current device. - */ - static boolean shouldTestWifiRtt(Context context) { - final PackageManager pm = context.getPackageManager(); - return pm.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT); - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - if (!shouldTestWifiRtt(getContext())) { - return; - } - - mLocationManager = (LocationManager) getContext().getSystemService( - Context.LOCATION_SERVICE); - assertTrue("RTT testing requires Location to be enabled", - mLocationManager.isLocationEnabled()); - - mWifiRttManager = (WifiRttManager) getContext().getSystemService( - Context.WIFI_RTT_RANGING_SERVICE); - assertNotNull("Wi-Fi RTT Manager", mWifiRttManager); - - mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); - assertNotNull("Wi-Fi Manager", mWifiManager); - mWifiLock = mWifiManager.createWifiLock(TAG); - mWifiLock.acquire(); - if (!mWifiManager.isWifiEnabled()) { - SystemUtil.runShellCommand("svc wifi enable"); - } - - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(WifiRttManager.ACTION_WIFI_RTT_STATE_CHANGED); - WifiRttBroadcastReceiver receiver = new WifiRttBroadcastReceiver(); - mContext.registerReceiver(receiver, intentFilter); - if (!mWifiRttManager.isAvailable()) { - assertTrue("Timeout waiting for Wi-Fi RTT to change status", - receiver.waitForStateChange()); - assertTrue("Wi-Fi RTT is not available (should be)", mWifiRttManager.isAvailable()); - } - } - - @Override - protected void tearDown() throws Exception { - if (!shouldTestWifiRtt(getContext())) { - super.tearDown(); - return; - } - - super.tearDown(); - } - - class WifiRttBroadcastReceiver extends BroadcastReceiver { - private CountDownLatch mBlocker = new CountDownLatch(1); - - @Override - public void onReceive(Context context, Intent intent) { - if (WifiRttManager.ACTION_WIFI_RTT_STATE_CHANGED.equals(intent.getAction())) { - mBlocker.countDown(); - } - } - - boolean waitForStateChange() throws InterruptedException { - return mBlocker.await(WAIT_FOR_RTT_CHANGE_SECS, TimeUnit.SECONDS); - } - } - - class WifiScansBroadcastReceiver extends BroadcastReceiver { - private CountDownLatch mBlocker = new CountDownLatch(1); - - @Override - public void onReceive(Context context, Intent intent) { - if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(intent.getAction())) { - mBlocker.countDown(); - } - } - - boolean waitForStateChange() throws InterruptedException { - return mBlocker.await(WAIT_FOR_SCAN_RESULTS_SECS, TimeUnit.SECONDS); - } - } - - class ResultCallback extends RangingResultCallback { - private CountDownLatch mBlocker = new CountDownLatch(1); - private int mCode; // 0: success, otherwise RangingResultCallback STATUS_CODE_*. - private List mResults; - - @Override - public void onRangingFailure(int code) { - mCode = code; - mResults = null; // not necessary since intialized to null - but for completeness - mBlocker.countDown(); - } - - @Override - public void onRangingResults(List results) { - mCode = 0; // not necessary since initialized to 0 - but for completeness - mResults = results; - mBlocker.countDown(); - } - - /** - * Waits for the listener callback to be called - or an error (timeout, interruption). - * Returns true on callback called, false on error (timeout, interruption). - */ - boolean waitForCallback() throws InterruptedException { - return mBlocker.await(WAIT_FOR_RTT_CHANGE_SECS, TimeUnit.SECONDS); - } - - /** - * Returns the code of the callback operation. Will be 0 for success (onRangingResults - * called), else (if onRangingFailure called) will be one of the STATUS_CODE_* values. - */ - int getCode() { - return mCode; - } - - /** - * Returns the list of ranging results. In cases of error (getCode() != 0) will return null. - */ - List getResults() { - return mResults; - } - } - - /** - * Start a scan and return a list of observed ScanResults (APs). - */ - protected List scanAps() throws InterruptedException { - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); - WifiScansBroadcastReceiver receiver = new WifiScansBroadcastReceiver(); - mContext.registerReceiver(receiver, intentFilter); - - mWifiManager.startScan(); - receiver.waitForStateChange(); - mContext.unregisterReceiver(receiver); - return mWifiManager.getScanResults(); - } - - /** - * Start a scan and return a test AP which supports IEEE 802.11mc and which has the highest - * RSSI. Will perform N (parameterized) scans and get the best AP across both scans. - * - * Returns null if test AP is not found in the specified number of scans. - * - * @param numScanRetries Maximum number of scans retries (in addition to first scan). - */ - protected ScanResult scanForTestAp(int numScanRetries) - throws InterruptedException { - int scanCount = 0; - ScanResult bestTestAp = null; - while (scanCount <= numScanRetries) { - for (ScanResult scanResult : scanAps()) { - if (!scanResult.is80211mcResponder()) { - continue; - } - if (bestTestAp == null || scanResult.level > bestTestAp.level) { - bestTestAp = scanResult; - } - } - - scanCount++; - } - - return bestTestAp; - } -} diff --git a/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java b/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java deleted file mode 100644 index f71cadba7e..0000000000 --- a/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java +++ /dev/null @@ -1,214 +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.wifi.rtt.cts; - -import android.net.wifi.ScanResult; -import android.net.wifi.rtt.RangingRequest; -import android.net.wifi.rtt.RangingResult; -import android.platform.test.annotations.AppModeFull; - -import com.android.compatibility.common.util.DeviceReportLog; -import com.android.compatibility.common.util.ResultType; -import com.android.compatibility.common.util.ResultUnit; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * Wi-Fi RTT CTS test: range to all available Access Points which support IEEE 802.11mc. - */ -@AppModeFull(reason = "Cannot get WifiManager in instant app mode") -public class WifiRttTest extends TestBase { - // Number of scans to do while searching for APs supporting IEEE 802.11mc - private static final int NUM_SCANS_SEARCHING_FOR_IEEE80211MC_AP = 2; - - // Number of RTT measurements per AP - private static final int NUM_OF_RTT_ITERATIONS = 10; - - // Maximum failure rate of RTT measurements (percentage) - private static final int MAX_FAILURE_RATE_PERCENT = 10; - - // Maximum variation from the average measurement (measures consistency) - private static final int MAX_VARIATION_FROM_AVERAGE_DISTANCE_MM = 1000; - - // Minimum valid RSSI value - private static final int MIN_VALID_RSSI = -100; - - /** - * Test Wi-Fi RTT ranging operation: - * - Scan for visible APs for the test AP (which is validated to support IEEE 802.11mc) - * - Perform N (constant) RTT operations - * - Validate: - * - Failure ratio < threshold (constant) - * - Result margin < threshold (constant) - */ - public void testRangingToTestAp() throws InterruptedException { - if (!shouldTestWifiRtt(getContext())) { - return; - } - - // Scan for IEEE 802.11mc supporting APs - ScanResult testAp = scanForTestAp(NUM_SCANS_SEARCHING_FOR_IEEE80211MC_AP); - assertTrue( - "Cannot find any test APs which support RTT / IEEE 802.11mc - please verify that " - + "your test setup includes them!", - testAp != null); - - // Perform RTT operations - RangingRequest request = new RangingRequest.Builder().addAccessPoint(testAp).build(); - List allResults = new ArrayList<>(); - int numFailures = 0; - int distanceSum = 0; - int distanceMin = 0; - int distanceMax = 0; - int[] statuses = new int[NUM_OF_RTT_ITERATIONS]; - int[] distanceMms = new int[NUM_OF_RTT_ITERATIONS]; - int[] distanceStdDevMms = new int[NUM_OF_RTT_ITERATIONS]; - int[] rssis = new int[NUM_OF_RTT_ITERATIONS]; - int[] numAttempted = new int[NUM_OF_RTT_ITERATIONS]; - int[] numSuccessful = new int[NUM_OF_RTT_ITERATIONS]; - long[] timestampsMs = new long[NUM_OF_RTT_ITERATIONS]; - byte[] lastLci = null; - byte[] lastLcr = null; - for (int i = 0; i < NUM_OF_RTT_ITERATIONS; ++i) { - ResultCallback callback = new ResultCallback(); - mWifiRttManager.startRanging(request, mExecutor, callback); - assertTrue("Wi-Fi RTT results: no callback on iteration " + i, - callback.waitForCallback()); - - List currentResults = callback.getResults(); - assertTrue("Wi-Fi RTT results: null results (onRangingFailure) on iteration " + i, - currentResults != null); - assertTrue("Wi-Fi RTT results: unexpected # of results (expect 1) on iteration " + i, - currentResults.size() == 1); - RangingResult result = currentResults.get(0); - assertTrue("Wi-Fi RTT results: invalid result (wrong BSSID) entry on iteration " + i, - result.getMacAddress().toString().equals(testAp.BSSID)); - assertEquals( - "Wi-Fi RTT results: invalid result (non-null PeerHandle) entry on iteration " - + i, null, result.getPeerHandle()); - - allResults.add(result); - int status = result.getStatus(); - statuses[i] = status; - if (status == RangingResult.STATUS_SUCCESS) { - distanceSum += result.getDistanceMm(); - if (i == 0) { - distanceMin = result.getDistanceMm(); - distanceMax = result.getDistanceMm(); - } else { - distanceMin = Math.min(distanceMin, result.getDistanceMm()); - distanceMax = Math.max(distanceMax, result.getDistanceMm()); - } - - assertTrue("Wi-Fi RTT results: invalid RSSI on iteration " + i, - result.getRssi() >= MIN_VALID_RSSI); - - distanceMms[i - numFailures] = result.getDistanceMm(); - distanceStdDevMms[i - numFailures] = result.getDistanceStdDevMm(); - rssis[i - numFailures] = result.getRssi(); - numAttempted[i - numFailures] = result.getNumAttemptedMeasurements(); - numSuccessful[i - numFailures] = result.getNumSuccessfulMeasurements(); - timestampsMs[i - numFailures] = result.getRangingTimestampMillis(); - - byte[] currentLci = result.getLci(); - byte[] currentLcr = result.getLcr(); - if (i - numFailures > 0) { - assertTrue("Wi-Fi RTT results: invalid result (LCI mismatch) on iteration " + i, - Arrays.equals(currentLci, lastLci)); - assertTrue("Wi-Fi RTT results: invalid result (LCR mismatch) on iteration " + i, - Arrays.equals(currentLcr, lastLcr)); - } - lastLci = currentLci; - lastLcr = currentLcr; - } else { - numFailures++; - } - } - - // Save results to log - int numGoodResults = NUM_OF_RTT_ITERATIONS - numFailures; - DeviceReportLog reportLog = new DeviceReportLog(TAG, "testRangingToTestAp"); - reportLog.addValues("status_codes", statuses, ResultType.NEUTRAL, ResultUnit.NONE); - reportLog.addValues("distance_mm", Arrays.copyOf(distanceMms, numGoodResults), - ResultType.NEUTRAL, ResultUnit.NONE); - reportLog.addValues("distance_stddev_mm", Arrays.copyOf(distanceStdDevMms, numGoodResults), - ResultType.NEUTRAL, ResultUnit.NONE); - reportLog.addValues("rssi_dbm", Arrays.copyOf(rssis, numGoodResults), ResultType.NEUTRAL, - ResultUnit.NONE); - reportLog.addValues("num_attempted", Arrays.copyOf(numAttempted, numGoodResults), - ResultType.NEUTRAL, ResultUnit.NONE); - reportLog.addValues("num_successful", Arrays.copyOf(numSuccessful, numGoodResults), - ResultType.NEUTRAL, ResultUnit.NONE); - reportLog.addValues("timestamps", Arrays.copyOf(timestampsMs, numGoodResults), - ResultType.NEUTRAL, ResultUnit.NONE); - reportLog.submit(); - - // Analyze results - assertTrue("Wi-Fi RTT failure rate exceeds threshold: FAIL=" + numFailures + ", ITERATIONS=" - + NUM_OF_RTT_ITERATIONS, - numFailures <= NUM_OF_RTT_ITERATIONS * MAX_FAILURE_RATE_PERCENT / 100); - if (numFailures != NUM_OF_RTT_ITERATIONS) { - double distanceAvg = distanceSum / (NUM_OF_RTT_ITERATIONS - numFailures); - assertTrue("Wi-Fi RTT: Variation (max direction) exceeds threshold", - (distanceMax - distanceAvg) <= MAX_VARIATION_FROM_AVERAGE_DISTANCE_MM); - assertTrue("Wi-Fi RTT: Variation (min direction) exceeds threshold", - (distanceAvg - distanceMin) <= MAX_VARIATION_FROM_AVERAGE_DISTANCE_MM); - for (int i = 0; i < numGoodResults; ++i) { - assertNotSame("Number of attempted measurements is 0", 0, numAttempted[i]); - assertNotSame("Number of successful measurements is 0", 0, numSuccessful[i]); - } - } - } - - /** - * Validate that when a request contains more range operations than allowed (by API) that we - * get an exception. - */ - public void testRequestTooLarge() { - if (!shouldTestWifiRtt(getContext())) { - return; - } - - ScanResult dummy = new ScanResult(); - dummy.BSSID = "00:01:02:03:04:05"; - - RangingRequest.Builder builder = new RangingRequest.Builder(); - for (int i = 0; i < RangingRequest.getMaxPeers() - 2; ++i) { - builder.addAccessPoint(dummy); - } - - List scanResults = new ArrayList<>(); - scanResults.add(dummy); - scanResults.add(dummy); - scanResults.add(dummy); - - builder.addAccessPoints(scanResults); - - try { - mWifiRttManager.startRanging(builder.build(), mExecutor, new ResultCallback()); - } catch (IllegalArgumentException e) { - return; - } - - assertTrue( - "Did not receive expected IllegalArgumentException when tried to range to too " - + "many peers", - false); - } -} From aa5d56647644856ea768d7b162c0211bd2da5345 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Tue, 24 Mar 2020 16:12:48 -0700 Subject: [PATCH 0813/1109] WifiNetworkSpecifierTest: Remove double quotes from preSharedKey Legacy WifiConfiguration.preSharedKey is double quoted (similar to SSID). Bug: 152264590 Test: atest android.net.wifi.cts.WifiNetworkSpecifierTest --rerun-until-failure Change-Id: Id139537f07efec4e1b49cda29b2ed9e9f40fb22f --- .../wifi/cts/WifiNetworkSpecifierTest.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java index 83018fa1cb..eb6d6843eb 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java @@ -363,13 +363,17 @@ public class WifiNetworkSpecifierTest extends AndroidTestCase { testConnectionFlowWithSpecifier(specifier, true); } + private static String removeDoubleQuotes(String string) { + return WifiInfo.sanitizeSsid(string); + } + private WifiNetworkSpecifier.Builder createSpecifierBuilderWithCredentialFromSavedNetwork() { WifiNetworkSpecifier.Builder specifierBuilder = new WifiNetworkSpecifier.Builder(); if (mTestNetwork.preSharedKey != null) { if (mTestNetwork.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK)) { - specifierBuilder.setWpa2Passphrase(mTestNetwork.preSharedKey); + specifierBuilder.setWpa2Passphrase(removeDoubleQuotes(mTestNetwork.preSharedKey)); } else if (mTestNetwork.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE)) { - specifierBuilder.setWpa3Passphrase(mTestNetwork.preSharedKey); + specifierBuilder.setWpa3Passphrase(removeDoubleQuotes(mTestNetwork.preSharedKey)); } else { fail("Unsupported security type found in saved networks"); } @@ -391,7 +395,7 @@ public class WifiNetworkSpecifierTest extends AndroidTestCase { return; } WifiNetworkSpecifier specifier = createSpecifierBuilderWithCredentialFromSavedNetwork() - .setSsid(WifiInfo.sanitizeSsid(mTestNetwork.SSID)) + .setSsid(removeDoubleQuotes(mTestNetwork.SSID)) .build(); testSuccessfulConnectionWithSpecifier(specifier); } @@ -406,7 +410,7 @@ public class WifiNetworkSpecifierTest extends AndroidTestCase { } // Creates a ssid pattern by dropping the last char in the saved network & pass that // as a prefix match pattern in the request. - String ssidUnquoted = WifiInfo.sanitizeSsid(mTestNetwork.SSID); + String ssidUnquoted = removeDoubleQuotes(mTestNetwork.SSID); assertThat(ssidUnquoted.length()).isAtLeast(2); String ssidPrefix = ssidUnquoted.substring(0, ssidUnquoted.length() - 1); // Note: The match may return more than 1 network in this case since we use a prefix match, @@ -460,7 +464,7 @@ public class WifiNetworkSpecifierTest extends AndroidTestCase { List scanResults = mWifiManager.getScanResults(); if (scanResults == null || scanResults.isEmpty()) fail("No scan results available"); for (ScanResult scanResult : scanResults) { - if (TextUtils.equals(scanResult.SSID, WifiInfo.sanitizeSsid(mTestNetwork.SSID))) { + if (TextUtils.equals(scanResult.SSID, removeDoubleQuotes(mTestNetwork.SSID))) { return scanResult; } } @@ -511,7 +515,7 @@ public class WifiNetworkSpecifierTest extends AndroidTestCase { return; } WifiNetworkSpecifier specifier = createSpecifierBuilderWithCredentialFromSavedNetwork() - .setSsid(WifiInfo.sanitizeSsid(mTestNetwork.SSID)) + .setSsid(removeDoubleQuotes(mTestNetwork.SSID)) .build(); testUserRejectionWithSpecifier(specifier); } @@ -526,11 +530,11 @@ public class WifiNetworkSpecifierTest extends AndroidTestCase { return; } WifiNetworkSpecifier specifier1 = new WifiNetworkSpecifier.Builder() - .setSsid(WifiInfo.sanitizeSsid(mTestNetwork.SSID)) + .setSsid(removeDoubleQuotes(mTestNetwork.SSID)) .setWpa2EnterpriseConfig(new WifiEnterpriseConfig()) .build(); WifiNetworkSpecifier specifier2 = new WifiNetworkSpecifier.Builder() - .setSsid(WifiInfo.sanitizeSsid(mTestNetwork.SSID)) + .setSsid(removeDoubleQuotes(mTestNetwork.SSID)) .setWpa2EnterpriseConfig(new WifiEnterpriseConfig()) .build(); assertThat(specifier1.satisfiedBy(specifier2)).isTrue(); @@ -546,11 +550,11 @@ public class WifiNetworkSpecifierTest extends AndroidTestCase { return; } WifiNetworkSpecifier specifier1 = new WifiNetworkSpecifier.Builder() - .setSsid(WifiInfo.sanitizeSsid(mTestNetwork.SSID)) + .setSsid(removeDoubleQuotes(mTestNetwork.SSID)) .setWpa3EnterpriseConfig(new WifiEnterpriseConfig()) .build(); WifiNetworkSpecifier specifier2 = new WifiNetworkSpecifier.Builder() - .setSsid(WifiInfo.sanitizeSsid(mTestNetwork.SSID)) + .setSsid(removeDoubleQuotes(mTestNetwork.SSID)) .setWpa3EnterpriseConfig(new WifiEnterpriseConfig()) .build(); assertThat(specifier1.satisfiedBy(specifier2)).isTrue(); From 04bf92fcceca2ae2b2b1a7bb764739822d3fc5bc Mon Sep 17 00:00:00 2001 From: paulhu Date: Thu, 12 Mar 2020 22:18:30 +0800 Subject: [PATCH 0814/1109] Rewrite NetworkInfo CTS tests to Kotlin Bug: 152356365 Test: atest CtsNetTestCasesLatestSdk:android.net.cts.NetworkInfoTest on both Q and R devices Change-Id: I44ffdc4b4a9ba8fcc1fda895b9d7f8f551fd6bb3 --- .../src/android/net/cts/NetworkInfoTest.java | 71 ------------------ .../src/android/net/cts/NetworkInfoTest.kt | 73 +++++++++++++++++++ 2 files changed, 73 insertions(+), 71 deletions(-) delete mode 100644 tests/cts/net/src/android/net/cts/NetworkInfoTest.java create mode 100644 tests/cts/net/src/android/net/cts/NetworkInfoTest.kt diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java deleted file mode 100644 index 4a7b4e7e82..0000000000 --- a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2009 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.content.Context; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.net.NetworkInfo.DetailedState; -import android.net.NetworkInfo.State; -import android.test.AndroidTestCase; - -public class NetworkInfoTest extends AndroidTestCase { - - public static final int TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE; - public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI; - public static final String MOBILE_TYPE_NAME = "mobile"; - public static final String WIFI_TYPE_NAME = "WIFI"; - - public void testAccessNetworkInfoProperties() { - ConnectivityManager cm = (ConnectivityManager) getContext().getSystemService( - Context.CONNECTIVITY_SERVICE); - NetworkInfo[] ni = cm.getAllNetworkInfo(); - assertTrue(ni.length >= 1); - - for (NetworkInfo netInfo: ni) { - switch (netInfo.getType()) { - case TYPE_MOBILE: - assertNetworkInfo(netInfo, MOBILE_TYPE_NAME); - break; - case TYPE_WIFI: - assertNetworkInfo(netInfo, WIFI_TYPE_NAME); - break; - // TODO: Add BLUETOOTH_TETHER testing - default: - break; - } - } - } - - private void assertNetworkInfo(NetworkInfo netInfo, String expectedTypeName) { - assertEquals(expectedTypeName.compareToIgnoreCase(netInfo.getTypeName()), 0); - if(netInfo.isConnectedOrConnecting()) { - assertTrue(netInfo.isAvailable()); - if (State.CONNECTED == netInfo.getState()) { - assertTrue(netInfo.isConnected()); - } - assertTrue(State.CONNECTING == netInfo.getState() - || State.CONNECTED == netInfo.getState()); - assertTrue(DetailedState.SCANNING == netInfo.getDetailedState() - || DetailedState.CONNECTING == netInfo.getDetailedState() - || DetailedState.AUTHENTICATING == netInfo.getDetailedState() - || DetailedState.CONNECTED == netInfo.getDetailedState()); - } - assertNotNull(netInfo.toString()); - } -} diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.kt b/tests/cts/net/src/android/net/cts/NetworkInfoTest.kt new file mode 100644 index 0000000000..e1dca53620 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.kt @@ -0,0 +1,73 @@ +/* + * 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.cts + +import android.content.Context +import android.net.ConnectivityManager +import android.net.NetworkInfo +import android.net.NetworkInfo.DetailedState +import android.net.NetworkInfo.State +import androidx.test.filters.SmallTest +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.runner.AndroidJUnit4 +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertTrue +import org.junit.runner.RunWith +import org.junit.Test + +const val TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE +const val TYPE_WIFI = ConnectivityManager.TYPE_WIFI +const val MOBILE_TYPE_NAME = "mobile" +const val WIFI_TYPE_NAME = "WIFI" + +@SmallTest +@RunWith(AndroidJUnit4::class) +class NetworkInfoTest { + @Test + fun testAccessNetworkInfoProperties() { + val cm = InstrumentationRegistry.getInstrumentation().context + .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + val ni = cm.getAllNetworkInfo() + assertTrue(ni.isNotEmpty()) + + for (netInfo in ni) { + when (netInfo.getType()) { + TYPE_MOBILE -> assertNetworkInfo(netInfo, MOBILE_TYPE_NAME) + TYPE_WIFI -> assertNetworkInfo(netInfo, WIFI_TYPE_NAME) + // TODO: Add BLUETOOTH_TETHER testing + } + } + } + + private fun assertNetworkInfo(netInfo: NetworkInfo, expectedTypeName: String) { + assertTrue(expectedTypeName.equals(netInfo.getTypeName(), ignoreCase = true)) + assertNotNull(netInfo.toString()) + + if (!netInfo.isConnectedOrConnecting()) return + + assertTrue(netInfo.isAvailable()) + if (State.CONNECTED == netInfo.getState()) { + assertTrue(netInfo.isConnected()) + } + assertTrue(State.CONNECTING == netInfo.getState() || + State.CONNECTED == netInfo.getState()) + assertTrue(DetailedState.SCANNING == netInfo.getDetailedState() || + DetailedState.CONNECTING == netInfo.getDetailedState() || + DetailedState.AUTHENTICATING == netInfo.getDetailedState() || + DetailedState.CONNECTED == netInfo.getDetailedState()) + } +} From 2725f6e267fac567e1de3a21906fb2e59a3f08ab Mon Sep 17 00:00:00 2001 From: paulhu Date: Wed, 25 Mar 2020 13:57:05 +0800 Subject: [PATCH 0815/1109] Add NetworkInfo CTS tests Test APIs below: NetworkInfo(int, int, String, String) setDetailedState(android.net.NetworkInfo.DetailedState, String, String) Bug: 152356365 Test: atest CtsNetTestCasesLatestSdk:android.net.cts.NetworkInfoTest on both Q and R devices Change-Id: Idada858b1d5cd4c0907998b289aca4d6e6d04f56 --- .../src/android/net/cts/NetworkInfoTest.kt | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.kt b/tests/cts/net/src/android/net/cts/NetworkInfoTest.kt index e1dca53620..fa15e8f82c 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfoTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.kt @@ -16,16 +16,24 @@ package android.net.cts +import android.os.Build import android.content.Context import android.net.ConnectivityManager import android.net.NetworkInfo import android.net.NetworkInfo.DetailedState import android.net.NetworkInfo.State +import android.telephony.TelephonyManager import androidx.test.filters.SmallTest import androidx.test.platform.app.InstrumentationRegistry import androidx.test.runner.AndroidJUnit4 +import com.android.testutils.DevSdkIgnoreRule +import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo +import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull +import org.junit.Assert.assertNull import org.junit.Assert.assertTrue +import org.junit.Assert.fail +import org.junit.Rule import org.junit.runner.RunWith import org.junit.Test @@ -33,10 +41,14 @@ const val TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE const val TYPE_WIFI = ConnectivityManager.TYPE_WIFI const val MOBILE_TYPE_NAME = "mobile" const val WIFI_TYPE_NAME = "WIFI" +const val LTE_SUBTYPE_NAME = "LTE" @SmallTest @RunWith(AndroidJUnit4::class) class NetworkInfoTest { + @Rule @JvmField + val ignoreRule = DevSdkIgnoreRule() + @Test fun testAccessNetworkInfoProperties() { val cm = InstrumentationRegistry.getInstrumentation().context @@ -70,4 +82,41 @@ class NetworkInfoTest { DetailedState.AUTHENTICATING == netInfo.getDetailedState() || DetailedState.CONNECTED == netInfo.getDetailedState()) } + + @Test @IgnoreUpTo(Build.VERSION_CODES.Q) + fun testConstructor() { + val networkInfo = NetworkInfo(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_LTE, + MOBILE_TYPE_NAME, LTE_SUBTYPE_NAME) + + assertEquals(TYPE_MOBILE, networkInfo.type) + assertEquals(TelephonyManager.NETWORK_TYPE_LTE, networkInfo.subtype) + assertEquals(MOBILE_TYPE_NAME, networkInfo.typeName) + assertEquals(LTE_SUBTYPE_NAME, networkInfo.subtypeName) + assertEquals(DetailedState.IDLE, networkInfo.detailedState) + assertEquals(State.UNKNOWN, networkInfo.state) + assertNull(networkInfo.reason) + assertNull(networkInfo.extraInfo) + + try { + NetworkInfo(ConnectivityManager.MAX_NETWORK_TYPE + 1, + TelephonyManager.NETWORK_TYPE_LTE, MOBILE_TYPE_NAME, LTE_SUBTYPE_NAME) + fail("Unexpected behavior. Network type is invalid.") + } catch (e: IllegalArgumentException) { + // Expected behavior. + } + } + + @Test + fun testSetDetailedState() { + val networkInfo = NetworkInfo(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_LTE, + MOBILE_TYPE_NAME, LTE_SUBTYPE_NAME) + val reason = "TestNetworkInfo" + val extraReason = "setDetailedState test" + + networkInfo.setDetailedState(DetailedState.CONNECTED, reason, extraReason) + assertEquals(DetailedState.CONNECTED, networkInfo.detailedState) + assertEquals(State.CONNECTED, networkInfo.state) + assertEquals(reason, networkInfo.reason) + assertEquals(extraReason, networkInfo.extraInfo) + } } From 7a3387b15ed7a3eb3863b00d5e8a7540a93b75fc Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Wed, 25 Mar 2020 05:14:52 +0000 Subject: [PATCH 0816/1109] Test IpConfiguration field count and parceling round trip Add test for IpConfiguration and also address review comments from aosp/1171795. Bug: 139268426 Test: CtsNetTestCasesLatestSdk:android.net.cts.IpConfigurationTest Change-Id: Ib30a98e11bdcd9d473b713f7e4c317172b14f000 Merged-In: Ib30a98e11bdcd9d473b713f7e4c317172b14f000 (cherry picked from commit 8e208eb353263bddca4d93a7a67a5f978316b0cc) --- .../android/net/cts/IpConfigurationTest.java | 78 ++++++------------- 1 file changed, 25 insertions(+), 53 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/IpConfigurationTest.java b/tests/cts/net/src/android/net/cts/IpConfigurationTest.java index 21be35142d..c6bc0770b8 100644 --- a/tests/cts/net/src/android/net/cts/IpConfigurationTest.java +++ b/tests/cts/net/src/android/net/cts/IpConfigurationTest.java @@ -16,6 +16,8 @@ package android.net.cts; +import static com.android.testutils.ParcelUtilsKt.assertParcelSane; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; @@ -37,13 +39,6 @@ import java.util.ArrayList; @RunWith(AndroidJUnit4.class) public final class IpConfigurationTest { - private static final int TYPE_IPASSIGNMENT_STATIC = 0; - private static final int TYPE_IPASSIGNMENT_DHCP = 1; - - private static final int TYPE_PROXY_SETTINGS_NONE = 0; - private static final int TYPE_PROXY_SETTINGS_STATIC = 1; - private static final int TYPE_PROXY_SETTINGS_PAC = 2; - private static final LinkAddress LINKADDR = new LinkAddress("192.0.2.2/25"); private static final InetAddress GATEWAY = InetAddressUtils.parseNumericAddress("192.0.2.1"); private static final InetAddress DNS1 = InetAddressUtils.parseNumericAddress("8.8.8.8"); @@ -76,24 +71,31 @@ public final class IpConfigurationTest { assertIpConfigurationEqual(ipConfig, new IpConfiguration()); assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig)); - ipConfig = createIpConfiguration(TYPE_IPASSIGNMENT_STATIC, - TYPE_PROXY_SETTINGS_PAC); + ipConfig.setStaticIpConfiguration(mStaticIpConfig); + ipConfig.setHttpProxy(mProxy); + + ipConfig.setIpAssignment(IpConfiguration.IpAssignment.STATIC); + ipConfig.setProxySettings(IpConfiguration.ProxySettings.PAC); assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig)); - ipConfig = createIpConfiguration(TYPE_IPASSIGNMENT_STATIC, - TYPE_PROXY_SETTINGS_STATIC); + ipConfig.setIpAssignment(IpConfiguration.IpAssignment.STATIC); + ipConfig.setProxySettings(IpConfiguration.ProxySettings.STATIC); assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig)); - ipConfig = createIpConfiguration(TYPE_IPASSIGNMENT_DHCP, - TYPE_PROXY_SETTINGS_PAC); + ipConfig.setIpAssignment(IpConfiguration.IpAssignment.DHCP); + ipConfig.setProxySettings(IpConfiguration.ProxySettings.PAC); assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig)); - ipConfig = createIpConfiguration(TYPE_IPASSIGNMENT_DHCP, - TYPE_PROXY_SETTINGS_STATIC); + ipConfig.setIpAssignment(IpConfiguration.IpAssignment.DHCP); + ipConfig.setProxySettings(IpConfiguration.ProxySettings.PAC); assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig)); - ipConfig = createIpConfiguration(TYPE_IPASSIGNMENT_DHCP, - TYPE_PROXY_SETTINGS_NONE); + ipConfig.setIpAssignment(IpConfiguration.IpAssignment.DHCP); + ipConfig.setProxySettings(IpConfiguration.ProxySettings.STATIC); + assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig)); + + ipConfig.setIpAssignment(IpConfiguration.IpAssignment.DHCP); + ipConfig.setProxySettings(IpConfiguration.ProxySettings.NONE); assertIpConfigurationEqual(ipConfig, new IpConfiguration(ipConfig)); } @@ -106,46 +108,16 @@ public final class IpConfigurationTest { assertNull(config.getHttpProxy()); } - private IpConfiguration createIpConfiguration(int ipAssignmentType, - int proxySettingType) { - - final IpConfiguration ipConfig = new IpConfiguration(); - - switch (ipAssignmentType) { - case TYPE_IPASSIGNMENT_STATIC: - ipConfig.setIpAssignment(IpConfiguration.IpAssignment.STATIC); - break; - case TYPE_IPASSIGNMENT_DHCP: - ipConfig.setIpAssignment(IpConfiguration.IpAssignment.DHCP); - break; - default: - throw new IllegalArgumentException("Unknown ip assignment type."); - } - - switch (proxySettingType) { - case TYPE_PROXY_SETTINGS_NONE: - ipConfig.setProxySettings(IpConfiguration.ProxySettings.NONE); - break; - case TYPE_PROXY_SETTINGS_STATIC: - ipConfig.setProxySettings(IpConfiguration.ProxySettings.STATIC); - break; - case TYPE_PROXY_SETTINGS_PAC: - ipConfig.setProxySettings(IpConfiguration.ProxySettings.PAC); - break; - default: - throw new IllegalArgumentException("Unknown proxy setting type."); - } - - ipConfig.setStaticIpConfiguration(mStaticIpConfig); - ipConfig.setHttpProxy(mProxy); - - return ipConfig; - } - private void assertIpConfigurationEqual(IpConfiguration source, IpConfiguration target) { assertEquals(source.getIpAssignment(), target.getIpAssignment()); assertEquals(source.getProxySettings(), target.getProxySettings()); assertEquals(source.getHttpProxy(), target.getHttpProxy()); assertEquals(source.getStaticIpConfiguration(), target.getStaticIpConfiguration()); } + + @Test + public void testParcel() { + final IpConfiguration config = new IpConfiguration(); + assertParcelSane(config, 4); + } } From c3fbce9459979ad45e7d128af7ef21b8bd61d6c4 Mon Sep 17 00:00:00 2001 From: Paul Hu Date: Wed, 25 Mar 2020 09:20:47 +0000 Subject: [PATCH 0817/1109] Rewrite NetworkInfo CTS tests to Kotlin Bug: 152356365 Test: atest CtsNetTestCasesLatestSdk:android.net.cts.NetworkInfoTest on both Q and R devices Change-Id: I44ffdc4b4a9ba8fcc1fda895b9d7f8f551fd6bb3 Merged-In: I44ffdc4b4a9ba8fcc1fda895b9d7f8f551fd6bb3 (cherry picked from aosp/1256248) --- .../src/android/net/cts/NetworkInfoTest.java | 71 ------------------ .../src/android/net/cts/NetworkInfoTest.kt | 73 +++++++++++++++++++ 2 files changed, 73 insertions(+), 71 deletions(-) delete mode 100644 tests/cts/net/src/android/net/cts/NetworkInfoTest.java create mode 100644 tests/cts/net/src/android/net/cts/NetworkInfoTest.kt diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java b/tests/cts/net/src/android/net/cts/NetworkInfoTest.java deleted file mode 100644 index 4a7b4e7e82..0000000000 --- a/tests/cts/net/src/android/net/cts/NetworkInfoTest.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2009 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.content.Context; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.net.NetworkInfo.DetailedState; -import android.net.NetworkInfo.State; -import android.test.AndroidTestCase; - -public class NetworkInfoTest extends AndroidTestCase { - - public static final int TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE; - public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI; - public static final String MOBILE_TYPE_NAME = "mobile"; - public static final String WIFI_TYPE_NAME = "WIFI"; - - public void testAccessNetworkInfoProperties() { - ConnectivityManager cm = (ConnectivityManager) getContext().getSystemService( - Context.CONNECTIVITY_SERVICE); - NetworkInfo[] ni = cm.getAllNetworkInfo(); - assertTrue(ni.length >= 1); - - for (NetworkInfo netInfo: ni) { - switch (netInfo.getType()) { - case TYPE_MOBILE: - assertNetworkInfo(netInfo, MOBILE_TYPE_NAME); - break; - case TYPE_WIFI: - assertNetworkInfo(netInfo, WIFI_TYPE_NAME); - break; - // TODO: Add BLUETOOTH_TETHER testing - default: - break; - } - } - } - - private void assertNetworkInfo(NetworkInfo netInfo, String expectedTypeName) { - assertEquals(expectedTypeName.compareToIgnoreCase(netInfo.getTypeName()), 0); - if(netInfo.isConnectedOrConnecting()) { - assertTrue(netInfo.isAvailable()); - if (State.CONNECTED == netInfo.getState()) { - assertTrue(netInfo.isConnected()); - } - assertTrue(State.CONNECTING == netInfo.getState() - || State.CONNECTED == netInfo.getState()); - assertTrue(DetailedState.SCANNING == netInfo.getDetailedState() - || DetailedState.CONNECTING == netInfo.getDetailedState() - || DetailedState.AUTHENTICATING == netInfo.getDetailedState() - || DetailedState.CONNECTED == netInfo.getDetailedState()); - } - assertNotNull(netInfo.toString()); - } -} diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.kt b/tests/cts/net/src/android/net/cts/NetworkInfoTest.kt new file mode 100644 index 0000000000..e1dca53620 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.kt @@ -0,0 +1,73 @@ +/* + * 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.cts + +import android.content.Context +import android.net.ConnectivityManager +import android.net.NetworkInfo +import android.net.NetworkInfo.DetailedState +import android.net.NetworkInfo.State +import androidx.test.filters.SmallTest +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.runner.AndroidJUnit4 +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertTrue +import org.junit.runner.RunWith +import org.junit.Test + +const val TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE +const val TYPE_WIFI = ConnectivityManager.TYPE_WIFI +const val MOBILE_TYPE_NAME = "mobile" +const val WIFI_TYPE_NAME = "WIFI" + +@SmallTest +@RunWith(AndroidJUnit4::class) +class NetworkInfoTest { + @Test + fun testAccessNetworkInfoProperties() { + val cm = InstrumentationRegistry.getInstrumentation().context + .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + val ni = cm.getAllNetworkInfo() + assertTrue(ni.isNotEmpty()) + + for (netInfo in ni) { + when (netInfo.getType()) { + TYPE_MOBILE -> assertNetworkInfo(netInfo, MOBILE_TYPE_NAME) + TYPE_WIFI -> assertNetworkInfo(netInfo, WIFI_TYPE_NAME) + // TODO: Add BLUETOOTH_TETHER testing + } + } + } + + private fun assertNetworkInfo(netInfo: NetworkInfo, expectedTypeName: String) { + assertTrue(expectedTypeName.equals(netInfo.getTypeName(), ignoreCase = true)) + assertNotNull(netInfo.toString()) + + if (!netInfo.isConnectedOrConnecting()) return + + assertTrue(netInfo.isAvailable()) + if (State.CONNECTED == netInfo.getState()) { + assertTrue(netInfo.isConnected()) + } + assertTrue(State.CONNECTING == netInfo.getState() || + State.CONNECTED == netInfo.getState()) + assertTrue(DetailedState.SCANNING == netInfo.getDetailedState() || + DetailedState.CONNECTING == netInfo.getDetailedState() || + DetailedState.AUTHENTICATING == netInfo.getDetailedState() || + DetailedState.CONNECTED == netInfo.getDetailedState()) + } +} From d1818df99dfabdcd8a95ebc7539a71e77bf33b6c Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 12 Mar 2020 22:36:18 -0700 Subject: [PATCH 0818/1109] CTS: Add tests for RssiCurve (clean cherry-pick from AOSP) Bug: 151110495 Test: atest android.net.cts.RssiCurveTest Change-Id: Ife157773f7bdb07d62c5b9a66810328d9fd5ac91 Merged-In: Ife157773f7bdb07d62c5b9a66810328d9fd5ac91 --- .../src/android/net/cts/RssiCurveTest.java | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 tests/cts/net/src/android/net/cts/RssiCurveTest.java diff --git a/tests/cts/net/src/android/net/cts/RssiCurveTest.java b/tests/cts/net/src/android/net/cts/RssiCurveTest.java new file mode 100644 index 0000000000..d651b7186b --- /dev/null +++ b/tests/cts/net/src/android/net/cts/RssiCurveTest.java @@ -0,0 +1,102 @@ +/* + * 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.cts; + +import static com.google.common.truth.Truth.assertThat; + +import android.net.RssiCurve; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +/** CTS tests for {@link RssiCurve}. */ +@RunWith(AndroidJUnit4.class) +public class RssiCurveTest { + + @Test + public void lookupScore_constantCurve() { + // One bucket from rssi=-100 to 100 with score 10. + RssiCurve curve = new RssiCurve(-100, 200, new byte[] { 10 }); + assertThat(curve.lookupScore(-200)).isEqualTo(10); + assertThat(curve.lookupScore(-100)).isEqualTo(10); + assertThat(curve.lookupScore(0)).isEqualTo(10); + assertThat(curve.lookupScore(100)).isEqualTo(10); + assertThat(curve.lookupScore(200)).isEqualTo(10); + } + + @Test + public void lookupScore_changingCurve() { + // One bucket from -100 to 0 with score -10, and one bucket from 0 to 100 with score 10. + RssiCurve curve = new RssiCurve(-100, 100, new byte[] { -10, 10 }); + assertThat(curve.lookupScore(-200)).isEqualTo(-10); + assertThat(curve.lookupScore(-100)).isEqualTo(-10); + assertThat(curve.lookupScore(-50)).isEqualTo(-10); + assertThat(curve.lookupScore(0)).isEqualTo(10); + assertThat(curve.lookupScore(50)).isEqualTo(10); + assertThat(curve.lookupScore(100)).isEqualTo(10); + assertThat(curve.lookupScore(200)).isEqualTo(10); + } + + @Test + public void lookupScore_linearCurve() { + // Curve starting at -110, with 15 buckets of width 10 whose scores increases by 10 with + // each bucket. The current active network gets a boost of 15 to its RSSI. + RssiCurve curve = new RssiCurve( + -110, + 10, + new byte[] { -20, -10, 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120 }, + 15); + + assertThat(curve.lookupScore(-120)).isEqualTo(-20); + assertThat(curve.lookupScore(-120, false)).isEqualTo(-20); + assertThat(curve.lookupScore(-120, true)).isEqualTo(-20); + + assertThat(curve.lookupScore(-111)).isEqualTo(-20); + assertThat(curve.lookupScore(-111, false)).isEqualTo(-20); + assertThat(curve.lookupScore(-111, true)).isEqualTo(-10); + + assertThat(curve.lookupScore(-110)).isEqualTo(-20); + assertThat(curve.lookupScore(-110, false)).isEqualTo(-20); + assertThat(curve.lookupScore(-110, true)).isEqualTo(-10); + + assertThat(curve.lookupScore(-105)).isEqualTo(-20); + assertThat(curve.lookupScore(-105, false)).isEqualTo(-20); + assertThat(curve.lookupScore(-105, true)).isEqualTo(0); + + assertThat(curve.lookupScore(-100)).isEqualTo(-10); + assertThat(curve.lookupScore(-100, false)).isEqualTo(-10); + assertThat(curve.lookupScore(-100, true)).isEqualTo(0); + + assertThat(curve.lookupScore(-50)).isEqualTo(40); + assertThat(curve.lookupScore(-50, false)).isEqualTo(40); + assertThat(curve.lookupScore(-50, true)).isEqualTo(50); + + assertThat(curve.lookupScore(0)).isEqualTo(90); + assertThat(curve.lookupScore(0, false)).isEqualTo(90); + assertThat(curve.lookupScore(0, true)).isEqualTo(100); + + assertThat(curve.lookupScore(30)).isEqualTo(120); + assertThat(curve.lookupScore(30, false)).isEqualTo(120); + assertThat(curve.lookupScore(30, true)).isEqualTo(120); + + assertThat(curve.lookupScore(40)).isEqualTo(120); + assertThat(curve.lookupScore(40, false)).isEqualTo(120); + assertThat(curve.lookupScore(40, true)).isEqualTo(120); + } +} From 8de7c96417adc1d0b31244d7e99344701072c32d Mon Sep 17 00:00:00 2001 From: Nate Jiang Date: Wed, 25 Mar 2020 14:19:54 -0700 Subject: [PATCH 0819/1109] Replace mock ScanResult with real one ScanResult is now a final class, mock will not work. Use real one instead. Bug: 152434349 Test: atest WifiRttTest Change-Id: I25daf0c2596a5a1a24726e68a79191ad4199b142 --- .../android/net/wifi/rtt/cts/WifiRttTest.java | 50 +++++++++---------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java b/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java index 49aa47ec38..9cbaf3953e 100644 --- a/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java +++ b/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java @@ -72,10 +72,9 @@ public class WifiRttTest extends TestBase { // Scan for IEEE 802.11mc supporting APs ScanResult testAp = scanForTestAp(NUM_SCANS_SEARCHING_FOR_IEEE80211MC_AP); - assertTrue( + assertNotNull( "Cannot find any test APs which support RTT / IEEE 802.11mc - please verify that " - + "your test setup includes them!", - testAp != null); + + "your test setup includes them!", testAp); // Perform RTT operations RangingRequest request = new RangingRequest.Builder().addAccessPoint(testAp).build(); @@ -100,16 +99,15 @@ public class WifiRttTest extends TestBase { callback.waitForCallback()); List currentResults = callback.getResults(); - assertTrue("Wi-Fi RTT results: null results (onRangingFailure) on iteration " + i, - currentResults != null); - assertTrue("Wi-Fi RTT results: unexpected # of results (expect 1) on iteration " + i, - currentResults.size() == 1); + assertNotNull("Wi-Fi RTT results: null results (onRangingFailure) on iteration " + i, + currentResults); + assertEquals("Wi-Fi RTT results: unexpected # of results (expect 1) on iteration " + i, + 1, currentResults.size()); RangingResult result = currentResults.get(0); - assertTrue("Wi-Fi RTT results: invalid result (wrong BSSID) entry on iteration " + i, - result.getMacAddress().toString().equals(testAp.BSSID)); - assertEquals( - "Wi-Fi RTT results: invalid result (non-null PeerHandle) entry on iteration " - + i, null, result.getPeerHandle()); + assertEquals("Wi-Fi RTT results: invalid result (wrong BSSID) entry on iteration " + i, + result.getMacAddress().toString(), testAp.BSSID); + assertNull("Wi-Fi RTT results: invalid result (non-null PeerHandle) entry on iteration " + + i, result.getPeerHandle()); allResults.add(result); int status = result.getStatus(); @@ -189,23 +187,24 @@ public class WifiRttTest extends TestBase { * Validate that when a request contains more range operations than allowed (by API) that we * get an exception. */ - public void testRequestTooLarge() { + public void testRequestTooLarge() throws InterruptedException { if (!shouldTestWifiRtt(getContext())) { return; } - - ScanResult dummy = mock(ScanResult.class); - dummy.BSSID = "00:01:02:03:04:05"; + ScanResult testAp = scanForTestAp(NUM_SCANS_SEARCHING_FOR_IEEE80211MC_AP); + assertNotNull( + "Cannot find any test APs which support RTT / IEEE 802.11mc - please verify that " + + "your test setup includes them!", testAp); RangingRequest.Builder builder = new RangingRequest.Builder(); for (int i = 0; i < RangingRequest.getMaxPeers() - 2; ++i) { - builder.addAccessPoint(dummy); + builder.addAccessPoint(testAp); } List scanResults = new ArrayList<>(); - scanResults.add(dummy); - scanResults.add(dummy); - scanResults.add(dummy); + scanResults.add(testAp); + scanResults.add(testAp); + scanResults.add(testAp); builder.addAccessPoints(scanResults); @@ -215,10 +214,8 @@ public class WifiRttTest extends TestBase { return; } - assertTrue( - "Did not receive expected IllegalArgumentException when tried to range to too " - + "many peers", - false); + fail("Did not receive expected IllegalArgumentException when tried to range to too " + + "many peers"); } /** @@ -230,10 +227,9 @@ public class WifiRttTest extends TestBase { } // Scan for IEEE 802.11mc supporting APs ScanResult testAp = scanForTestAp(NUM_SCANS_SEARCHING_FOR_IEEE80211MC_AP); - assertTrue( + assertNotNull( "Cannot find any test APs which support RTT / IEEE 802.11mc - please verify that " - + "your test setup includes them!", - testAp != null); + + "your test setup includes them!", testAp); // Perform RTT operations RangingRequest request = new RangingRequest.Builder().addAccessPoint(testAp).build(); From 932336bb81624b3882a23c827663df6d2d42c72f Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Wed, 25 Mar 2020 16:57:00 -0700 Subject: [PATCH 0820/1109] ConnectedNetworkScorerTest: Test for a getter in WifiUsabilityStatsEntry Missed in the initial check-in. Bug: 150236894 Test: atest android.net.wifi.cts.ConnectedNetworkScorerTest Change-Id: I081e6840083f5b6115c143cc57fc8f3132bdbe47 --- .../net/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/cts/net/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java b/tests/cts/net/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java index ce5bb81d7b..9624dd7c4d 100644 --- a/tests/cts/net/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java @@ -174,6 +174,7 @@ public class ConnectedNetworkScorerTest extends AndroidTestCase { assertThat(statsEntry.getTotalHotspot2ScanTimeMillis()).isAtLeast(0L); assertThat(statsEntry.getTotalCcaBusyFreqTimeMillis()).isAtLeast(0L); assertThat(statsEntry.getTotalRadioOnTimeMillis()).isGreaterThan(0L); + assertThat(statsEntry.getTotalRadioOnFreqTimeMillis()).isGreaterThan(0L); assertThat(statsEntry.getTotalBeaconRx()).isGreaterThan(0L); assertThat(statsEntry.getProbeStatusSinceLastUpdate()) .isAnyOf(PROBE_STATUS_SUCCESS, From 6254c4a809a30b95bc227c9b41b24d2870e5e2a0 Mon Sep 17 00:00:00 2001 From: Paul Hu Date: Wed, 25 Mar 2020 09:21:17 +0000 Subject: [PATCH 0821/1109] Add NetworkInfo CTS tests Test APIs below: NetworkInfo(int, int, String, String) setDetailedState(android.net.NetworkInfo.DetailedState, String, String) Bug: 152356365 Test: atest CtsNetTestCasesLatestSdk:android.net.cts.NetworkInfoTest on both Q and R devices Change-Id: Idada858b1d5cd4c0907998b289aca4d6e6d04f56 Merged-In: Idada858b1d5cd4c0907998b289aca4d6e6d04f56 (cherry picked from aosp/1267480) --- .../src/android/net/cts/NetworkInfoTest.kt | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/NetworkInfoTest.kt b/tests/cts/net/src/android/net/cts/NetworkInfoTest.kt index e1dca53620..fa15e8f82c 100644 --- a/tests/cts/net/src/android/net/cts/NetworkInfoTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkInfoTest.kt @@ -16,16 +16,24 @@ package android.net.cts +import android.os.Build import android.content.Context import android.net.ConnectivityManager import android.net.NetworkInfo import android.net.NetworkInfo.DetailedState import android.net.NetworkInfo.State +import android.telephony.TelephonyManager import androidx.test.filters.SmallTest import androidx.test.platform.app.InstrumentationRegistry import androidx.test.runner.AndroidJUnit4 +import com.android.testutils.DevSdkIgnoreRule +import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo +import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull +import org.junit.Assert.assertNull import org.junit.Assert.assertTrue +import org.junit.Assert.fail +import org.junit.Rule import org.junit.runner.RunWith import org.junit.Test @@ -33,10 +41,14 @@ const val TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE const val TYPE_WIFI = ConnectivityManager.TYPE_WIFI const val MOBILE_TYPE_NAME = "mobile" const val WIFI_TYPE_NAME = "WIFI" +const val LTE_SUBTYPE_NAME = "LTE" @SmallTest @RunWith(AndroidJUnit4::class) class NetworkInfoTest { + @Rule @JvmField + val ignoreRule = DevSdkIgnoreRule() + @Test fun testAccessNetworkInfoProperties() { val cm = InstrumentationRegistry.getInstrumentation().context @@ -70,4 +82,41 @@ class NetworkInfoTest { DetailedState.AUTHENTICATING == netInfo.getDetailedState() || DetailedState.CONNECTED == netInfo.getDetailedState()) } + + @Test @IgnoreUpTo(Build.VERSION_CODES.Q) + fun testConstructor() { + val networkInfo = NetworkInfo(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_LTE, + MOBILE_TYPE_NAME, LTE_SUBTYPE_NAME) + + assertEquals(TYPE_MOBILE, networkInfo.type) + assertEquals(TelephonyManager.NETWORK_TYPE_LTE, networkInfo.subtype) + assertEquals(MOBILE_TYPE_NAME, networkInfo.typeName) + assertEquals(LTE_SUBTYPE_NAME, networkInfo.subtypeName) + assertEquals(DetailedState.IDLE, networkInfo.detailedState) + assertEquals(State.UNKNOWN, networkInfo.state) + assertNull(networkInfo.reason) + assertNull(networkInfo.extraInfo) + + try { + NetworkInfo(ConnectivityManager.MAX_NETWORK_TYPE + 1, + TelephonyManager.NETWORK_TYPE_LTE, MOBILE_TYPE_NAME, LTE_SUBTYPE_NAME) + fail("Unexpected behavior. Network type is invalid.") + } catch (e: IllegalArgumentException) { + // Expected behavior. + } + } + + @Test + fun testSetDetailedState() { + val networkInfo = NetworkInfo(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_LTE, + MOBILE_TYPE_NAME, LTE_SUBTYPE_NAME) + val reason = "TestNetworkInfo" + val extraReason = "setDetailedState test" + + networkInfo.setDetailedState(DetailedState.CONNECTED, reason, extraReason) + assertEquals(DetailedState.CONNECTED, networkInfo.detailedState) + assertEquals(State.CONNECTED, networkInfo.state) + assertEquals(reason, networkInfo.reason) + assertEquals(extraReason, networkInfo.extraInfo) + } } From 31097ecbb6a134689693f49e67cfa0911f5888e7 Mon Sep 17 00:00:00 2001 From: Treehugger Robot Date: Wed, 25 Mar 2020 10:49:39 +0000 Subject: [PATCH 0822/1109] Fix AudioGroupTest on Q The AudioGroup constructor with a Context parameter does not exist on Q devices. Use the previous constructor on older devices. Test: atest CtsNetTestCasesLatestSdk on Q and R devices Bug: 150918852 Merged-In: I24c3e7ab8c7219d6f345943ead3e3b6418fa7f47 Change-Id: I24c3e7ab8c7219d6f345943ead3e3b6418fa7f47 --- tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java b/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java index fee8621c70..fc78e96e11 100644 --- a/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java +++ b/tests/cts/net/src/android/net/rtp/cts/AudioGroupTest.java @@ -21,9 +21,12 @@ import android.net.rtp.AudioCodec; import android.net.rtp.AudioGroup; import android.net.rtp.AudioStream; import android.net.rtp.RtpStream; +import android.os.Build; import android.platform.test.annotations.AppModeFull; import android.test.AndroidTestCase; +import androidx.core.os.BuildCompat; + import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; @@ -62,7 +65,10 @@ public class AudioGroupTest extends AndroidTestCase { mSocketB.connect(mStreamB.getLocalAddress(), mStreamB.getLocalPort()); mStreamB.associate(mSocketB.getLocalAddress(), mSocketB.getLocalPort()); - mGroup = new AudioGroup(mContext); + // BuildCompat.isAtLeastR is documented to return false on release SDKs (including R) + mGroup = Build.VERSION.SDK_INT > Build.VERSION_CODES.Q || BuildCompat.isAtLeastR() + ? new AudioGroup(mContext) + : new AudioGroup(); // Constructor with context argument was introduced in R } @Override From 210a4a7e555d37ac29090bdde8fb65f32f0041f1 Mon Sep 17 00:00:00 2001 From: Dan Shi Date: Thu, 19 Mar 2020 14:07:07 -0700 Subject: [PATCH 0823/1109] Add vts10 suite to existing vts tests This is to prepare renaming vts to vts10. Bug: 151896491 Test: local build Exempt-From-Owner-Approval: This CL adds all tests in vts to a new suite vts10. vts10 will be the new name of existing vts suite. This CL won't change test logic or behavior. Change-Id: Ic250f04f0424d0a586c183d571b0ad57c56a03d0 Merged-In: Icfbc0ef0d40b908dc9ef664bedf3ead563ff9855 Merged-In: Ibb8ca5e3b9d1cc7247f57d0d89bd15b9f52fec92 Merged-In: Ia9af1fbddc66d3c94976a58c36d274425f1fe461 --- tests/cts/hostside/Android.bp | 1 + tests/cts/hostside/app/Android.bp | 1 + tests/cts/hostside/app2/Android.bp | 1 + tests/cts/net/Android.bp | 1 + tests/cts/net/api23Test/Android.bp | 1 + tests/cts/net/appForApi23/Android.bp | 1 + tests/cts/net/native/qtaguid/Android.bp | 1 + 7 files changed, 7 insertions(+) diff --git a/tests/cts/hostside/Android.bp b/tests/cts/hostside/Android.bp index b6f514233a..a8cc95ba5f 100644 --- a/tests/cts/hostside/Android.bp +++ b/tests/cts/hostside/Android.bp @@ -25,6 +25,7 @@ java_test_host { test_suites: [ "cts", "vts", + "vts10", "general-tests", ], } diff --git a/tests/cts/hostside/app/Android.bp b/tests/cts/hostside/app/Android.bp index d66b71ba83..49aacd91a9 100644 --- a/tests/cts/hostside/app/Android.bp +++ b/tests/cts/hostside/app/Android.bp @@ -34,6 +34,7 @@ android_test_helper_app { test_suites: [ "cts", "vts", + "vts10", "general-tests", ], } diff --git a/tests/cts/hostside/app2/Android.bp b/tests/cts/hostside/app2/Android.bp index 8a3c8e712a..0bb0d2f631 100644 --- a/tests/cts/hostside/app2/Android.bp +++ b/tests/cts/hostside/app2/Android.bp @@ -24,6 +24,7 @@ android_test_helper_app { test_suites: [ "cts", "vts", + "vts10", "general-tests", ], certificate: ":cts-net-app", diff --git a/tests/cts/net/Android.bp b/tests/cts/net/Android.bp index 624d149776..d77f416557 100644 --- a/tests/cts/net/Android.bp +++ b/tests/cts/net/Android.bp @@ -65,6 +65,7 @@ android_test { test_suites: [ "cts", "vts", + "vts10", "general-tests", ], test_config_template: "AndroidTestTemplate.xml", diff --git a/tests/cts/net/api23Test/Android.bp b/tests/cts/net/api23Test/Android.bp index ffe854e2e9..614a5a2a76 100644 --- a/tests/cts/net/api23Test/Android.bp +++ b/tests/cts/net/api23Test/Android.bp @@ -46,6 +46,7 @@ android_test { test_suites: [ "cts", "vts", + "vts10", "general-tests", ], diff --git a/tests/cts/net/appForApi23/Android.bp b/tests/cts/net/appForApi23/Android.bp index 82e2a08c10..17cfe3821b 100644 --- a/tests/cts/net/appForApi23/Android.bp +++ b/tests/cts/net/appForApi23/Android.bp @@ -27,6 +27,7 @@ android_test { test_suites: [ "cts", "vts", + "vts10", "general-tests", ], diff --git a/tests/cts/net/native/qtaguid/Android.bp b/tests/cts/net/native/qtaguid/Android.bp index c0f0613040..054937b4fa 100644 --- a/tests/cts/net/native/qtaguid/Android.bp +++ b/tests/cts/net/native/qtaguid/Android.bp @@ -43,6 +43,7 @@ cc_test { test_suites: [ "cts", "vts", + "vts10", ], cflags: [ From 88357725e5d16ccfa2c80ca2c4b7ae700323a8e9 Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Thu, 26 Mar 2020 09:07:28 -0700 Subject: [PATCH 0824/1109] [CTS] Fix testAddOrUpdatePasspointConfiguration in WifiManagerTest The API addOrUpdatePasspointConfiguration is deprecated on R and available only for privileged apps. Inherit Shell permissions. Bug: 152373068 Test: atest android.net.wifi.cts.WifiManagerTest#testAddOrUpdatePasspointConfiguration Change-Id: Iaedc1e67ecff116a540d7ac9f2f4e50696e459f8 --- .../android/net/wifi/cts/WifiManagerTest.java | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java index 3153149629..98846fa39b 100644 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java @@ -2471,15 +2471,21 @@ public class WifiManagerTest extends AndroidTestCase { // Create and install a Passpoint configuration PasspointConfiguration passpointConfiguration = createPasspointConfiguration(); - mWifiManager.addOrUpdatePasspointConfiguration(passpointConfiguration); + UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); + try { + uiAutomation.adoptShellPermissionIdentity(); + mWifiManager.addOrUpdatePasspointConfiguration(passpointConfiguration); - // Compare configurations - List configurations = mWifiManager.getPasspointConfigurations(); - assertNotNull(configurations); - assertEquals(passpointConfiguration, configurations.get(0)); + // Compare configurations + List configurations = mWifiManager.getPasspointConfigurations(); + assertNotNull(configurations); + assertEquals(passpointConfiguration, configurations.get(0)); - // Clean up - mWifiManager.removePasspointConfiguration(passpointConfiguration.getHomeSp().getFqdn()); + // Clean up + mWifiManager.removePasspointConfiguration(passpointConfiguration.getHomeSp().getFqdn()); + } finally { + uiAutomation.dropShellPermissionIdentity(); + } } /** From 9db13f3b266f4474726194b690a186de90d4b7fa Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 19 Mar 2020 21:59:37 -0700 Subject: [PATCH 0825/1109] CTS: Split Wifi tests out of CtsNetTestCases Create CtsWifiTestCases. Bug: 129133376 Test: atest CtsWifiTestCases Change-Id: Iaa51f7ec86e6b4bfe64dcb26a8d8b818dd356608 --- tests/cts/net/src/android/net/wifi/OWNERS | 5 - .../net/wifi/aware/cts/SingleDeviceTest.java | 871 ------ .../android/net/wifi/aware/cts/TestUtils.java | 69 - .../android/net/wifi/cts/ConcurrencyTest.java | 704 ----- .../net/wifi/cts/ConfigParserTest.java | 114 - .../wifi/cts/ConnectedNetworkScorerTest.java | 345 --- .../cts/EasyConnectStatusCallbackTest.java | 170 -- .../src/android/net/wifi/cts/FakeKeys.java | 257 -- .../net/wifi/cts/MulticastLockTest.java | 79 - .../android/net/wifi/cts/NsdManagerTest.java | 592 ---- .../android/net/wifi/cts/PpsMoParserTest.java | 131 - .../android/net/wifi/cts/ScanResultTest.java | 331 --- .../net/wifi/cts/SupplicantStateTest.java | 42 - .../net/wifi/cts/WifiConfigurationTest.java | 51 - .../wifi/cts/WifiEnterpriseConfigTest.java | 899 ------ .../src/android/net/wifi/cts/WifiFeature.java | 32 - .../cts/WifiFrameworkInitializerTest.java | 40 - .../net/wifi/cts/WifiHotspot2Test.java | 488 ---- .../android/net/wifi/cts/WifiInfoTest.java | 255 -- .../android/net/wifi/cts/WifiLockTest.java | 92 - .../android/net/wifi/cts/WifiManagerTest.java | 2532 ----------------- .../net/wifi/cts/WifiMigrationTest.java | 138 - .../wifi/cts/WifiNetworkSpecifierTest.java | 562 ---- .../wifi/cts/WifiNetworkSuggestionTest.java | 268 -- .../cts/DeviceWiphyCapabilitiesTest.java | 99 - .../nl80211/cts/NativeWifiClientTest.java | 81 - .../net/wifi/nl80211/cts/PnoNetworkTest.java | 97 - .../net/wifi/nl80211/cts/PnoSettingsTest.java | 124 - .../wifi/nl80211/cts/RadioChainInfoTest.java | 83 - .../nl80211/cts/WifiNl80211ManagerTest.java | 84 - .../net/wifi/p2p/cts/WifiP2pConfigTest.java | 80 - .../net/wifi/p2p/cts/WifiP2pDeviceTest.java | 38 - .../net/wifi/p2p/cts/WifiP2pInfoTest.java | 60 - .../p2p/cts/WifiP2pServiceRequestTest.java | 75 - .../net/wifi/p2p/cts/WifiP2pWfdInfoTest.java | 50 - .../android/net/wifi/rtt/cts/TestBase.java | 237 -- .../android/net/wifi/rtt/cts/WifiRttTest.java | 404 --- 37 files changed, 10579 deletions(-) delete mode 100644 tests/cts/net/src/android/net/wifi/OWNERS delete mode 100644 tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/aware/cts/TestUtils.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/ConfigParserTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/EasyConnectStatusCallbackTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/FakeKeys.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/MulticastLockTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/PpsMoParserTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiFeature.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiFrameworkInitializerTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiHotspot2Test.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiLockTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiMigrationTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/nl80211/cts/DeviceWiphyCapabilitiesTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/nl80211/cts/NativeWifiClientTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/nl80211/cts/PnoNetworkTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/nl80211/cts/PnoSettingsTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/nl80211/cts/RadioChainInfoTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pConfigTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pDeviceTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pInfoTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pServiceRequestTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pWfdInfoTest.java delete mode 100644 tests/cts/net/src/android/net/wifi/rtt/cts/TestBase.java delete mode 100644 tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java diff --git a/tests/cts/net/src/android/net/wifi/OWNERS b/tests/cts/net/src/android/net/wifi/OWNERS deleted file mode 100644 index 4a6001bcfe..0000000000 --- a/tests/cts/net/src/android/net/wifi/OWNERS +++ /dev/null @@ -1,5 +0,0 @@ -etancohen@google.com -lorenzo@google.com -mplass@google.com -rpius@google.com -satk@google.com diff --git a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java deleted file mode 100644 index 8f233244e8..0000000000 --- a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java +++ /dev/null @@ -1,871 +0,0 @@ -/* - * Copyright (C) 2017 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.wifi.aware.cts; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.mockito.Mockito.mock; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.location.LocationManager; -import android.net.ConnectivityManager; -import android.net.MacAddress; -import android.net.NetworkCapabilities; -import android.net.NetworkRequest; -import android.net.wifi.WifiManager; -import android.net.wifi.aware.AttachCallback; -import android.net.wifi.aware.Characteristics; -import android.net.wifi.aware.DiscoverySession; -import android.net.wifi.aware.DiscoverySessionCallback; -import android.net.wifi.aware.IdentityChangedListener; -import android.net.wifi.aware.ParcelablePeerHandle; -import android.net.wifi.aware.PeerHandle; -import android.net.wifi.aware.PublishConfig; -import android.net.wifi.aware.PublishDiscoverySession; -import android.net.wifi.aware.SubscribeConfig; -import android.net.wifi.aware.SubscribeDiscoverySession; -import android.net.wifi.aware.WifiAwareManager; -import android.net.wifi.aware.WifiAwareNetworkSpecifier; -import android.net.wifi.aware.WifiAwareSession; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.Parcel; -import android.platform.test.annotations.AppModeFull; -import android.test.AndroidTestCase; - -import com.android.compatibility.common.util.SystemUtil; - -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -/** - * Wi-Fi Aware CTS test suite: single device testing. Performs tests on a single - * device to validate Wi-Fi Aware. - */ -@AppModeFull(reason = "Cannot get WifiAwareManager in instant app mode") -public class SingleDeviceTest extends AndroidTestCase { - private static final String TAG = "WifiAwareCtsTests"; - - // wait for Wi-Fi Aware state changes & network requests callbacks - static private final int WAIT_FOR_AWARE_CHANGE_SECS = 10; // 10 seconds - private static final int MIN_DISTANCE_MM = 1 * 1000; - private static final int MAX_DISTANCE_MM = 3 * 1000; - private static final byte[] PMK_VALID = "01234567890123456789012345678901".getBytes(); - - private final Object mLock = new Object(); - private final HandlerThread mHandlerThread = new HandlerThread("SingleDeviceTest"); - private final Handler mHandler; - { - mHandlerThread.start(); - mHandler = new Handler(mHandlerThread.getLooper()); - } - - private WifiAwareManager mWifiAwareManager; - private WifiManager mWifiManager; - private WifiManager.WifiLock mWifiLock; - private ConnectivityManager mConnectivityManager; - - // used to store any WifiAwareSession allocated during tests - will clean-up after tests - private List mSessions = new ArrayList<>(); - - private class WifiAwareBroadcastReceiver extends BroadcastReceiver { - private CountDownLatch mBlocker = new CountDownLatch(1); - - @Override - public void onReceive(Context context, Intent intent) { - if (WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED.equals(intent.getAction())) { - mBlocker.countDown(); - } - } - - boolean waitForStateChange() throws InterruptedException { - return mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS); - } - } - - private class AttachCallbackTest extends AttachCallback { - static final int ATTACHED = 0; - static final int ATTACH_FAILED = 1; - static final int ERROR = 2; // no callback: timeout, interruption - - private CountDownLatch mBlocker = new CountDownLatch(1); - private int mCallbackCalled = ERROR; // garbage init - private WifiAwareSession mSession = null; - - @Override - public void onAttached(WifiAwareSession session) { - mCallbackCalled = ATTACHED; - mSession = session; - synchronized (mLock) { - mSessions.add(session); - } - mBlocker.countDown(); - } - - @Override - public void onAttachFailed() { - mCallbackCalled = ATTACH_FAILED; - mBlocker.countDown(); - } - - /** - * Waits for any of the callbacks to be called - or an error (timeout, interruption). - * Returns one of the ATTACHED, ATTACH_FAILED, or ERROR values. - */ - int waitForAnyCallback() { - try { - boolean noTimeout = mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS); - if (noTimeout) { - return mCallbackCalled; - } else { - return ERROR; - } - } catch (InterruptedException e) { - return ERROR; - } - } - - /** - * Access the session created by a callback. Only useful to be called after calling - * waitForAnyCallback() and getting the ATTACHED code back. - */ - WifiAwareSession getSession() { - return mSession; - } - } - - private class IdentityChangedListenerTest extends IdentityChangedListener { - private CountDownLatch mBlocker = new CountDownLatch(1); - private byte[] mMac = null; - - @Override - public void onIdentityChanged(byte[] mac) { - mMac = mac; - mBlocker.countDown(); - } - - /** - * Waits for the listener callback to be called - or an error (timeout, interruption). - * Returns true on callback called, false on error (timeout, interruption). - */ - boolean waitForListener() { - try { - return mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS); - } catch (InterruptedException e) { - return false; - } - } - - /** - * Returns the MAC address of the discovery interface supplied to the triggered callback. - */ - byte[] getMac() { - return mMac; - } - } - - private class DiscoverySessionCallbackTest extends DiscoverySessionCallback { - static final int ON_PUBLISH_STARTED = 0; - static final int ON_SUBSCRIBE_STARTED = 1; - static final int ON_SESSION_CONFIG_UPDATED = 2; - static final int ON_SESSION_CONFIG_FAILED = 3; - static final int ON_SESSION_TERMINATED = 4; - static final int ON_SERVICE_DISCOVERED = 5; - static final int ON_MESSAGE_SEND_SUCCEEDED = 6; - static final int ON_MESSAGE_SEND_FAILED = 7; - static final int ON_MESSAGE_RECEIVED = 8; - - private final Object mLocalLock = new Object(); - - private CountDownLatch mBlocker; - private int mCurrentWaitForCallback; - private ArrayDeque mCallbackQueue = new ArrayDeque<>(); - - private PublishDiscoverySession mPublishDiscoverySession; - private SubscribeDiscoverySession mSubscribeDiscoverySession; - - private void processCallback(int callback) { - synchronized (mLocalLock) { - if (mBlocker != null && mCurrentWaitForCallback == callback) { - mBlocker.countDown(); - } else { - mCallbackQueue.addLast(callback); - } - } - } - - @Override - public void onPublishStarted(PublishDiscoverySession session) { - mPublishDiscoverySession = session; - processCallback(ON_PUBLISH_STARTED); - } - - @Override - public void onSubscribeStarted(SubscribeDiscoverySession session) { - mSubscribeDiscoverySession = session; - processCallback(ON_SUBSCRIBE_STARTED); - } - - @Override - public void onSessionConfigUpdated() { - processCallback(ON_SESSION_CONFIG_UPDATED); - } - - @Override - public void onSessionConfigFailed() { - processCallback(ON_SESSION_CONFIG_FAILED); - } - - @Override - public void onSessionTerminated() { - processCallback(ON_SESSION_TERMINATED); - } - - @Override - public void onServiceDiscovered(PeerHandle peerHandle, byte[] serviceSpecificInfo, - List matchFilter) { - processCallback(ON_SERVICE_DISCOVERED); - } - - @Override - public void onMessageSendSucceeded(int messageId) { - processCallback(ON_MESSAGE_SEND_SUCCEEDED); - } - - @Override - public void onMessageSendFailed(int messageId) { - processCallback(ON_MESSAGE_SEND_FAILED); - } - - @Override - public void onMessageReceived(PeerHandle peerHandle, byte[] message) { - processCallback(ON_MESSAGE_RECEIVED); - } - - /** - * Wait for the specified callback - any of the ON_* constants. Returns a true - * on success (specified callback triggered) or false on failure (timed-out or - * interrupted while waiting for the requested callback). - * - * Note: other callbacks happening while while waiting for the specified callback will - * be queued. - */ - boolean waitForCallback(int callback) { - return waitForCallback(callback, WAIT_FOR_AWARE_CHANGE_SECS); - } - - /** - * Wait for the specified callback - any of the ON_* constants. Returns a true - * on success (specified callback triggered) or false on failure (timed-out or - * interrupted while waiting for the requested callback). - * - * Same as waitForCallback(int callback) execpt that allows specifying a custom timeout. - * The default timeout is a short value expected to be sufficient for all behaviors which - * should happen relatively quickly. Specifying a custom timeout should only be done for - * those cases which are known to take a specific longer period of time. - * - * Note: other callbacks happening while while waiting for the specified callback will - * be queued. - */ - boolean waitForCallback(int callback, int timeoutSec) { - synchronized (mLocalLock) { - boolean found = mCallbackQueue.remove(callback); - if (found) { - return true; - } - - mCurrentWaitForCallback = callback; - mBlocker = new CountDownLatch(1); - } - - try { - return mBlocker.await(timeoutSec, TimeUnit.SECONDS); - } catch (InterruptedException e) { - return false; - } - } - - /** - * Indicates whether the specified callback (any of the ON_* constants) has already - * happened and in the queue. Useful when the order of events is important. - */ - boolean hasCallbackAlreadyHappened(int callback) { - synchronized (mLocalLock) { - return mCallbackQueue.contains(callback); - } - } - - /** - * Returns the last created publish discovery session. - */ - PublishDiscoverySession getPublishDiscoverySession() { - PublishDiscoverySession session = mPublishDiscoverySession; - mPublishDiscoverySession = null; - return session; - } - - /** - * Returns the last created subscribe discovery session. - */ - SubscribeDiscoverySession getSubscribeDiscoverySession() { - SubscribeDiscoverySession session = mSubscribeDiscoverySession; - mSubscribeDiscoverySession = null; - return session; - } - } - - private class NetworkCallbackTest extends ConnectivityManager.NetworkCallback { - private CountDownLatch mBlocker = new CountDownLatch(1); - - @Override - public void onUnavailable() { - mBlocker.countDown(); - } - - /** - * Wait for the onUnavailable() callback to be triggered. Returns true if triggered, - * otherwise (timed-out, interrupted) returns false. - */ - boolean waitForOnUnavailable() { - try { - return mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS); - } catch (InterruptedException e) { - return false; - } - } - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - - assertTrue("Wi-Fi Aware requires Location to be Enabled", - ((LocationManager) getContext().getSystemService( - Context.LOCATION_SERVICE)).isLocationEnabled()); - - mWifiAwareManager = (WifiAwareManager) getContext().getSystemService( - Context.WIFI_AWARE_SERVICE); - assertNotNull("Wi-Fi Aware Manager", mWifiAwareManager); - - mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); - assertNotNull("Wi-Fi Manager", mWifiManager); - mWifiLock = mWifiManager.createWifiLock(TAG); - mWifiLock.acquire(); - if (!mWifiManager.isWifiEnabled()) { - SystemUtil.runShellCommand("svc wifi enable"); - } - - mConnectivityManager = (ConnectivityManager) getContext().getSystemService( - Context.CONNECTIVITY_SERVICE); - assertNotNull("Connectivity Manager", mConnectivityManager); - - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED); - WifiAwareBroadcastReceiver receiver = new WifiAwareBroadcastReceiver(); - mContext.registerReceiver(receiver, intentFilter); - if (!mWifiAwareManager.isAvailable()) { - assertTrue("Timeout waiting for Wi-Fi Aware to change status", - receiver.waitForStateChange()); - assertTrue("Wi-Fi Aware is not available (should be)", mWifiAwareManager.isAvailable()); - } - } - - @Override - protected void tearDown() throws Exception { - if (!TestUtils.shouldTestWifiAware(getContext())) { - super.tearDown(); - return; - } - - synchronized (mLock) { - for (WifiAwareSession session : mSessions) { - // no damage from destroying twice (i.e. ok if test cleaned up after itself already) - session.close(); - } - mSessions.clear(); - } - - super.tearDown(); - } - - /** - * Validate: - * - Characteristics are available - * - Characteristics values are legitimate. Not in the CDD. However, the tested values are - * based on the Wi-Fi Aware protocol. - */ - public void testCharacteristics() { - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - - Characteristics characteristics = mWifiAwareManager.getCharacteristics(); - assertNotNull("Wi-Fi Aware characteristics are null", characteristics); - assertEquals("Service Name Length", characteristics.getMaxServiceNameLength(), 255); - assertEquals("Service Specific Information Length", - characteristics.getMaxServiceSpecificInfoLength(), 255); - assertEquals("Match Filter Length", characteristics.getMaxMatchFilterLength(), 255); - assertNotEquals("Cipher suites", characteristics.getSupportedCipherSuites(), 0); - } - - /** - * Validate that on Wi-Fi Aware availability change we get a broadcast + the API returns - * correct status. - */ - public void testAvailabilityStatusChange() throws Exception { - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED); - - // 1. Disable Wi-Fi - WifiAwareBroadcastReceiver receiver1 = new WifiAwareBroadcastReceiver(); - mContext.registerReceiver(receiver1, intentFilter); - SystemUtil.runShellCommand("svc wifi disable"); - - assertTrue("Timeout waiting for Wi-Fi Aware to change status", - receiver1.waitForStateChange()); - assertFalse("Wi-Fi Aware is available (should not be)", mWifiAwareManager.isAvailable()); - - // 2. Enable Wi-Fi - WifiAwareBroadcastReceiver receiver2 = new WifiAwareBroadcastReceiver(); - mContext.registerReceiver(receiver2, intentFilter); - SystemUtil.runShellCommand("svc wifi enable"); - - assertTrue("Timeout waiting for Wi-Fi Aware to change status", - receiver2.waitForStateChange()); - assertTrue("Wi-Fi Aware is not available (should be)", mWifiAwareManager.isAvailable()); - } - - /** - * Validate that can attach to Wi-Fi Aware. - */ - public void testAttachNoIdentity() { - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - - WifiAwareSession session = attachAndGetSession(); - session.close(); - } - - /** - * Validate that can attach to Wi-Fi Aware and get identity information. Use the identity - * information to validate that MAC address changes on every attach. - * - * Note: relies on no other entity using Wi-Fi Aware during the CTS test. Since if it is used - * then the attach/destroy will not correspond to enable/disable and will not result in a new - * MAC address being generated. - */ - public void testAttachDiscoveryAddressChanges() { - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - - final int numIterations = 10; - Set macs = new HashSet<>(); - - for (int i = 0; i < numIterations; ++i) { - AttachCallbackTest attachCb = new AttachCallbackTest(); - IdentityChangedListenerTest identityL = new IdentityChangedListenerTest(); - mWifiAwareManager.attach(attachCb, identityL, mHandler); - assertEquals("Wi-Fi Aware attach: iteration " + i, AttachCallbackTest.ATTACHED, - attachCb.waitForAnyCallback()); - assertTrue("Wi-Fi Aware attach: iteration " + i, identityL.waitForListener()); - - WifiAwareSession session = attachCb.getSession(); - assertNotNull("Wi-Fi Aware session: iteration " + i, session); - - byte[] mac = identityL.getMac(); - assertNotNull("Wi-Fi Aware discovery MAC: iteration " + i, mac); - - session.close(); - - macs.add(new TestUtils.MacWrapper(mac)); - } - - assertEquals("", numIterations, macs.size()); - } - - /** - * Validate a successful publish discovery session lifetime: publish, update publish, destroy. - */ - public void testPublishDiscoverySuccess() { - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - - final String serviceName = "ValidName"; - - WifiAwareSession session = attachAndGetSession(); - - PublishConfig publishConfig = new PublishConfig.Builder().setServiceName( - serviceName).build(); - DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); - - // 1. publish - session.publish(publishConfig, discoveryCb, mHandler); - assertTrue("Publish started", - discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED)); - PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession(); - assertNotNull("Publish session", discoverySession); - - // 2. update-publish - publishConfig = new PublishConfig.Builder().setServiceName( - serviceName).setServiceSpecificInfo("extras".getBytes()).build(); - discoverySession.updatePublish(publishConfig); - assertTrue("Publish update", discoveryCb.waitForCallback( - DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED)); - - // 3. destroy - assertFalse("Publish not terminated", discoveryCb.hasCallbackAlreadyHappened( - DiscoverySessionCallbackTest.ON_SESSION_TERMINATED)); - discoverySession.close(); - - // 4. try update post-destroy: should time-out waiting for cb - discoverySession.updatePublish(publishConfig); - assertFalse("Publish update post destroy", discoveryCb.waitForCallback( - DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED)); - - session.close(); - } - - /** - * Validate that publish with a Time To Live (TTL) setting expires within the specified - * time (and validates that the terminate callback is triggered). - */ - public void testPublishLimitedTtlSuccess() { - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - - final String serviceName = "ValidName"; - final int ttlSec = 5; - - WifiAwareSession session = attachAndGetSession(); - - PublishConfig publishConfig = new PublishConfig.Builder().setServiceName( - serviceName).setTtlSec(ttlSec).setTerminateNotificationEnabled(true).build(); - DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); - - // 1. publish - session.publish(publishConfig, discoveryCb, mHandler); - assertTrue("Publish started", - discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED)); - PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession(); - assertNotNull("Publish session", discoverySession); - - // 2. wait for terminate within 'ttlSec'. - assertTrue("Publish terminated", - discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_SESSION_TERMINATED, - ttlSec + 5)); - - // 3. try update post-termination: should time-out waiting for cb - publishConfig = new PublishConfig.Builder().setServiceName( - serviceName).setServiceSpecificInfo("extras".getBytes()).build(); - discoverySession.updatePublish(publishConfig); - assertFalse("Publish update post terminate", discoveryCb.waitForCallback( - DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED)); - - session.close(); - } - - /** - * Validate a successful subscribe discovery session lifetime: subscribe, update subscribe, - * destroy. - */ - public void testSubscribeDiscoverySuccess() { - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - - final String serviceName = "ValidName"; - - WifiAwareSession session = attachAndGetSession(); - - SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName( - serviceName).build(); - DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); - - // 1. subscribe - session.subscribe(subscribeConfig, discoveryCb, mHandler); - assertTrue("Subscribe started", - discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_SUBSCRIBE_STARTED)); - SubscribeDiscoverySession discoverySession = discoveryCb.getSubscribeDiscoverySession(); - assertNotNull("Subscribe session", discoverySession); - - // 2. update-subscribe - subscribeConfig = new SubscribeConfig.Builder().setServiceName( - serviceName).setServiceSpecificInfo("extras".getBytes()) - .setMinDistanceMm(MIN_DISTANCE_MM).build(); - discoverySession.updateSubscribe(subscribeConfig); - assertTrue("Subscribe update", discoveryCb.waitForCallback( - DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED)); - - // 3. destroy - assertFalse("Subscribe not terminated", discoveryCb.hasCallbackAlreadyHappened( - DiscoverySessionCallbackTest.ON_SESSION_TERMINATED)); - discoverySession.close(); - - // 4. try update post-destroy: should time-out waiting for cb - discoverySession.updateSubscribe(subscribeConfig); - assertFalse("Subscribe update post destroy", discoveryCb.waitForCallback( - DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED)); - - session.close(); - } - - /** - * Validate that subscribe with a Time To Live (TTL) setting expires within the specified - * time (and validates that the terminate callback is triggered). - */ - public void testSubscribeLimitedTtlSuccess() { - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - - final String serviceName = "ValidName"; - final int ttlSec = 5; - - WifiAwareSession session = attachAndGetSession(); - - SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName( - serviceName).setTtlSec(ttlSec).setTerminateNotificationEnabled(true).build(); - DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); - - // 1. subscribe - session.subscribe(subscribeConfig, discoveryCb, mHandler); - assertTrue("Subscribe started", - discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_SUBSCRIBE_STARTED)); - SubscribeDiscoverySession discoverySession = discoveryCb.getSubscribeDiscoverySession(); - assertNotNull("Subscribe session", discoverySession); - - // 2. wait for terminate within 'ttlSec'. - assertTrue("Subscribe terminated", - discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_SESSION_TERMINATED, - ttlSec + 5)); - - // 3. try update post-termination: should time-out waiting for cb - subscribeConfig = new SubscribeConfig.Builder().setServiceName( - serviceName).setServiceSpecificInfo("extras".getBytes()).build(); - discoverySession.updateSubscribe(subscribeConfig); - assertFalse("Subscribe update post terminate", discoveryCb.waitForCallback( - DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED)); - - session.close(); - } - - /** - * Test the send message flow. Since testing single device cannot send to a real peer - - * validate that sending to a bogus peer fails. - */ - public void testSendMessageFail() { - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - - WifiAwareSession session = attachAndGetSession(); - - PublishConfig publishConfig = new PublishConfig.Builder().setServiceName( - "ValidName").build(); - DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); - - // 1. publish - session.publish(publishConfig, discoveryCb, mHandler); - assertTrue("Publish started", - discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED)); - PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession(); - assertNotNull("Publish session", discoverySession); - - // 2. send a message with a null peer-handle - expect exception - try { - discoverySession.sendMessage(null, -1290, "some message".getBytes()); - fail("Expected IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // empty - } - - discoverySession.close(); - session.close(); - } - - /** - * Request an Aware data-path (open) as a Responder with an arbitrary peer MAC address. Validate - * that receive an onUnavailable() callback. - */ - public void testDataPathOpenOutOfBandFail() { - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - MacAddress mac = MacAddress.fromString("00:01:02:03:04:05"); - - // 1. initialize Aware: only purpose is to make sure it is available for OOB data-path - WifiAwareSession session = attachAndGetSession(); - - PublishConfig publishConfig = new PublishConfig.Builder().setServiceName( - "ValidName").build(); - DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); - session.publish(publishConfig, discoveryCb, mHandler); - assertTrue("Publish started", - discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED)); - - // 2. request an AWARE network - NetworkCallbackTest networkCb = new NetworkCallbackTest(); - NetworkRequest nr = new NetworkRequest.Builder().addTransportType( - NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier( - session.createNetworkSpecifierOpen( - WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, - mac.toByteArray())).build(); - mConnectivityManager.requestNetwork(nr, networkCb); - assertTrue("OnUnavailable not received", networkCb.waitForOnUnavailable()); - - session.close(); - } - - /** - * Request an Aware data-path (encrypted with Passphrase) as a Responder with an arbitrary peer - * MAC address. - * Validate that receive an onUnavailable() callback. - */ - public void testDataPathPassphraseOutOfBandFail() { - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - MacAddress mac = MacAddress.fromString("00:01:02:03:04:05"); - - // 1. initialize Aware: only purpose is to make sure it is available for OOB data-path - WifiAwareSession session = attachAndGetSession(); - - PublishConfig publishConfig = new PublishConfig.Builder().setServiceName( - "ValidName").build(); - DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); - session.publish(publishConfig, discoveryCb, mHandler); - assertTrue("Publish started", - discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED)); - - // 2. request an AWARE network - NetworkCallbackTest networkCb = new NetworkCallbackTest(); - NetworkRequest nr = new NetworkRequest.Builder().addTransportType( - NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier( - session.createNetworkSpecifierPassphrase( - WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, mac.toByteArray(), - "abcdefghihk")).build(); - mConnectivityManager.requestNetwork(nr, networkCb); - assertTrue("OnUnavailable not received", networkCb.waitForOnUnavailable()); - - session.close(); - } - - /** - * Request an Aware data-path (encrypted with PMK) as a Responder with an arbitrary peer MAC - * address. - * Validate that receive an onUnavailable() callback. - */ - public void testDataPathPmkOutOfBandFail() { - if (!TestUtils.shouldTestWifiAware(getContext())) { - return; - } - MacAddress mac = MacAddress.fromString("00:01:02:03:04:05"); - - // 1. initialize Aware: only purpose is to make sure it is available for OOB data-path - WifiAwareSession session = attachAndGetSession(); - - PublishConfig publishConfig = new PublishConfig.Builder().setServiceName( - "ValidName").build(); - DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest(); - session.publish(publishConfig, discoveryCb, mHandler); - assertTrue("Publish started", - discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED)); - - // 2. request an AWARE network - NetworkCallbackTest networkCb = new NetworkCallbackTest(); - NetworkRequest nr = new NetworkRequest.Builder().addTransportType( - NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier( - session.createNetworkSpecifierPmk( - WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, mac.toByteArray(), - PMK_VALID)).build(); - mConnectivityManager.requestNetwork(nr, networkCb); - assertTrue("OnUnavailable not received", networkCb.waitForOnUnavailable()); - - session.close(); - } - - /** - * Test WifiAwareNetworkSpecifier. - */ - public void testWifiAwareNetworkSpecifier() { - DiscoverySession session = mock(DiscoverySession.class); - PeerHandle handle = mock(PeerHandle.class); - WifiAwareNetworkSpecifier networkSpecifier = - new WifiAwareNetworkSpecifier.Builder(session, handle).build(); - assertFalse(networkSpecifier.satisfiedBy(null)); - assertTrue(networkSpecifier.satisfiedBy(networkSpecifier)); - - WifiAwareNetworkSpecifier anotherNetworkSpecifier = - new WifiAwareNetworkSpecifier.Builder(session, handle).setPmk(PMK_VALID).build(); - assertFalse(networkSpecifier.satisfiedBy(anotherNetworkSpecifier)); - } - - /** - * Test ParcelablePeerHandle parcel. - */ - public void testParcelablePeerHandle() { - PeerHandle peerHandle = mock(PeerHandle.class); - ParcelablePeerHandle parcelablePeerHandle = new ParcelablePeerHandle(peerHandle); - Parcel parcelW = Parcel.obtain(); - parcelablePeerHandle.writeToParcel(parcelW, 0); - byte[] bytes = parcelW.marshall(); - parcelW.recycle(); - - Parcel parcelR = Parcel.obtain(); - parcelR.unmarshall(bytes, 0, bytes.length); - parcelR.setDataPosition(0); - ParcelablePeerHandle rereadParcelablePeerHandle = - ParcelablePeerHandle.CREATOR.createFromParcel(parcelR); - - assertEquals(parcelablePeerHandle, rereadParcelablePeerHandle); - assertEquals(parcelablePeerHandle.hashCode(), rereadParcelablePeerHandle.hashCode()); - } - - // local utilities - - private WifiAwareSession attachAndGetSession() { - AttachCallbackTest attachCb = new AttachCallbackTest(); - mWifiAwareManager.attach(attachCb, mHandler); - int cbCalled = attachCb.waitForAnyCallback(); - assertEquals("Wi-Fi Aware attach", AttachCallbackTest.ATTACHED, cbCalled); - - WifiAwareSession session = attachCb.getSession(); - assertNotNull("Wi-Fi Aware session", session); - - return session; - } -} diff --git a/tests/cts/net/src/android/net/wifi/aware/cts/TestUtils.java b/tests/cts/net/src/android/net/wifi/aware/cts/TestUtils.java deleted file mode 100644 index a12c8bb0d2..0000000000 --- a/tests/cts/net/src/android/net/wifi/aware/cts/TestUtils.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2017 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.wifi.aware.cts; - -import android.content.Context; -import android.content.pm.PackageManager; - -import java.util.Arrays; - -/** - * Test utilities for Wi-Fi Aware CTS test suite. - */ -class TestUtils { - static final String TAG = "WifiAwareCtsTests"; - - /** - * Returns a flag indicating whether or not Wi-Fi Aware should be tested. Wi-Fi Aware - * should be tested if the feature is supported on the current device. - */ - static boolean shouldTestWifiAware(Context context) { - final PackageManager pm = context.getPackageManager(); - return pm.hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE); - } - - /** - * Wraps a byte[] (MAC address representation). Intended to provide hash and equality operators - * so that the MAC address can be used in containers. - */ - static class MacWrapper { - private byte[] mMac; - - MacWrapper(byte[] mac) { - mMac = mac; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (!(o instanceof MacWrapper)) { - return false; - } - - MacWrapper lhs = (MacWrapper) o; - return Arrays.equals(mMac, lhs.mMac); - } - - @Override - public int hashCode() { - return Arrays.hashCode(mMac); - } - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java b/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java deleted file mode 100644 index d91bce8319..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java +++ /dev/null @@ -1,704 +0,0 @@ -/* - * Copyright (C) 2012 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.wifi.cts; - -import static org.junit.Assert.assertNotEquals; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.net.ConnectivityManager; -import android.net.ConnectivityManager.NetworkCallback; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.NetworkInfo; -import android.net.NetworkRequest; -import android.net.wifi.WifiManager; -import android.net.wifi.p2p.WifiP2pDevice; -import android.net.wifi.p2p.WifiP2pGroup; -import android.net.wifi.p2p.WifiP2pGroupList; -import android.net.wifi.p2p.WifiP2pInfo; -import android.net.wifi.p2p.WifiP2pManager; -import android.net.wifi.p2p.nsd.WifiP2pServiceInfo; -import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo; -import android.provider.Settings; -import android.platform.test.annotations.AppModeFull; -import android.test.AndroidTestCase; -import android.util.Log; - -import com.android.compatibility.common.util.ShellIdentityUtils; -import com.android.compatibility.common.util.SystemUtil; - -import java.util.Arrays; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -@AppModeFull(reason = "Cannot get WifiManager in instant app mode") -public class ConcurrencyTest extends AndroidTestCase { - private class MySync { - static final int WIFI_STATE = 0; - static final int P2P_STATE = 1; - static final int DISCOVERY_STATE = 2; - static final int NETWORK_INFO = 3; - - public BitSet pendingSync = new BitSet(); - - public int expectedWifiState; - public int expectedP2pState; - public int expectedDiscoveryState; - public NetworkInfo expectedNetworkInfo; - } - - private class MyResponse { - public boolean valid = false; - - public boolean success; - public int p2pState; - public int discoveryState; - public NetworkInfo networkInfo; - public WifiP2pInfo p2pInfo; - public String deviceName; - public WifiP2pGroupList persistentGroups; - public WifiP2pGroup group = new WifiP2pGroup(); - } - - private WifiManager mWifiManager; - private WifiP2pManager mWifiP2pManager; - private WifiP2pManager.Channel mWifiP2pChannel; - private MySync mMySync = new MySync(); - private MyResponse mMyResponse = new MyResponse(); - private boolean mWasVerboseLoggingEnabled; - - private static final String TAG = "ConcurrencyTest"; - private static final int TIMEOUT_MSEC = 6000; - private static final int WAIT_MSEC = 60; - private static final int DURATION = 10000; - private IntentFilter mIntentFilter; - private final BroadcastReceiver mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - final String action = intent.getAction(); - if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { - synchronized (mMySync) { - mMySync.pendingSync.set(MySync.WIFI_STATE); - mMySync.expectedWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, - WifiManager.WIFI_STATE_DISABLED); - mMySync.notify(); - } - } else if(action.equals(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION)) { - synchronized (mMySync) { - mMySync.pendingSync.set(MySync.P2P_STATE); - mMySync.expectedP2pState = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, - WifiP2pManager.WIFI_P2P_STATE_DISABLED); - mMySync.notify(); - } - } else if (action.equals(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION)) { - synchronized (mMySync) { - mMySync.pendingSync.set(MySync.DISCOVERY_STATE); - mMySync.expectedDiscoveryState = intent.getIntExtra( - WifiP2pManager.EXTRA_DISCOVERY_STATE, - WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED); - mMySync.notify(); - } - } else if (action.equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) { - synchronized (mMySync) { - mMySync.pendingSync.set(MySync.NETWORK_INFO); - mMySync.expectedNetworkInfo = (NetworkInfo) intent.getExtra( - WifiP2pManager.EXTRA_NETWORK_INFO, null); - mMySync.notify(); - } - } - } - }; - - private WifiP2pManager.ActionListener mActionListener = new WifiP2pManager.ActionListener() { - @Override - public void onSuccess() { - synchronized (mMyResponse) { - mMyResponse.valid = true; - mMyResponse.success = true; - mMyResponse.notify(); - } - } - - @Override - public void onFailure(int reason) { - synchronized (mMyResponse) { - Log.d(TAG, "failure reason: " + reason); - mMyResponse.valid = true; - mMyResponse.success = false; - mMyResponse.notify(); - } - } - }; - - @Override - protected void setUp() throws Exception { - super.setUp(); - if (!WifiFeature.isWifiSupported(getContext()) && - !WifiFeature.isP2pSupported(getContext())) { - // skip the test if WiFi && p2p are not supported - return; - } - - mIntentFilter = new IntentFilter(); - mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); - mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); - mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION); - mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); - - mContext.registerReceiver(mReceiver, mIntentFilter); - mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); - assertNotNull(mWifiManager); - if (mWifiManager.isWifiEnabled()) { - SystemUtil.runShellCommand("svc wifi disable"); - Thread.sleep(DURATION); - } - - // turn on verbose logging for tests - mWasVerboseLoggingEnabled = ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.isVerboseLoggingEnabled()); - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.setVerboseLoggingEnabled(true)); - - assertTrue(!mWifiManager.isWifiEnabled()); - mMySync.expectedWifiState = WifiManager.WIFI_STATE_DISABLED; - mMySync.expectedP2pState = WifiP2pManager.WIFI_P2P_STATE_DISABLED; - mMySync.expectedDiscoveryState = WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED; - mMySync.expectedNetworkInfo = null; - } - - @Override - protected void tearDown() throws Exception { - if (!WifiFeature.isWifiSupported(getContext()) && - !WifiFeature.isP2pSupported(getContext())) { - // skip the test if WiFi and p2p are not supported - super.tearDown(); - return; - } - mContext.unregisterReceiver(mReceiver); - - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled)); - - enableWifi(); - super.tearDown(); - } - - private boolean waitForBroadcasts(List waitSyncList) { - synchronized (mMySync) { - long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; - while (System.currentTimeMillis() < timeout) { - List handledSyncList = waitSyncList.stream() - .filter(w -> mMySync.pendingSync.get(w)) - .collect(Collectors.toList()); - handledSyncList.forEach(w -> mMySync.pendingSync.clear(w)); - waitSyncList.removeAll(handledSyncList); - if (waitSyncList.isEmpty()) { - break; - } - try { - mMySync.wait(WAIT_MSEC); - } catch (InterruptedException e) { } - } - if (!waitSyncList.isEmpty()) { - Log.i(TAG, "Missing broadcast: " + waitSyncList); - } - return waitSyncList.isEmpty(); - } - } - - private boolean waitForBroadcasts(int waitSingleSync) { - return waitForBroadcasts( - new LinkedList(Arrays.asList(waitSingleSync))); - } - - private boolean waitForServiceResponse(MyResponse waitResponse) { - synchronized (waitResponse) { - long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; - while (System.currentTimeMillis() < timeout) { - try { - waitResponse.wait(WAIT_MSEC); - } catch (InterruptedException e) { } - - if (waitResponse.valid) { - return true; - } - } - return false; - } - } - - // Return true if location is enabled. - private boolean isLocationEnabled() { - return Settings.Secure.getInt(getContext().getContentResolver(), - Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF) - != Settings.Secure.LOCATION_MODE_OFF; - } - - // Returns true if the device has location feature. - private boolean hasLocationFeature() { - return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION); - } - - private void resetResponse(MyResponse responseObj) { - synchronized (responseObj) { - responseObj.valid = false; - responseObj.networkInfo = null; - responseObj.p2pInfo = null; - responseObj.deviceName = null; - responseObj.persistentGroups = null; - responseObj.group = null; - } - } - - /* - * Enables Wifi and block until connection is established. - */ - private void enableWifi() throws InterruptedException { - if (!mWifiManager.isWifiEnabled()) { - SystemUtil.runShellCommand("svc wifi enable"); - } - - ConnectivityManager cm = - (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkRequest request = - new NetworkRequest.Builder().addTransportType(NetworkCapabilities.TRANSPORT_WIFI) - .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) - .build(); - final CountDownLatch latch = new CountDownLatch(1); - NetworkCallback networkCallback = new NetworkCallback() { - @Override - public void onAvailable(Network network) { - latch.countDown(); - } - }; - cm.registerNetworkCallback(request, networkCallback); - latch.await(DURATION, TimeUnit.MILLISECONDS); - - cm.unregisterNetworkCallback(networkCallback); - } - - private boolean setupWifiP2p() { - // Cannot support p2p alone - if (!WifiFeature.isWifiSupported(getContext())) { - assertTrue(!WifiFeature.isP2pSupported(getContext())); - return false; - } - - if (!WifiFeature.isP2pSupported(getContext())) { - // skip the test if p2p is not supported - return false; - } - - if (!hasLocationFeature()) { - Log.d(TAG, "Skipping test as location is not supported"); - return false; - } - if (!isLocationEnabled()) { - fail("Please enable location for this test - since P-release WiFi Direct" - + " needs Location enabled."); - } - - mWifiP2pManager = - (WifiP2pManager) getContext().getSystemService(Context.WIFI_P2P_SERVICE); - mWifiP2pChannel = mWifiP2pManager.initialize( - getContext(), getContext().getMainLooper(), null); - - assertNotNull(mWifiP2pManager); - assertNotNull(mWifiP2pChannel); - - long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; - while (!mWifiManager.isWifiEnabled() && System.currentTimeMillis() < timeout) { - try { - enableWifi(); - } catch (InterruptedException e) { } - } - - assertTrue(mWifiManager.isWifiEnabled()); - - assertTrue(waitForBroadcasts( - new LinkedList( - Arrays.asList(MySync.WIFI_STATE, MySync.P2P_STATE)))); - - assertEquals(WifiManager.WIFI_STATE_ENABLED, mMySync.expectedWifiState); - assertEquals(WifiP2pManager.WIFI_P2P_STATE_ENABLED, mMySync.expectedP2pState); - - assertTrue(waitForBroadcasts(MySync.NETWORK_INFO)); - // wait for changing to EnabledState - assertNotNull(mMySync.expectedNetworkInfo); - - return true; - } - - public void testConcurrency() { - if (!setupWifiP2p()) { - return; - } - - resetResponse(mMyResponse); - mWifiP2pManager.requestP2pState(mWifiP2pChannel, new WifiP2pManager.P2pStateListener() { - @Override - public void onP2pStateAvailable(int state) { - synchronized (mMyResponse) { - mMyResponse.valid = true; - mMyResponse.p2pState = state; - mMyResponse.notify(); - } - } - }); - assertTrue(waitForServiceResponse(mMyResponse)); - assertEquals(WifiP2pManager.WIFI_P2P_STATE_ENABLED, mMyResponse.p2pState); - } - - public void testRequestDiscoveryState() { - if (!setupWifiP2p()) { - return; - } - - resetResponse(mMyResponse); - mWifiP2pManager.requestDiscoveryState( - mWifiP2pChannel, new WifiP2pManager.DiscoveryStateListener() { - @Override - public void onDiscoveryStateAvailable(int state) { - synchronized (mMyResponse) { - mMyResponse.valid = true; - mMyResponse.discoveryState = state; - mMyResponse.notify(); - } - } - }); - assertTrue(waitForServiceResponse(mMyResponse)); - assertEquals(WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED, mMyResponse.discoveryState); - - resetResponse(mMyResponse); - mWifiP2pManager.discoverPeers(mWifiP2pChannel, mActionListener); - assertTrue(waitForServiceResponse(mMyResponse)); - assertTrue(mMyResponse.success); - assertTrue(waitForBroadcasts(MySync.DISCOVERY_STATE)); - - resetResponse(mMyResponse); - mWifiP2pManager.requestDiscoveryState(mWifiP2pChannel, - new WifiP2pManager.DiscoveryStateListener() { - @Override - public void onDiscoveryStateAvailable(int state) { - synchronized (mMyResponse) { - mMyResponse.valid = true; - mMyResponse.discoveryState = state; - mMyResponse.notify(); - } - } - }); - assertTrue(waitForServiceResponse(mMyResponse)); - assertEquals(WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED, mMyResponse.discoveryState); - - mWifiP2pManager.stopPeerDiscovery(mWifiP2pChannel, null); - } - - public void testRequestNetworkInfo() { - if (!setupWifiP2p()) { - return; - } - - resetResponse(mMyResponse); - mWifiP2pManager.requestNetworkInfo(mWifiP2pChannel, - new WifiP2pManager.NetworkInfoListener() { - @Override - public void onNetworkInfoAvailable(NetworkInfo info) { - synchronized (mMyResponse) { - mMyResponse.valid = true; - mMyResponse.networkInfo = info; - mMyResponse.notify(); - } - } - }); - assertTrue(waitForServiceResponse(mMyResponse)); - assertNotNull(mMyResponse.networkInfo); - // The state might be IDLE, DISCONNECTED, FAILED before a connection establishment. - // Just ensure the state is NOT CONNECTED. - assertNotEquals(NetworkInfo.DetailedState.CONNECTED, - mMySync.expectedNetworkInfo.getDetailedState()); - - resetResponse(mMyResponse); - mWifiP2pManager.createGroup(mWifiP2pChannel, mActionListener); - assertTrue(waitForServiceResponse(mMyResponse)); - assertTrue(mMyResponse.success); - assertTrue(waitForBroadcasts(MySync.NETWORK_INFO)); - assertNotNull(mMySync.expectedNetworkInfo); - assertEquals(NetworkInfo.DetailedState.CONNECTED, - mMySync.expectedNetworkInfo.getDetailedState()); - - resetResponse(mMyResponse); - mWifiP2pManager.requestNetworkInfo(mWifiP2pChannel, - new WifiP2pManager.NetworkInfoListener() { - @Override - public void onNetworkInfoAvailable(NetworkInfo info) { - synchronized (mMyResponse) { - mMyResponse.valid = true; - mMyResponse.networkInfo = info; - mMyResponse.notify(); - } - } - }); - assertTrue(waitForServiceResponse(mMyResponse)); - assertNotNull(mMyResponse.networkInfo); - assertEquals(NetworkInfo.DetailedState.CONNECTED, - mMyResponse.networkInfo.getDetailedState()); - - resetResponse(mMyResponse); - mWifiP2pManager.requestConnectionInfo(mWifiP2pChannel, - new WifiP2pManager.ConnectionInfoListener() { - @Override - public void onConnectionInfoAvailable(WifiP2pInfo info) { - synchronized (mMyResponse) { - mMyResponse.valid = true; - mMyResponse.p2pInfo = new WifiP2pInfo(info); - mMyResponse.notify(); - } - } - }); - assertTrue(waitForServiceResponse(mMyResponse)); - assertNotNull(mMyResponse.p2pInfo); - assertTrue(mMyResponse.p2pInfo.groupFormed); - assertTrue(mMyResponse.p2pInfo.isGroupOwner); - - resetResponse(mMyResponse); - mWifiP2pManager.requestGroupInfo(mWifiP2pChannel, - new WifiP2pManager.GroupInfoListener() { - @Override - public void onGroupInfoAvailable(WifiP2pGroup group) { - synchronized (mMyResponse) { - mMyResponse.group = new WifiP2pGroup(group); - mMyResponse.valid = true; - mMyResponse.notify(); - } - } - }); - assertTrue(waitForServiceResponse(mMyResponse)); - assertNotNull(mMyResponse.group); - assertNotEquals(0, mMyResponse.group.getFrequency()); - assertTrue(mMyResponse.group.getNetworkId() >= 0); - - resetResponse(mMyResponse); - mWifiP2pManager.removeGroup(mWifiP2pChannel, mActionListener); - assertTrue(waitForServiceResponse(mMyResponse)); - assertTrue(mMyResponse.success); - } - - private String getDeviceName() { - resetResponse(mMyResponse); - mWifiP2pManager.requestDeviceInfo(mWifiP2pChannel, - new WifiP2pManager.DeviceInfoListener() { - @Override - public void onDeviceInfoAvailable(WifiP2pDevice wifiP2pDevice) { - synchronized (mMyResponse) { - mMyResponse.deviceName = wifiP2pDevice.deviceName; - mMyResponse.valid = true; - mMyResponse.notify(); - } - } - }); - assertTrue(waitForServiceResponse(mMyResponse)); - return mMyResponse.deviceName; - } - - public void testSetDeviceName() { - if (!setupWifiP2p()) { - return; - } - - String testDeviceName = "test"; - String originalDeviceName = getDeviceName(); - assertNotNull(originalDeviceName); - - ShellIdentityUtils.invokeWithShellPermissions(() -> { - mWifiP2pManager.setDeviceName( - mWifiP2pChannel, testDeviceName, mActionListener); - assertTrue(waitForServiceResponse(mMyResponse)); - assertTrue(mMyResponse.success); - }); - - String currentDeviceName = getDeviceName(); - assertEquals(testDeviceName, currentDeviceName); - - // restore the device name at the end - ShellIdentityUtils.invokeWithShellPermissions(() -> { - mWifiP2pManager.setDeviceName( - mWifiP2pChannel, originalDeviceName, mActionListener); - assertTrue(waitForServiceResponse(mMyResponse)); - assertTrue(mMyResponse.success); - }); - } - - private WifiP2pGroupList getPersistentGroups() { - resetResponse(mMyResponse); - ShellIdentityUtils.invokeWithShellPermissions(() -> { - mWifiP2pManager.requestPersistentGroupInfo(mWifiP2pChannel, - new WifiP2pManager.PersistentGroupInfoListener() { - @Override - public void onPersistentGroupInfoAvailable(WifiP2pGroupList groups) { - synchronized (mMyResponse) { - mMyResponse.persistentGroups = groups; - mMyResponse.valid = true; - mMyResponse.notify(); - } - } - }); - assertTrue(waitForServiceResponse(mMyResponse)); - }); - return mMyResponse.persistentGroups; - } - - public void testPersistentGroupOperation() { - if (!setupWifiP2p()) { - return; - } - - resetResponse(mMyResponse); - mWifiP2pManager.createGroup(mWifiP2pChannel, mActionListener); - assertTrue(waitForServiceResponse(mMyResponse)); - assertTrue(mMyResponse.success); - assertTrue(waitForBroadcasts(MySync.NETWORK_INFO)); - assertNotNull(mMySync.expectedNetworkInfo); - assertEquals(NetworkInfo.DetailedState.CONNECTED, - mMySync.expectedNetworkInfo.getDetailedState()); - - resetResponse(mMyResponse); - mWifiP2pManager.removeGroup(mWifiP2pChannel, mActionListener); - assertTrue(waitForServiceResponse(mMyResponse)); - assertTrue(mMyResponse.success); - - WifiP2pGroupList persistentGroups = getPersistentGroups(); - assertNotNull(persistentGroups); - assertEquals(1, persistentGroups.getGroupList().size()); - - resetResponse(mMyResponse); - final int firstNetworkId = persistentGroups.getGroupList().get(0).getNetworkId(); - ShellIdentityUtils.invokeWithShellPermissions(() -> { - mWifiP2pManager.deletePersistentGroup(mWifiP2pChannel, - firstNetworkId, - mActionListener); - assertTrue(waitForServiceResponse(mMyResponse)); - assertTrue(mMyResponse.success); - }); - - persistentGroups = getPersistentGroups(); - assertNotNull(persistentGroups); - assertEquals(0, persistentGroups.getGroupList().size()); - - resetResponse(mMyResponse); - mWifiP2pManager.createGroup(mWifiP2pChannel, mActionListener); - assertTrue(waitForServiceResponse(mMyResponse)); - assertTrue(mMyResponse.success); - assertTrue(waitForBroadcasts(MySync.NETWORK_INFO)); - assertNotNull(mMySync.expectedNetworkInfo); - assertEquals(NetworkInfo.DetailedState.CONNECTED, - mMySync.expectedNetworkInfo.getDetailedState()); - - resetResponse(mMyResponse); - mWifiP2pManager.removeGroup(mWifiP2pChannel, mActionListener); - assertTrue(waitForServiceResponse(mMyResponse)); - assertTrue(mMyResponse.success); - - resetResponse(mMyResponse); - ShellIdentityUtils.invokeWithShellPermissions(() -> { - mWifiP2pManager.factoryReset(mWifiP2pChannel, mActionListener); - assertTrue(waitForServiceResponse(mMyResponse)); - assertTrue(mMyResponse.success); - }); - - persistentGroups = getPersistentGroups(); - assertNotNull(persistentGroups); - assertEquals(0, persistentGroups.getGroupList().size()); - } - - public void testP2pListening() { - if (!setupWifiP2p()) { - return; - } - - resetResponse(mMyResponse); - ShellIdentityUtils.invokeWithShellPermissions(() -> { - mWifiP2pManager.setWifiP2pChannels(mWifiP2pChannel, 6, 11, mActionListener); - assertTrue(waitForServiceResponse(mMyResponse)); - assertTrue(mMyResponse.success); - }); - - resetResponse(mMyResponse); - ShellIdentityUtils.invokeWithShellPermissions(() -> { - mWifiP2pManager.startListening(mWifiP2pChannel, mActionListener); - assertTrue(waitForServiceResponse(mMyResponse)); - assertTrue(mMyResponse.success); - }); - - resetResponse(mMyResponse); - ShellIdentityUtils.invokeWithShellPermissions(() -> { - mWifiP2pManager.stopListening(mWifiP2pChannel, mActionListener); - assertTrue(waitForServiceResponse(mMyResponse)); - assertTrue(mMyResponse.success); - }); - } - - public void testP2pService() { - if (!setupWifiP2p()) { - return; - } - - // This only store the listener to the WifiP2pManager internal variable, nothing to fail. - mWifiP2pManager.setServiceResponseListener(mWifiP2pChannel, - new WifiP2pManager.ServiceResponseListener() { - @Override - public void onServiceAvailable( - int protocolType, byte[] responseData, WifiP2pDevice srcDevice) { - } - }); - - resetResponse(mMyResponse); - List services = new ArrayList(); - services.add("urn:schemas-upnp-org:service:AVTransport:1"); - services.add("urn:schemas-upnp-org:service:ConnectionManager:1"); - WifiP2pServiceInfo rendererService = WifiP2pUpnpServiceInfo.newInstance( - "6859dede-8574-59ab-9332-123456789011", - "urn:schemas-upnp-org:device:MediaRenderer:1", - services); - mWifiP2pManager.addLocalService(mWifiP2pChannel, - rendererService, - mActionListener); - assertTrue(waitForServiceResponse(mMyResponse)); - assertTrue(mMyResponse.success); - - resetResponse(mMyResponse); - mWifiP2pManager.removeLocalService(mWifiP2pChannel, - rendererService, - mActionListener); - assertTrue(waitForServiceResponse(mMyResponse)); - assertTrue(mMyResponse.success); - - resetResponse(mMyResponse); - mWifiP2pManager.clearLocalServices(mWifiP2pChannel, - mActionListener); - assertTrue(waitForServiceResponse(mMyResponse)); - assertTrue(mMyResponse.success); - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/ConfigParserTest.java b/tests/cts/net/src/android/net/wifi/cts/ConfigParserTest.java deleted file mode 100644 index 52ed2a6d73..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/ConfigParserTest.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2017 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.wifi.cts; - -import android.net.wifi.hotspot2.ConfigParser; -import android.net.wifi.hotspot2.PasspointConfiguration; -import android.net.wifi.hotspot2.pps.Credential; -import android.net.wifi.hotspot2.pps.HomeSp; -import android.test.AndroidTestCase; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.Arrays; - -/** - * CTS tests for Hotspot 2.0 Release 1 installation file parsing API. - */ -public class ConfigParserTest extends AndroidTestCase { - /** - * Hotspot 2.0 Release 1 installation file that contains a Passpoint profile and a - * CA (Certificate Authority) X.509 certificate {@link FakeKeys#CA_CERT0}. - */ - private static final String PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT = - "assets/HSR1ProfileWithCACert.base64"; - - /** - * Read the content of the given resource file into a String. - * - * @param filename String name of the file - * @return String - * @throws IOException - */ - private String loadResourceFile(String filename) throws IOException { - InputStream in = getClass().getClassLoader().getResourceAsStream(filename); - BufferedReader reader = new BufferedReader(new InputStreamReader(in)); - StringBuilder builder = new StringBuilder(); - String line; - while ((line = reader.readLine()) != null) { - builder.append(line).append("\n"); - } - - return builder.toString(); - } - - /** - * Generate a {@link PasspointConfiguration} that matches the configuration specified in the - * XML file {@link #PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT}. - * - * @return {@link PasspointConfiguration} - */ - private PasspointConfiguration generateConfigurationFromProfile() { - PasspointConfiguration config = new PasspointConfiguration(); - - // HomeSP configuration. - HomeSp homeSp = new HomeSp(); - homeSp.setFriendlyName("Century House"); - homeSp.setFqdn("mi6.co.uk"); - homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L}); - config.setHomeSp(homeSp); - - // Credential configuration. - Credential credential = new Credential(); - credential.setRealm("shaken.stirred.com"); - Credential.UserCredential userCredential = new Credential.UserCredential(); - userCredential.setUsername("james"); - userCredential.setPassword("Ym9uZDAwNw=="); - userCredential.setEapType(21); - userCredential.setNonEapInnerMethod("MS-CHAP-V2"); - credential.setUserCredential(userCredential); - Credential.CertificateCredential certCredential = new Credential.CertificateCredential(); - certCredential.setCertType("x509v3"); - byte[] certSha256Fingerprint = new byte[32]; - Arrays.fill(certSha256Fingerprint, (byte)0x1f); - certCredential.setCertSha256Fingerprint(certSha256Fingerprint); - credential.setCertCredential(certCredential); - Credential.SimCredential simCredential = new Credential.SimCredential(); - simCredential.setImsi("imsi"); - simCredential.setEapType(24); - credential.setSimCredential(simCredential); - credential.setCaCertificate(FakeKeys.CA_CERT0); - config.setCredential(credential); - return config; - } - - /** - * Verify a valid installation file is parsed successfully with the matching contents. - * - * @throws Exception - */ - public void testParseConfigFile() throws Exception { - String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT); - PasspointConfiguration expectedConfig = generateConfigurationFromProfile(); - PasspointConfiguration actualConfig = - ConfigParser.parsePasspointConfig( - "application/x-wifi-config", configStr.getBytes()); - assertTrue(actualConfig.equals(expectedConfig)); - } -} \ No newline at end of file diff --git a/tests/cts/net/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java b/tests/cts/net/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java deleted file mode 100644 index 9624dd7c4d..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java +++ /dev/null @@ -1,345 +0,0 @@ -/* - * 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.wifi.cts; - -import static android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_FAILURE; -import static android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_NO_PROBE; -import static android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_SUCCESS; -import static android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_UNKNOWN; - -import static com.google.common.truth.Truth.assertThat; - -import android.app.UiAutomation; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiManager; -import android.net.wifi.WifiUsabilityStatsEntry; -import android.support.test.uiautomator.UiDevice; -import android.telephony.TelephonyManager; -import android.test.AndroidTestCase; - -import androidx.test.platform.app.InstrumentationRegistry; - -import com.android.compatibility.common.util.PollingCheck; -import com.android.compatibility.common.util.ShellIdentityUtils; -import com.android.compatibility.common.util.SystemUtil; - -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - -public class ConnectedNetworkScorerTest extends AndroidTestCase { - private WifiManager mWifiManager; - private UiDevice mUiDevice; - private boolean mWasVerboseLoggingEnabled; - - private static final int DURATION = 10_000; - private static final int DURATION_SCREEN_TOGGLE = 2000; - - @Override - protected void setUp() throws Exception { - super.setUp(); - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - mWifiManager = getContext().getSystemService(WifiManager.class); - assertThat(mWifiManager).isNotNull(); - - // turn on verbose logging for tests - mWasVerboseLoggingEnabled = ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.isVerboseLoggingEnabled()); - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.setVerboseLoggingEnabled(true)); - - if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true); - mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); - turnScreenOn(); - PollingCheck.check("Wifi not enabled", DURATION, () -> mWifiManager.isWifiEnabled()); - List savedNetworks = ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.getConfiguredNetworks()); - assertFalse("Need at least one saved network", savedNetworks.isEmpty()); - // Wait for wifi is to be connected - PollingCheck.check( - "Wifi not connected", - DURATION, - () -> mWifiManager.getConnectionInfo().getNetworkId() != -1); - assertThat(mWifiManager.getConnectionInfo().getNetworkId()).isNotEqualTo(-1); - } - - @Override - protected void tearDown() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - super.tearDown(); - return; - } - if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true); - turnScreenOff(); - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled)); - super.tearDown(); - } - - private void setWifiEnabled(boolean enable) throws Exception { - // now trigger the change using shell commands. - SystemUtil.runShellCommand("svc wifi " + (enable ? "enable" : "disable")); - } - - private void turnScreenOn() throws Exception { - mUiDevice.executeShellCommand("input keyevent KEYCODE_WAKEUP"); - mUiDevice.executeShellCommand("wm dismiss-keyguard"); - // Since the screen on/off intent is ordered, they will not be sent right now. - Thread.sleep(DURATION_SCREEN_TOGGLE); - } - - private void turnScreenOff() throws Exception { - mUiDevice.executeShellCommand("input keyevent KEYCODE_SLEEP"); - } - - private static class TestUsabilityStatsListener implements - WifiManager.OnWifiUsabilityStatsListener { - private final CountDownLatch mCountDownLatch; - public int seqNum; - public boolean isSameBssidAndFre; - public WifiUsabilityStatsEntry statsEntry; - - TestUsabilityStatsListener(CountDownLatch countDownLatch) { - mCountDownLatch = countDownLatch; - } - - @Override - public void onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq, - WifiUsabilityStatsEntry statsEntry) { - this.seqNum = seqNum; - this.isSameBssidAndFre = isSameBssidAndFreq; - this.statsEntry = statsEntry; - mCountDownLatch.countDown(); - } - } - - /** - * Tests the {@link android.net.wifi.WifiUsabilityStatsEntry} retrieved from - * {@link WifiManager.OnWifiUsabilityStatsListener}. - */ - public void testWifiUsabilityStatsEntry() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - CountDownLatch countDownLatch = new CountDownLatch(1); - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - TestUsabilityStatsListener usabilityStatsListener = - new TestUsabilityStatsListener(countDownLatch); - try { - uiAutomation.adoptShellPermissionIdentity(); - mWifiManager.addOnWifiUsabilityStatsListener( - Executors.newSingleThreadExecutor(), usabilityStatsListener); - // Wait for new usability stats (while connected & screen on this is triggered - // by platform periodically). - assertThat(countDownLatch.await(DURATION, TimeUnit.MILLISECONDS)).isTrue(); - - assertThat(usabilityStatsListener.statsEntry).isNotNull(); - WifiUsabilityStatsEntry statsEntry = usabilityStatsListener.statsEntry; - - assertThat(statsEntry.getTimeStampMillis()).isGreaterThan(0L); - assertThat(statsEntry.getRssi()).isLessThan(0); - assertThat(statsEntry.getLinkSpeedMbps()).isGreaterThan(0); - assertThat(statsEntry.getTotalTxSuccess()).isGreaterThan(0L); - assertThat(statsEntry.getTotalTxRetries()).isAtLeast(0L); - assertThat(statsEntry.getTotalTxBad()).isAtLeast(0L); - assertThat(statsEntry.getTotalRxSuccess()).isAtLeast(0L); - assertThat(statsEntry.getTotalRadioOnTimeMillis()).isGreaterThan(0L); - assertThat(statsEntry.getTotalRadioTxTimeMillis()).isGreaterThan(0L); - assertThat(statsEntry.getTotalRadioRxTimeMillis()).isGreaterThan(0L); - assertThat(statsEntry.getTotalScanTimeMillis()).isGreaterThan(0L); - assertThat(statsEntry.getTotalNanScanTimeMillis()).isAtLeast(0L); - assertThat(statsEntry.getTotalBackgroundScanTimeMillis()).isAtLeast(0L); - assertThat(statsEntry.getTotalRoamScanTimeMillis()).isAtLeast(0L); - assertThat(statsEntry.getTotalPnoScanTimeMillis()).isAtLeast(0L); - assertThat(statsEntry.getTotalHotspot2ScanTimeMillis()).isAtLeast(0L); - assertThat(statsEntry.getTotalCcaBusyFreqTimeMillis()).isAtLeast(0L); - assertThat(statsEntry.getTotalRadioOnTimeMillis()).isGreaterThan(0L); - assertThat(statsEntry.getTotalRadioOnFreqTimeMillis()).isGreaterThan(0L); - assertThat(statsEntry.getTotalBeaconRx()).isGreaterThan(0L); - assertThat(statsEntry.getProbeStatusSinceLastUpdate()) - .isAnyOf(PROBE_STATUS_SUCCESS, - PROBE_STATUS_FAILURE, - PROBE_STATUS_NO_PROBE, - PROBE_STATUS_UNKNOWN); - // -1 is default value for some of these fields if they're not available. - assertThat(statsEntry.getProbeElapsedTimeSinceLastUpdateMillis()).isAtLeast(-1); - assertThat(statsEntry.getProbeMcsRateSinceLastUpdate()).isAtLeast(-1); - assertThat(statsEntry.getRxLinkSpeedMbps()).isAtLeast(-1); - // no longer populated, return default value. - assertThat(statsEntry.getCellularDataNetworkType()) - .isAnyOf(TelephonyManager.NETWORK_TYPE_UNKNOWN, - TelephonyManager.NETWORK_TYPE_GPRS, - TelephonyManager.NETWORK_TYPE_EDGE, - TelephonyManager.NETWORK_TYPE_UMTS, - TelephonyManager.NETWORK_TYPE_CDMA, - TelephonyManager.NETWORK_TYPE_EVDO_0, - TelephonyManager.NETWORK_TYPE_EVDO_A, - TelephonyManager.NETWORK_TYPE_1xRTT, - TelephonyManager.NETWORK_TYPE_HSDPA, - TelephonyManager.NETWORK_TYPE_HSUPA, - TelephonyManager.NETWORK_TYPE_HSPA, - TelephonyManager.NETWORK_TYPE_IDEN, - TelephonyManager.NETWORK_TYPE_EVDO_B, - TelephonyManager.NETWORK_TYPE_LTE, - TelephonyManager.NETWORK_TYPE_EHRPD, - TelephonyManager.NETWORK_TYPE_HSPAP, - TelephonyManager.NETWORK_TYPE_GSM, - TelephonyManager.NETWORK_TYPE_TD_SCDMA, - TelephonyManager.NETWORK_TYPE_IWLAN, - TelephonyManager.NETWORK_TYPE_NR); - assertThat(statsEntry.getCellularSignalStrengthDbm()).isAtMost(0); - assertThat(statsEntry.getCellularSignalStrengthDb()).isAtMost(0); - assertThat(statsEntry.isSameRegisteredCell()).isFalse(); - } finally { - mWifiManager.removeOnWifiUsabilityStatsListener(usabilityStatsListener); - uiAutomation.dropShellPermissionIdentity(); - } - } - - /** - * Tests the {@link android.net.wifi.WifiManager#updateWifiUsabilityScore(int, int, int)} - */ - public void testUpdateWifiUsabilityScore() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - try { - uiAutomation.adoptShellPermissionIdentity(); - // update scoring with dummy values. - mWifiManager.updateWifiUsabilityScore(0, 50, 50); - } finally { - uiAutomation.dropShellPermissionIdentity(); - } - } - - private static class TestConnectedNetworkScorer implements - WifiManager.WifiConnectedNetworkScorer { - private CountDownLatch mCountDownLatch; - public int startSessionId; - public int stopSessionId; - public WifiManager.ScoreUpdateObserver scoreUpdateObserver; - - TestConnectedNetworkScorer(CountDownLatch countDownLatch) { - mCountDownLatch = countDownLatch; - } - - @Override - public void onStart(int sessionId) { - synchronized (mCountDownLatch) { - this.startSessionId = sessionId; - mCountDownLatch.countDown(); - } - } - - @Override - public void onStop(int sessionId) { - synchronized (mCountDownLatch) { - this.stopSessionId = sessionId; - mCountDownLatch.countDown(); - } - } - - @Override - public void onSetScoreUpdateObserver(WifiManager.ScoreUpdateObserver observerImpl) { - this.scoreUpdateObserver = observerImpl; - } - - public void resetCountDownLatch(CountDownLatch countDownLatch) { - synchronized (mCountDownLatch) { - mCountDownLatch = countDownLatch; - } - } - } - - /** - * Tests the {@link android.net.wifi.WifiConnectedNetworkScorer} interface. - * - * Note: We could write more interesting test cases (if the device has a mobile connection), but - * that would make the test flaky. The default network/route selection on the device is not just - * controlled by the wifi scorer input, but also based on params which are controlled by - * other parts of the platform (likely in connectivity service) and hence will behave - * differently on OEM devices. - */ - public void testSetWifiConnectedNetworkScorer() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - CountDownLatch countDownLatchScorer = new CountDownLatch(1); - CountDownLatch countDownLatchUsabilityStats = new CountDownLatch(1); - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - TestConnectedNetworkScorer connectedNetworkScorer = - new TestConnectedNetworkScorer(countDownLatchScorer); - TestUsabilityStatsListener usabilityStatsListener = - new TestUsabilityStatsListener(countDownLatchUsabilityStats); - try { - uiAutomation.adoptShellPermissionIdentity(); - mWifiManager.setWifiConnectedNetworkScorer( - Executors.newSingleThreadExecutor(), connectedNetworkScorer); - // Since we're already connected, wait for onStart to be invoked. - assertThat(countDownLatchScorer.await(DURATION, TimeUnit.MILLISECONDS)).isTrue(); - - assertThat(connectedNetworkScorer.startSessionId).isAtLeast(0); - assertThat(connectedNetworkScorer.scoreUpdateObserver).isNotNull(); - WifiManager.ScoreUpdateObserver scoreUpdateObserver = - connectedNetworkScorer.scoreUpdateObserver; - - // Now trigger a dummy score update. - scoreUpdateObserver.notifyScoreUpdate(connectedNetworkScorer.startSessionId, 50); - - // Register the usability listener - mWifiManager.addOnWifiUsabilityStatsListener( - Executors.newSingleThreadExecutor(), usabilityStatsListener); - // Trigger a usability stats update. - scoreUpdateObserver.triggerUpdateOfWifiUsabilityStats( - connectedNetworkScorer.startSessionId); - // Ensure that we got the stats update callback. - assertThat(countDownLatchUsabilityStats.await(DURATION, TimeUnit.MILLISECONDS)) - .isTrue(); - assertThat(usabilityStatsListener.seqNum).isAtLeast(0); - - // Reset the scorer countdown latch for onStop - countDownLatchScorer = new CountDownLatch(1); - connectedNetworkScorer.resetCountDownLatch(countDownLatchScorer); - // Now disconnect from the network. - mWifiManager.disconnect(); - // Wait for it to be disconnected. - PollingCheck.check( - "Wifi not disconnected", - DURATION, - () -> mWifiManager.getConnectionInfo().getNetworkId() == -1); - assertThat(mWifiManager.getConnectionInfo().getNetworkId()).isEqualTo(-1); - - // Wait for stop to be invoked and ensure that the session id matches. - assertThat(countDownLatchScorer.await(DURATION, TimeUnit.MILLISECONDS)).isTrue(); - assertThat(connectedNetworkScorer.stopSessionId) - .isEqualTo(connectedNetworkScorer.startSessionId); - } finally { - mWifiManager.removeOnWifiUsabilityStatsListener(usabilityStatsListener); - mWifiManager.clearWifiConnectedNetworkScorer(); - uiAutomation.dropShellPermissionIdentity(); - } - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/EasyConnectStatusCallbackTest.java b/tests/cts/net/src/android/net/wifi/cts/EasyConnectStatusCallbackTest.java deleted file mode 100644 index eef50a0059..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/EasyConnectStatusCallbackTest.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * 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.wifi.cts; - -import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_TIMEOUT; -import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_PSK; -import static android.net.wifi.WifiManager.EASY_CONNECT_NETWORK_ROLE_STA; - -import android.app.UiAutomation; -import android.content.Context; -import android.net.wifi.EasyConnectStatusCallback; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiManager; -import android.os.Handler; -import android.os.HandlerExecutor; -import android.os.HandlerThread; -import android.test.AndroidTestCase; -import android.util.SparseArray; -import androidx.test.platform.app.InstrumentationRegistry; - -import java.util.concurrent.Executor; - -public class EasyConnectStatusCallbackTest extends AndroidTestCase { - private static final String TEST_SSID = "\"testSsid\""; - private static final String TEST_PASSPHRASE = "\"testPassword\""; - private static final int TEST_WAIT_DURATION_MS = 12_000; // Long delay is necessary, see below - private WifiManager mWifiManager; - private static final String TEST_DPP_URI = - "DPP:C:81/1;I:Easy_Connect_Demo;M:000102030405;" - + "K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgACDmtXD1Sz6/5B4YRdmTkbkkFLDwk8f0yRnfm1Go" - + "kpx/0=;;"; - private final HandlerThread mHandlerThread = new HandlerThread("EasyConnectTest"); - protected final Executor mExecutor; - { - mHandlerThread.start(); - mExecutor = new HandlerExecutor(new Handler(mHandlerThread.getLooper())); - } - private final Object mLock = new Object(); - private boolean mOnFailureCallback = false; - private int mErrorCode; - - @Override - protected void setUp() throws Exception { - super.setUp(); - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - - mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - } - - private EasyConnectStatusCallback mEasyConnectStatusCallback = new EasyConnectStatusCallback() { - @Override - public void onEnrolleeSuccess(int newNetworkId) { - - } - - @Override - public void onConfiguratorSuccess(int code) { - - } - - @Override - public void onProgress(int code) { - - } - - @Override - public void onFailure(int code) { - synchronized (mLock) { - mOnFailureCallback = true; - mErrorCode = code; - mLock.notify(); - } - } - - public void onFailure(int code, String ssid, SparseArray channelListArray, - int[] operatingClassArray) { - synchronized (mLock) { - mOnFailureCallback = true; - mErrorCode = code; - mLock.notify(); - } - } - }; - - /** - * Tests {@link android.net.wifi.EasyConnectStatusCallback} class. - * - * Since Easy Connect requires 2 devices, start Easy Connect session and expect an error. - */ - public void testConfiguratorInitiatorOnFailure() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - try { - uiAutomation.adoptShellPermissionIdentity(); - WifiConfiguration config; - config = new WifiConfiguration(); - config.SSID = TEST_SSID; - config.preSharedKey = TEST_PASSPHRASE; - config.setSecurityParams(SECURITY_TYPE_PSK); - int networkId = mWifiManager.addNetwork(config); - assertFalse(networkId == -1); - synchronized (mLock) { - mWifiManager.startEasyConnectAsConfiguratorInitiator(TEST_DPP_URI, networkId, - EASY_CONNECT_NETWORK_ROLE_STA, mExecutor, mEasyConnectStatusCallback); - // Note: A long delay is necessary because there is no enrollee, and the system - // tries to discover it. We will wait for a timeout error to occur. - mLock.wait(TEST_WAIT_DURATION_MS); - } - mWifiManager.removeNetwork(networkId); - assertTrue(mOnFailureCallback); - assertEquals(EASY_CONNECT_EVENT_FAILURE_TIMEOUT, mErrorCode); - mWifiManager.stopEasyConnectSession(); - } finally { - uiAutomation.dropShellPermissionIdentity(); - } - } - - /** - * Tests {@link android.net.wifi.EasyConnectStatusCallback} class. - * - * Since Easy Connect requires 2 devices, start Easy Connect session and expect an error. - */ - public void testEnrolleeInitiatorOnFailure() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - try { - uiAutomation.adoptShellPermissionIdentity(); - synchronized (mLock) { - mWifiManager.startEasyConnectAsEnrolleeInitiator(TEST_DPP_URI, mExecutor, - mEasyConnectStatusCallback); - // Note: A long delay is necessary because there is no configurator, and the system - // tries to discover it. We will wait for a timeout error to occur. - mLock.wait(TEST_WAIT_DURATION_MS); - } - assertTrue(mOnFailureCallback); - assertEquals(EASY_CONNECT_EVENT_FAILURE_TIMEOUT, mErrorCode); - mWifiManager.stopEasyConnectSession(); - } finally { - uiAutomation.dropShellPermissionIdentity(); - } - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/FakeKeys.java b/tests/cts/net/src/android/net/wifi/cts/FakeKeys.java deleted file mode 100644 index f8753017db..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/FakeKeys.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (C) 2016 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.wifi.cts; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; - -/** - * A class containing test certificates and private keys. - */ -public class FakeKeys { - private static final String CA_CERT0_STRING = "-----BEGIN CERTIFICATE-----\n" + - "MIIDKDCCAhCgAwIBAgIJAILlFdwzLVurMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV\n" + - "BAMTB0VBUCBDQTEwHhcNMTYwMTEyMTE1MDE1WhcNMjYwMTA5MTE1MDE1WjASMRAw\n" + - "DgYDVQQDEwdFQVAgQ0ExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n" + - "znAPUz26Msae4ws43czR41/J2QtrSIZUKmVUsVumDbYHrPNvTXKSMXAcewORDQYX\n" + - "RqvHvpn8CscB1+oGXZvHwxj4zV0WKoK2zeXkau3vcyl3HIKupJfq2TEACefVjj0t\n" + - "JW+X35PGWp9/H5zIUNVNVjS7Ums84IvKhRB8512PB9UyHagXYVX5GWpAcVpyfrlR\n" + - "FI9Qdhh+Pbk0uyktdbf/CdfgHOoebrTtwRljM0oDtX+2Cv6j0wBK7hD8pPvf1+uy\n" + - "GzczigAU/4Kw7eZqydf9B+5RupR+IZipX41xEiIrKRwqi517WWzXcjaG2cNbf451\n" + - "xpH5PnV3i1tq04jMGQUzFwIDAQABo4GAMH4wHQYDVR0OBBYEFIwX4vs8BiBcScod\n" + - "5noZHRM8E4+iMEIGA1UdIwQ7MDmAFIwX4vs8BiBcScod5noZHRM8E4+ioRakFDAS\n" + - "MRAwDgYDVQQDEwdFQVAgQ0ExggkAguUV3DMtW6swDAYDVR0TBAUwAwEB/zALBgNV\n" + - "HQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAFfQqOTA7Rv7K+luQ7pnas4BYwHE\n" + - "9GEP/uohv6KOy0TGQFbrRTjFoLVNB9BZ1ymMDZ0/TIwIUc7wi7a8t5mEqYH153wW\n" + - "aWooiSjyLLhuI4sNrNCOtisdBq2r2MFXt6h0mAQYOPv8R8K7/fgSxGFqzhyNmmVL\n" + - "1qBJldx34SpwsTALQVPb4hGwJzZfr1PcpEQx6xMnTl8xEWZE3Ms99uaUxbQqIwRu\n" + - "LgAOkNCmY2m89VhzaHJ1uV85AdM/tD+Ysmlnnjt9LRCejbBipjIGjOXrg1JP+lxV\n" + - "muM4vH+P/mlmxsPPz0d65b+EGmJZpoLkO/tdNNvCYzjJpTEWpEsO6NMhKYo=\n" + - "-----END CERTIFICATE-----\n"; - public static final X509Certificate CA_CERT0 = loadCertificate(CA_CERT0_STRING); - - private static final String CA_CERT1_STRING = "-----BEGIN CERTIFICATE-----\n" + - "MIIDKDCCAhCgAwIBAgIJAOM5SzKO2pzCMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV\n" + - "BAMTB0VBUCBDQTAwHhcNMTYwMTEyMDAxMDQ3WhcNMjYwMTA5MDAxMDQ3WjASMRAw\n" + - "DgYDVQQDEwdFQVAgQ0EwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n" + - "89ug+IEKVQXnJGKg5g4uVHg6J/8iRUxR5k2eH5o03hrJNMfN2D+cBe/wCiZcnWbI\n" + - "GbGZACWm2nQth2wy9Zgm2LOd3b4ocrHYls3XLq6Qb5Dd7a0JKU7pdGufiNVEkrmF\n" + - "EB+N64wgwH4COTvCiN4erp5kyJwkfqAl2xLkZo0C464c9XoyQOXbmYD9A8v10wZu\n" + - "jyNsEo7Nr2USyw+qhjWSbFbEirP77Tvx+7pJQJwdtk1V9Tn73T2dGF2WHYejei9S\n" + - "mcWpdIUqsu9etYH+zDmtu7I1xlkwiaVsNr2+D+qaCJyOYqrDTKVNK5nmbBPXDWZc\n" + - "NoDbTOoqquX7xONpq9M6jQIDAQABo4GAMH4wHQYDVR0OBBYEFAZ3A2S4qJZZwuNY\n" + - "wkJ6mAdc0gVdMEIGA1UdIwQ7MDmAFAZ3A2S4qJZZwuNYwkJ6mAdc0gVdoRakFDAS\n" + - "MRAwDgYDVQQDEwdFQVAgQ0EwggkA4zlLMo7anMIwDAYDVR0TBAUwAwEB/zALBgNV\n" + - "HQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAHmdMwEhtys4d0E+t7owBmoVR+lU\n" + - "hMCcRtWs8YKX5WIM2kTweT0h/O1xwE1mWmRv/IbDAEb8od4BjAQLhIcolStr2JaO\n" + - "9ZzyxjOnNzqeErh/1DHDbb/moPpqfeJ8YiEz7nH/YU56Q8iCPO7TsgS0sNNE7PfN\n" + - "IUsBW0yHRgpQ4OxWmiZG2YZWiECRzAC0ecPzo59N5iH4vLQIMTMYquiDeMPQnn1e\n" + - "NDGxG8gCtDKIaS6tMg3a28MvWB094pr2ETou8O1C8Ji0Y4hE8QJmSdT7I4+GZjgW\n" + - "g94DZ5RiL7sdp3vC48CXOmeT61YBIvhGUsE1rPhXqkpqQ3Z3C4TFF0jXZZc=\n" + - "-----END CERTIFICATE-----\n"; - public static final X509Certificate CA_CERT1 = loadCertificate(CA_CERT1_STRING); - - private static final String CA_PUBLIC_CERT_STRING = "-----BEGIN CERTIFICATE-----\n" + - "MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx\n" + - "GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds\n" + - "b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV\n" + - "BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD\n" + - "VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa\n" + - "DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc\n" + - "THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb\n" + - "Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP\n" + - "c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX\n" + - "gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV\n" + - "HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF\n" + - "AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj\n" + - "Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG\n" + - "j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH\n" + - "hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC\n" + - "X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==\n" + - "-----END CERTIFICATE-----\n"; - public static final X509Certificate CA_PUBLIC_CERT = loadCertificate(CA_PUBLIC_CERT_STRING); - - private static final String CLIENT_CERT_STR = "-----BEGIN CERTIFICATE-----\n" + - "MIIE/DCCAuQCAQEwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxCzAJBgNV\n" + - "BAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdUZXN0aW5n\n" + - "MB4XDTE2MDkzMDIwNTQyOFoXDTE3MDkzMDIwNTQyOFowRDELMAkGA1UEBhMCVVMx\n" + - "CzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdU\n" + - "ZXN0aW5nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnpmcbuaeHfnJ\n" + - "k+2QNvxmdVFTawyFMNk0USCq5sexscwmxbewG/Rb8YnixwJWS44v2XkSujB67z5C\n" + - "s2qudFEhRXKdEuC6idbAuA97KjipHh0AAniWMsyv61fvbgsUC0b0canx3LiDq81p\n" + - "y28NNGmAvoazLZUZ4AhBRiwYZY6FKk723gmZoGbEIeG7J1dlXPusc1662rIjz4eU\n" + - "zlmmlvqyHfNqnNk8L14Vug6Xh+lOEGN85xhu1YHAEKGrS89kZxs5rum/cZU8KH2V\n" + - "v6eKnY03kxjiVLQtnLpm/7VUEoCMGHyruRj+p3my4+DgqMsmsH52RZCBsjyGlpbU\n" + - "NOwOTIX6xh+Rqloduz4AnrMYYIiIw2s8g+2zJM7VbcVKx0fGS26BKdrxgrXWfmNE\n" + - "nR0/REQ5AxDGw0jfTUvtdTkXAf+K4MDjcNLEZ+MA4rHfAfQWZtUR5BkHCQYxNpJk\n" + - "pA0gyk+BpKdC4WdzI14NSWsu5sRCmBCFqH6BTOSEq/V1cNorBxNwLSSTwFFqUDqx\n" + - "Y5nQLXygkJf9WHZWtSKeSjtOYgilz7UKzC2s3CsjmIyGFe+SwpuHJnuE4Uc8Z5Cb\n" + - "bjNGHPzqL6XnmzZHJp7RF8kBdKdjGC7dCUltzOfICZeKlzOOq+Kw42T/nXjuXvpb\n" + - "nkXNxg741Nwd6RecykXJbseFwm3EYxkCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEA\n" + - "Ga1mGwI9aXkL2fTPXO9YkAPzoGeX8aeuVYSQaSkNq+5vnogYCyAt3YDHjRG+ewTT\n" + - "WbnPA991xRAPac+biJeXWmwvgGj0YuT7e79phAiGkTTnbAjFHGfYnBy/tI/v7btO\n" + - "hRNElA5yTJ1m2fVbBEKXzMR83jrT9iyI+YLRN86zUZIaC86xxSbqnrdWN2jOK6MX\n" + - "dS8Arp9tPQjC/4gW+2Ilxv68jiYh+5auWHQZVjppWVY//iu4mAbkq1pTwQEhZ8F8\n" + - "Zrmh9DHh60hLFcfSuhIAwf/NMzppwdkjy1ruKVrpijhGKGp4OWu8nvOUgHSzxc7F\n" + - "PwpVZ5N2Ku4L8MLO6BG2VasRJK7l17TzDXlfLZHJjkuryOFxVaQKt8ZNFgTOaCXS\n" + - "E+gpTLksKU7riYckoiP4+H1sn9qcis0e8s4o/uf1UVc8GSdDw61ReGM5oZEDm1u8\n" + - "H9x20QU6igLqzyBpqvCKv7JNgU1uB2PAODHH78zJiUfnKd1y+o+J1iWzaGj3EFji\n" + - "T8AXksbTP733FeFXfggXju2dyBH+Z1S5BBTEOd1brWgXlHSAZGm97MKZ94r6/tkX\n" + - "qfv3fCos0DKz0oV7qBxYS8wiYhzrRVxG6ITAoH8uuUVVQaZF+G4nJ2jEqNbfuKyX\n" + - "ATQsVNjNNlDA0J33GobPMjT326wa4YAWMx8PI5PJZ3g=\n" + - "-----END CERTIFICATE-----\n"; - public static final X509Certificate CLIENT_CERT = loadCertificate(CLIENT_CERT_STR); - - private static final byte[] FAKE_RSA_KEY_1 = new byte[] { - (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x02, (byte) 0x01, - (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, - (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, - (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82, - (byte) 0x02, (byte) 0x62, (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5e, - (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81, - (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6, (byte) 0x5b, - (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c, (byte) 0x66, - (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86, (byte) 0x8a, - (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3, (byte) 0x02, - (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08, (byte) 0xf3, - (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04, (byte) 0x6d, - (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f, (byte) 0x67, - (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c, (byte) 0xcb, - (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30, (byte) 0xe2, - (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5, (byte) 0x79, - (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b, (byte) 0xce, - (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb, (byte) 0x08, - (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff, (byte) 0x3b, - (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9, (byte) 0xc4, - (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29, (byte) 0x0d, - (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b, (byte) 0x23, - (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78, (byte) 0x08, - (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5, (byte) 0xf1, - (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19, (byte) 0xb4, - (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03, (byte) 0x16, - (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce, (byte) 0x9e, - (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03, (byte) 0x01, - (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x16, - (byte) 0x59, (byte) 0xc3, (byte) 0x24, (byte) 0x1d, (byte) 0x33, (byte) 0x98, - (byte) 0x9c, (byte) 0xc9, (byte) 0xc8, (byte) 0x2c, (byte) 0x88, (byte) 0xbf, - (byte) 0x0a, (byte) 0x01, (byte) 0xce, (byte) 0xfb, (byte) 0x34, (byte) 0x7a, - (byte) 0x58, (byte) 0x7a, (byte) 0xb0, (byte) 0xbf, (byte) 0xa6, (byte) 0xb2, - (byte) 0x60, (byte) 0xbe, (byte) 0x70, (byte) 0x21, (byte) 0xf5, (byte) 0xfc, - (byte) 0x85, (byte) 0x0d, (byte) 0x33, (byte) 0x58, (byte) 0xa1, (byte) 0xe5, - (byte) 0x09, (byte) 0x36, (byte) 0x84, (byte) 0xb2, (byte) 0x04, (byte) 0x0a, - (byte) 0x02, (byte) 0xd3, (byte) 0x88, (byte) 0x1f, (byte) 0x0c, (byte) 0x2b, - (byte) 0x1d, (byte) 0xe9, (byte) 0x3d, (byte) 0xe7, (byte) 0x79, (byte) 0xf9, - (byte) 0x32, (byte) 0x5c, (byte) 0x8a, (byte) 0x75, (byte) 0x49, (byte) 0x12, - (byte) 0xe4, (byte) 0x05, (byte) 0x26, (byte) 0xd4, (byte) 0x2e, (byte) 0x9e, - (byte) 0x1f, (byte) 0xcc, (byte) 0x54, (byte) 0xad, (byte) 0x33, (byte) 0x8d, - (byte) 0x99, (byte) 0x00, (byte) 0xdc, (byte) 0xf5, (byte) 0xb4, (byte) 0xa2, - (byte) 0x2f, (byte) 0xba, (byte) 0xe5, (byte) 0x62, (byte) 0x30, (byte) 0x6d, - (byte) 0xe6, (byte) 0x3d, (byte) 0xeb, (byte) 0x24, (byte) 0xc2, (byte) 0xdc, - (byte) 0x5f, (byte) 0xb7, (byte) 0x16, (byte) 0x35, (byte) 0xa3, (byte) 0x98, - (byte) 0x98, (byte) 0xa8, (byte) 0xef, (byte) 0xe8, (byte) 0xc4, (byte) 0x96, - (byte) 0x6d, (byte) 0x38, (byte) 0xab, (byte) 0x26, (byte) 0x6d, (byte) 0x30, - (byte) 0xc2, (byte) 0xa0, (byte) 0x44, (byte) 0xe4, (byte) 0xff, (byte) 0x7e, - (byte) 0xbe, (byte) 0x7c, (byte) 0x33, (byte) 0xa5, (byte) 0x10, (byte) 0xad, - (byte) 0xd7, (byte) 0x1e, (byte) 0x13, (byte) 0x20, (byte) 0xb3, (byte) 0x1f, - (byte) 0x41, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xf1, (byte) 0x89, - (byte) 0x07, (byte) 0x0f, (byte) 0xe8, (byte) 0xcf, (byte) 0xab, (byte) 0x13, - (byte) 0x2a, (byte) 0x8f, (byte) 0x88, (byte) 0x80, (byte) 0x11, (byte) 0x9a, - (byte) 0x79, (byte) 0xb6, (byte) 0x59, (byte) 0x3a, (byte) 0x50, (byte) 0x6e, - (byte) 0x57, (byte) 0x37, (byte) 0xab, (byte) 0x2a, (byte) 0xd2, (byte) 0xaa, - (byte) 0xd9, (byte) 0x72, (byte) 0x73, (byte) 0xff, (byte) 0x8b, (byte) 0x47, - (byte) 0x76, (byte) 0xdd, (byte) 0xdc, (byte) 0xf5, (byte) 0x97, (byte) 0x44, - (byte) 0x3a, (byte) 0x78, (byte) 0xbe, (byte) 0x17, (byte) 0xb4, (byte) 0x22, - (byte) 0x6f, (byte) 0xe5, (byte) 0x23, (byte) 0x70, (byte) 0x1d, (byte) 0x10, - (byte) 0x5d, (byte) 0xba, (byte) 0x16, (byte) 0x81, (byte) 0xf1, (byte) 0x45, - (byte) 0xce, (byte) 0x30, (byte) 0xb4, (byte) 0xab, (byte) 0x80, (byte) 0xe4, - (byte) 0x98, (byte) 0x31, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xda, - (byte) 0x82, (byte) 0x9d, (byte) 0x3f, (byte) 0xca, (byte) 0x2f, (byte) 0xe1, - (byte) 0xd4, (byte) 0x86, (byte) 0x77, (byte) 0x48, (byte) 0xa6, (byte) 0xab, - (byte) 0xab, (byte) 0x1c, (byte) 0x42, (byte) 0x5c, (byte) 0xd5, (byte) 0xc7, - (byte) 0x46, (byte) 0x59, (byte) 0x91, (byte) 0x3f, (byte) 0xfc, (byte) 0xcc, - (byte) 0xec, (byte) 0xc2, (byte) 0x40, (byte) 0x12, (byte) 0x2c, (byte) 0x8d, - (byte) 0x1f, (byte) 0xa2, (byte) 0x18, (byte) 0x88, (byte) 0xee, (byte) 0x82, - (byte) 0x4a, (byte) 0x5a, (byte) 0x5e, (byte) 0x88, (byte) 0x20, (byte) 0xe3, - (byte) 0x7b, (byte) 0xe0, (byte) 0xd8, (byte) 0x3a, (byte) 0x52, (byte) 0x9a, - (byte) 0x26, (byte) 0x6a, (byte) 0x04, (byte) 0xec, (byte) 0xe8, (byte) 0xb9, - (byte) 0x48, (byte) 0x40, (byte) 0xe1, (byte) 0xe1, (byte) 0x83, (byte) 0xa6, - (byte) 0x67, (byte) 0xa6, (byte) 0xfd, (byte) 0x02, (byte) 0x41, (byte) 0x00, - (byte) 0x89, (byte) 0x72, (byte) 0x3e, (byte) 0xb0, (byte) 0x90, (byte) 0xfd, - (byte) 0x4c, (byte) 0x0e, (byte) 0xd6, (byte) 0x13, (byte) 0x63, (byte) 0xcb, - (byte) 0xed, (byte) 0x38, (byte) 0x88, (byte) 0xb6, (byte) 0x79, (byte) 0xc4, - (byte) 0x33, (byte) 0x6c, (byte) 0xf6, (byte) 0xf8, (byte) 0xd8, (byte) 0xd0, - (byte) 0xbf, (byte) 0x9d, (byte) 0x35, (byte) 0xac, (byte) 0x69, (byte) 0xd2, - (byte) 0x2b, (byte) 0xc1, (byte) 0xf9, (byte) 0x24, (byte) 0x7b, (byte) 0xce, - (byte) 0xcd, (byte) 0xcb, (byte) 0xa7, (byte) 0xb2, (byte) 0x7a, (byte) 0x0a, - (byte) 0x27, (byte) 0x19, (byte) 0xc9, (byte) 0xaf, (byte) 0x0d, (byte) 0x21, - (byte) 0x89, (byte) 0x88, (byte) 0x7c, (byte) 0xad, (byte) 0x9e, (byte) 0x8d, - (byte) 0x47, (byte) 0x6d, (byte) 0x3f, (byte) 0xce, (byte) 0x7b, (byte) 0xa1, - (byte) 0x74, (byte) 0xf1, (byte) 0xa0, (byte) 0xa1, (byte) 0x02, (byte) 0x41, - (byte) 0x00, (byte) 0xd9, (byte) 0xa8, (byte) 0xf5, (byte) 0xfe, (byte) 0xce, - (byte) 0xe6, (byte) 0x77, (byte) 0x6b, (byte) 0xfe, (byte) 0x2d, (byte) 0xe0, - (byte) 0x1e, (byte) 0xb6, (byte) 0x2e, (byte) 0x12, (byte) 0x4e, (byte) 0x40, - (byte) 0xaf, (byte) 0x6a, (byte) 0x7b, (byte) 0x37, (byte) 0x49, (byte) 0x2a, - (byte) 0x96, (byte) 0x25, (byte) 0x83, (byte) 0x49, (byte) 0xd4, (byte) 0x0c, - (byte) 0xc6, (byte) 0x78, (byte) 0x25, (byte) 0x24, (byte) 0x90, (byte) 0x90, - (byte) 0x06, (byte) 0x15, (byte) 0x9e, (byte) 0xfe, (byte) 0xf9, (byte) 0xdf, - (byte) 0x5b, (byte) 0xf3, (byte) 0x7e, (byte) 0x38, (byte) 0x70, (byte) 0xeb, - (byte) 0x57, (byte) 0xd0, (byte) 0xd9, (byte) 0xa7, (byte) 0x0e, (byte) 0x14, - (byte) 0xf7, (byte) 0x95, (byte) 0x68, (byte) 0xd5, (byte) 0xc8, (byte) 0xab, - (byte) 0x9d, (byte) 0x3a, (byte) 0x2b, (byte) 0x51, (byte) 0xf9, (byte) 0x02, - (byte) 0x41, (byte) 0x00, (byte) 0x96, (byte) 0xdf, (byte) 0xe9, (byte) 0x67, - (byte) 0x6c, (byte) 0xdc, (byte) 0x90, (byte) 0x14, (byte) 0xb4, (byte) 0x1d, - (byte) 0x22, (byte) 0x33, (byte) 0x4a, (byte) 0x31, (byte) 0xc1, (byte) 0x9d, - (byte) 0x2e, (byte) 0xff, (byte) 0x9a, (byte) 0x2a, (byte) 0x95, (byte) 0x4b, - (byte) 0x27, (byte) 0x74, (byte) 0xcb, (byte) 0x21, (byte) 0xc3, (byte) 0xd2, - (byte) 0x0b, (byte) 0xb2, (byte) 0x46, (byte) 0x87, (byte) 0xf8, (byte) 0x28, - (byte) 0x01, (byte) 0x8b, (byte) 0xd8, (byte) 0xb9, (byte) 0x4b, (byte) 0xcd, - (byte) 0x9a, (byte) 0x96, (byte) 0x41, (byte) 0x0e, (byte) 0x36, (byte) 0x6d, - (byte) 0x40, (byte) 0x42, (byte) 0xbc, (byte) 0xd9, (byte) 0xd3, (byte) 0x7b, - (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1, - (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51 - }; - public static final PrivateKey RSA_KEY1 = loadPrivateRSAKey(FAKE_RSA_KEY_1); - - private static X509Certificate loadCertificate(String blob) { - try { - final CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); - InputStream stream = new ByteArrayInputStream(blob.getBytes(StandardCharsets.UTF_8)); - - return (X509Certificate) certFactory.generateCertificate(stream); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - private static PrivateKey loadPrivateRSAKey(byte[] fakeKey) { - try { - KeyFactory kf = KeyFactory.getInstance("RSA"); - return kf.generatePrivate(new PKCS8EncodedKeySpec(fakeKey)); - } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { - return null; - } - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/MulticastLockTest.java b/tests/cts/net/src/android/net/wifi/cts/MulticastLockTest.java deleted file mode 100644 index 71f04a33c1..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/MulticastLockTest.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2019 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.wifi.cts; - -import android.content.Context; -import android.net.wifi.WifiManager; -import android.net.wifi.WifiManager.MulticastLock; -import android.platform.test.annotations.AppModeFull; -import android.test.AndroidTestCase; - -@AppModeFull(reason = "Cannot get WifiManager in instant app mode") -public class MulticastLockTest extends AndroidTestCase { - - private static final String WIFI_TAG = "MulticastLockTest"; - - /** - * Verify acquire and release of Multicast locks - */ - public void testMulticastLock() { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - WifiManager wm = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); - MulticastLock mcl = wm.createMulticastLock(WIFI_TAG); - - mcl.setReferenceCounted(true); - assertFalse(mcl.isHeld()); - mcl.acquire(); - assertTrue(mcl.isHeld()); - mcl.release(); - assertFalse(mcl.isHeld()); - mcl.acquire(); - mcl.acquire(); - assertTrue(mcl.isHeld()); - mcl.release(); - assertTrue(mcl.isHeld()); - mcl.release(); - assertFalse(mcl.isHeld()); - assertNotNull(mcl.toString()); - try { - mcl.release(); - fail("should throw out exception because release is called" - +" a greater number of times than acquire"); - } catch (RuntimeException e) { - // expected - } - - mcl = wm.createMulticastLock(WIFI_TAG); - mcl.setReferenceCounted(false); - assertFalse(mcl.isHeld()); - mcl.acquire(); - assertTrue(mcl.isHeld()); - mcl.release(); - assertFalse(mcl.isHeld()); - mcl.acquire(); - mcl.acquire(); - assertTrue(mcl.isHeld()); - mcl.release(); - assertFalse(mcl.isHeld()); - assertNotNull(mcl.toString()); - // releasing again after release: but ignored for non-referenced locks - mcl.release(); - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java deleted file mode 100644 index f2a2b48267..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java +++ /dev/null @@ -1,592 +0,0 @@ -/* - * Copyright (C) 2012 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.wifi.cts; - -import android.content.Context; -import android.net.nsd.NsdManager; -import android.net.nsd.NsdServiceInfo; -import android.platform.test.annotations.AppModeFull; -import android.test.AndroidTestCase; -import android.util.Log; - -import java.io.IOException; -import java.net.ServerSocket; -import java.util.Arrays; -import java.util.Random; -import java.util.List; -import java.util.ArrayList; - -@AppModeFull(reason = "Socket cannot bind in instant app mode") -public class NsdManagerTest extends AndroidTestCase { - - private static final String TAG = "NsdManagerTest"; - private static final String SERVICE_TYPE = "_nmt._tcp"; - private static final int TIMEOUT = 2000; - - private static final boolean DBG = false; - - NsdManager mNsdManager; - - NsdManager.RegistrationListener mRegistrationListener; - NsdManager.DiscoveryListener mDiscoveryListener; - NsdManager.ResolveListener mResolveListener; - private NsdServiceInfo mResolvedService; - - public NsdManagerTest() { - initRegistrationListener(); - initDiscoveryListener(); - initResolveListener(); - } - - private void initRegistrationListener() { - mRegistrationListener = new NsdManager.RegistrationListener() { - @Override - public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) { - setEvent("onRegistrationFailed", errorCode); - } - - @Override - public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) { - setEvent("onUnregistrationFailed", errorCode); - } - - @Override - public void onServiceRegistered(NsdServiceInfo serviceInfo) { - setEvent("onServiceRegistered", serviceInfo); - } - - @Override - public void onServiceUnregistered(NsdServiceInfo serviceInfo) { - setEvent("onServiceUnregistered", serviceInfo); - } - }; - } - - private void initDiscoveryListener() { - mDiscoveryListener = new NsdManager.DiscoveryListener() { - @Override - public void onStartDiscoveryFailed(String serviceType, int errorCode) { - setEvent("onStartDiscoveryFailed", errorCode); - } - - @Override - public void onStopDiscoveryFailed(String serviceType, int errorCode) { - setEvent("onStopDiscoveryFailed", errorCode); - } - - @Override - public void onDiscoveryStarted(String serviceType) { - NsdServiceInfo info = new NsdServiceInfo(); - info.setServiceType(serviceType); - setEvent("onDiscoveryStarted", info); - } - - @Override - public void onDiscoveryStopped(String serviceType) { - NsdServiceInfo info = new NsdServiceInfo(); - info.setServiceType(serviceType); - setEvent("onDiscoveryStopped", info); - } - - @Override - public void onServiceFound(NsdServiceInfo serviceInfo) { - setEvent("onServiceFound", serviceInfo); - } - - @Override - public void onServiceLost(NsdServiceInfo serviceInfo) { - setEvent("onServiceLost", serviceInfo); - } - }; - } - - private void initResolveListener() { - mResolveListener = new NsdManager.ResolveListener() { - @Override - public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { - setEvent("onResolveFailed", errorCode); - } - - @Override - public void onServiceResolved(NsdServiceInfo serviceInfo) { - mResolvedService = serviceInfo; - setEvent("onServiceResolved", serviceInfo); - } - }; - } - - - - private final class EventData { - EventData(String callbackName, NsdServiceInfo info) { - mCallbackName = callbackName; - mSucceeded = true; - mErrorCode = 0; - mInfo = info; - } - EventData(String callbackName, int errorCode) { - mCallbackName = callbackName; - mSucceeded = false; - mErrorCode = errorCode; - mInfo = null; - } - private final String mCallbackName; - private final boolean mSucceeded; - private final int mErrorCode; - private final NsdServiceInfo mInfo; - } - - private final List mEventCache = new ArrayList(); - - private void setEvent(String callbackName, int errorCode) { - if (DBG) Log.d(TAG, callbackName + " failed with " + String.valueOf(errorCode)); - EventData eventData = new EventData(callbackName, errorCode); - synchronized (mEventCache) { - mEventCache.add(eventData); - mEventCache.notify(); - } - } - - private void setEvent(String callbackName, NsdServiceInfo info) { - if (DBG) Log.d(TAG, "Received event " + callbackName + " for " + info.getServiceName()); - EventData eventData = new EventData(callbackName, info); - synchronized (mEventCache) { - mEventCache.add(eventData); - mEventCache.notify(); - } - } - - void clearEventCache() { - synchronized(mEventCache) { - mEventCache.clear(); - } - } - - int eventCacheSize() { - synchronized(mEventCache) { - return mEventCache.size(); - } - } - - private int mWaitId = 0; - private EventData waitForCallback(String callbackName) { - - synchronized(mEventCache) { - - mWaitId ++; - if (DBG) Log.d(TAG, "Waiting for " + callbackName + ", id=" + String.valueOf(mWaitId)); - - try { - long startTime = android.os.SystemClock.uptimeMillis(); - long elapsedTime = 0; - int index = 0; - while (elapsedTime < TIMEOUT ) { - // first check if we've received that event - for (; index < mEventCache.size(); index++) { - EventData e = mEventCache.get(index); - if (e.mCallbackName.equals(callbackName)) { - if (DBG) Log.d(TAG, "exiting wait id=" + String.valueOf(mWaitId)); - return e; - } - } - - // Not yet received, just wait - mEventCache.wait(TIMEOUT - elapsedTime); - elapsedTime = android.os.SystemClock.uptimeMillis() - startTime; - } - // we exited the loop because of TIMEOUT; fail the call - if (DBG) Log.d(TAG, "timed out waiting id=" + String.valueOf(mWaitId)); - return null; - } catch (InterruptedException e) { - return null; // wait timed out! - } - } - } - - private EventData waitForNewEvents() throws InterruptedException { - if (DBG) Log.d(TAG, "Waiting for a bit, id=" + String.valueOf(mWaitId)); - - long startTime = android.os.SystemClock.uptimeMillis(); - long elapsedTime = 0; - synchronized (mEventCache) { - int index = mEventCache.size(); - while (elapsedTime < TIMEOUT ) { - // first check if we've received that event - for (; index < mEventCache.size(); index++) { - EventData e = mEventCache.get(index); - return e; - } - - // Not yet received, just wait - mEventCache.wait(TIMEOUT - elapsedTime); - elapsedTime = android.os.SystemClock.uptimeMillis() - startTime; - } - } - - return null; - } - - private String mServiceName; - - @Override - public void setUp() { - if (DBG) Log.d(TAG, "Setup test ..."); - mNsdManager = (NsdManager) getContext().getSystemService(Context.NSD_SERVICE); - - Random rand = new Random(); - mServiceName = new String("NsdTest"); - for (int i = 0; i < 4; i++) { - mServiceName = mServiceName + String.valueOf(rand.nextInt(10)); - } - } - - @Override - public void tearDown() { - if (DBG) Log.d(TAG, "Tear down test ..."); - } - - public void testNDSManager() throws Exception { - EventData lastEvent = null; - - if (DBG) Log.d(TAG, "Starting test ..."); - - NsdServiceInfo si = new NsdServiceInfo(); - si.setServiceType(SERVICE_TYPE); - si.setServiceName(mServiceName); - - byte testByteArray[] = new byte[] {-128, 127, 2, 1, 0, 1, 2}; - String String256 = "1_________2_________3_________4_________5_________6_________" + - "7_________8_________9_________10________11________12________13________" + - "14________15________16________17________18________19________20________" + - "21________22________23________24________25________123456"; - - // Illegal attributes - try { - si.setAttribute(null, (String) null); - fail("Could set null key"); - } catch (IllegalArgumentException e) { - // expected - } - - try { - si.setAttribute("", (String) null); - fail("Could set empty key"); - } catch (IllegalArgumentException e) { - // expected - } - - try { - si.setAttribute(String256, (String) null); - fail("Could set key with 255 characters"); - } catch (IllegalArgumentException e) { - // expected - } - - try { - si.setAttribute("key", String256.substring(3)); - fail("Could set key+value combination with more than 255 characters"); - } catch (IllegalArgumentException e) { - // expected - } - - try { - si.setAttribute("key", String256.substring(4)); - fail("Could set key+value combination with 255 characters"); - } catch (IllegalArgumentException e) { - // expected - } - - try { - si.setAttribute(new String(new byte[]{0x19}), (String) null); - fail("Could set key with invalid character"); - } catch (IllegalArgumentException e) { - // expected - } - - try { - si.setAttribute("=", (String) null); - fail("Could set key with invalid character"); - } catch (IllegalArgumentException e) { - // expected - } - - try { - si.setAttribute(new String(new byte[]{0x7F}), (String) null); - fail("Could set key with invalid character"); - } catch (IllegalArgumentException e) { - // expected - } - - // Allowed attributes - si.setAttribute("booleanAttr", (String) null); - si.setAttribute("keyValueAttr", "value"); - si.setAttribute("keyEqualsAttr", "="); - si.setAttribute(" whiteSpaceKeyValueAttr ", " value "); - si.setAttribute("binaryDataAttr", testByteArray); - si.setAttribute("nullBinaryDataAttr", (byte[]) null); - si.setAttribute("emptyBinaryDataAttr", new byte[]{}); - si.setAttribute("longkey", String256.substring(9)); - - ServerSocket socket; - int localPort; - - try { - socket = new ServerSocket(0); - localPort = socket.getLocalPort(); - si.setPort(localPort); - } catch (IOException e) { - if (DBG) Log.d(TAG, "Could not open a local socket"); - assertTrue(false); - return; - } - - if (DBG) Log.d(TAG, "Port = " + String.valueOf(localPort)); - - clearEventCache(); - - mNsdManager.registerService(si, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener); - lastEvent = waitForCallback("onServiceRegistered"); // id = 1 - assertTrue(lastEvent != null); - assertTrue(lastEvent.mSucceeded); - assertTrue(eventCacheSize() == 1); - - // We may not always get the name that we tried to register; - // This events tells us the name that was registered. - String registeredName = lastEvent.mInfo.getServiceName(); - si.setServiceName(registeredName); - - clearEventCache(); - - mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, - mDiscoveryListener); - - // Expect discovery started - lastEvent = waitForCallback("onDiscoveryStarted"); // id = 2 - - assertTrue(lastEvent != null); - assertTrue(lastEvent.mSucceeded); - - // Remove this event, so accounting becomes easier later - synchronized (mEventCache) { - mEventCache.remove(lastEvent); - } - - // Expect a service record to be discovered (and filter the ones - // that are unrelated to this test) - boolean found = false; - for (int i = 0; i < 32; i++) { - - lastEvent = waitForCallback("onServiceFound"); // id = 3 - if (lastEvent == null) { - // no more onServiceFound events are being reported! - break; - } - - assertTrue(lastEvent.mSucceeded); - - if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": ServiceName = " + - lastEvent.mInfo.getServiceName()); - - if (lastEvent.mInfo.getServiceName().equals(registeredName)) { - // Save it, as it will get overwritten with new serviceFound events - si = lastEvent.mInfo; - found = true; - } - - // Remove this event from the event cache, so it won't be found by subsequent - // calls to waitForCallback - synchronized (mEventCache) { - mEventCache.remove(lastEvent); - } - } - - assertTrue(found); - - // We've removed all serviceFound events, and we've removed the discoveryStarted - // event as well, so now the event cache should be empty! - assertTrue(eventCacheSize() == 0); - - // Resolve the service - clearEventCache(); - mNsdManager.resolveService(si, mResolveListener); - lastEvent = waitForCallback("onServiceResolved"); // id = 4 - - assertNotNull(mResolvedService); - - // Check Txt attributes - assertEquals(8, mResolvedService.getAttributes().size()); - assertTrue(mResolvedService.getAttributes().containsKey("booleanAttr")); - assertNull(mResolvedService.getAttributes().get("booleanAttr")); - assertEquals("value", new String(mResolvedService.getAttributes().get("keyValueAttr"))); - assertEquals("=", new String(mResolvedService.getAttributes().get("keyEqualsAttr"))); - assertEquals(" value ", new String(mResolvedService.getAttributes() - .get(" whiteSpaceKeyValueAttr "))); - assertEquals(String256.substring(9), new String(mResolvedService.getAttributes() - .get("longkey"))); - assertTrue(Arrays.equals(testByteArray, - mResolvedService.getAttributes().get("binaryDataAttr"))); - assertTrue(mResolvedService.getAttributes().containsKey("nullBinaryDataAttr")); - assertNull(mResolvedService.getAttributes().get("nullBinaryDataAttr")); - assertTrue(mResolvedService.getAttributes().containsKey("emptyBinaryDataAttr")); - assertNull(mResolvedService.getAttributes().get("emptyBinaryDataAttr")); - - assertTrue(lastEvent != null); - assertTrue(lastEvent.mSucceeded); - - if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": Port = " + - String.valueOf(lastEvent.mInfo.getPort())); - - assertTrue(lastEvent.mInfo.getPort() == localPort); - assertTrue(eventCacheSize() == 1); - - checkForAdditionalEvents(); - clearEventCache(); - - // Unregister the service - mNsdManager.unregisterService(mRegistrationListener); - lastEvent = waitForCallback("onServiceUnregistered"); // id = 5 - - assertTrue(lastEvent != null); - assertTrue(lastEvent.mSucceeded); - - // Expect a callback for service lost - lastEvent = waitForCallback("onServiceLost"); // id = 6 - - assertTrue(lastEvent != null); - assertTrue(lastEvent.mInfo.getServiceName().equals(registeredName)); - - // Register service again to see if we discover it - checkForAdditionalEvents(); - clearEventCache(); - - si = new NsdServiceInfo(); - si.setServiceType(SERVICE_TYPE); - si.setServiceName(mServiceName); - si.setPort(localPort); - - // Create a new registration listener and register same service again - initRegistrationListener(); - - mNsdManager.registerService(si, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener); - - lastEvent = waitForCallback("onServiceRegistered"); // id = 7 - - assertTrue(lastEvent != null); - assertTrue(lastEvent.mSucceeded); - - registeredName = lastEvent.mInfo.getServiceName(); - - // Expect a record to be discovered - // Expect a service record to be discovered (and filter the ones - // that are unrelated to this test) - found = false; - for (int i = 0; i < 32; i++) { - - lastEvent = waitForCallback("onServiceFound"); // id = 8 - if (lastEvent == null) { - // no more onServiceFound events are being reported! - break; - } - - assertTrue(lastEvent.mSucceeded); - - if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": ServiceName = " + - lastEvent.mInfo.getServiceName()); - - if (lastEvent.mInfo.getServiceName().equals(registeredName)) { - // Save it, as it will get overwritten with new serviceFound events - si = lastEvent.mInfo; - found = true; - } - - // Remove this event from the event cache, so it won't be found by subsequent - // calls to waitForCallback - synchronized (mEventCache) { - mEventCache.remove(lastEvent); - } - } - - assertTrue(found); - - // Resolve the service - clearEventCache(); - mNsdManager.resolveService(si, mResolveListener); - lastEvent = waitForCallback("onServiceResolved"); // id = 9 - - assertTrue(lastEvent != null); - assertTrue(lastEvent.mSucceeded); - - if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": ServiceName = " + - lastEvent.mInfo.getServiceName()); - - assertTrue(lastEvent.mInfo.getServiceName().equals(registeredName)); - - assertNotNull(mResolvedService); - - // Check that we don't have any TXT records - assertEquals(0, mResolvedService.getAttributes().size()); - - checkForAdditionalEvents(); - clearEventCache(); - - mNsdManager.stopServiceDiscovery(mDiscoveryListener); - lastEvent = waitForCallback("onDiscoveryStopped"); // id = 10 - assertTrue(lastEvent != null); - assertTrue(lastEvent.mSucceeded); - assertTrue(checkCacheSize(1)); - - checkForAdditionalEvents(); - clearEventCache(); - - mNsdManager.unregisterService(mRegistrationListener); - - lastEvent = waitForCallback("onServiceUnregistered"); // id = 11 - assertTrue(lastEvent != null); - assertTrue(lastEvent.mSucceeded); - assertTrue(checkCacheSize(1)); - } - - boolean checkCacheSize(int size) { - synchronized (mEventCache) { - int cacheSize = mEventCache.size(); - if (cacheSize != size) { - Log.d(TAG, "id = " + mWaitId + ": event cache size = " + cacheSize); - for (int i = 0; i < cacheSize; i++) { - EventData e = mEventCache.get(i); - String sname = (e.mInfo != null) ? "(" + e.mInfo.getServiceName() + ")" : ""; - Log.d(TAG, "eventName is " + e.mCallbackName + sname); - } - } - return (cacheSize == size); - } - } - - boolean checkForAdditionalEvents() { - try { - EventData e = waitForNewEvents(); - if (e != null) { - String sname = (e.mInfo != null) ? "(" + e.mInfo.getServiceName() + ")" : ""; - Log.d(TAG, "ignoring unexpected event " + e.mCallbackName + sname); - } - return (e == null); - } - catch (InterruptedException ex) { - return false; - } - } -} - diff --git a/tests/cts/net/src/android/net/wifi/cts/PpsMoParserTest.java b/tests/cts/net/src/android/net/wifi/cts/PpsMoParserTest.java deleted file mode 100644 index feafd434a7..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/PpsMoParserTest.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2017 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.wifi.cts; - -import android.net.wifi.hotspot2.PasspointConfiguration; -import android.net.wifi.hotspot2.omadm.PpsMoParser; -import android.net.wifi.hotspot2.pps.Credential; -import android.net.wifi.hotspot2.pps.HomeSp; -import android.test.AndroidTestCase; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * CTS tests for PPS MO (PerProviderSubscription Management Object) XML string parsing API. - */ -public class PpsMoParserTest extends AndroidTestCase { - private static final String PPS_MO_XML_FILE = "assets/PerProviderSubscription.xml"; - - /** - * Read the content of the given resource file into a String. - * - * @param filename String name of the file - * @return String - * @throws IOException - */ - private String loadResourceFile(String filename) throws IOException { - InputStream in = getClass().getClassLoader().getResourceAsStream(filename); - BufferedReader reader = new BufferedReader(new InputStreamReader(in)); - StringBuilder builder = new StringBuilder(); - String line; - while ((line = reader.readLine()) != null) { - builder.append(line).append("\n"); - } - return builder.toString(); - } - - /** - * Generate a {@link PasspointConfiguration} that matches the configuration specified in the - * XML file {@link #PPS_MO_XML_FILE}. - * - * @return {@link PasspointConfiguration} - */ - private PasspointConfiguration generateConfigurationFromPPSMOTree() throws Exception { - DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); - byte[] certFingerprint = new byte[32]; - Arrays.fill(certFingerprint, (byte) 0x1f); - - PasspointConfiguration config = new PasspointConfiguration(); - - // HomeSP configuration. - HomeSp homeSp = new HomeSp(); - homeSp.setFriendlyName("Century House"); - assertEquals("Century House", homeSp.getFriendlyName()); - homeSp.setFqdn("mi6.co.uk"); - assertEquals("mi6.co.uk", homeSp.getFqdn()); - homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L}); - assertTrue(Arrays.equals(new long[] {0x112233L, 0x445566L}, - homeSp.getRoamingConsortiumOis())); - config.setHomeSp(homeSp); - assertEquals(homeSp, config.getHomeSp()); - - // Credential configuration. - Credential credential = new Credential(); - credential.setRealm("shaken.stirred.com"); - assertEquals("shaken.stirred.com", credential.getRealm()); - Credential.UserCredential userCredential = new Credential.UserCredential(); - userCredential.setUsername("james"); - assertEquals("james", userCredential.getUsername()); - userCredential.setPassword("Ym9uZDAwNw=="); - assertEquals("Ym9uZDAwNw==", userCredential.getPassword()); - userCredential.setEapType(21); - assertEquals(21, userCredential.getEapType()); - userCredential.setNonEapInnerMethod("MS-CHAP-V2"); - assertEquals("MS-CHAP-V2", userCredential.getNonEapInnerMethod()); - credential.setUserCredential(userCredential); - assertEquals(userCredential, credential.getUserCredential()); - Credential.CertificateCredential certCredential = new Credential.CertificateCredential(); - certCredential.setCertType("x509v3"); - assertEquals("x509v3", certCredential.getCertType()); - certCredential.setCertSha256Fingerprint(certFingerprint); - assertTrue(Arrays.equals(certFingerprint, certCredential.getCertSha256Fingerprint())); - credential.setCertCredential(certCredential); - assertEquals(certCredential, credential.getCertCredential()); - Credential.SimCredential simCredential = new Credential.SimCredential(); - simCredential.setImsi("imsi"); - assertEquals("imsi", simCredential.getImsi()); - simCredential.setEapType(24); - assertEquals(24, simCredential.getEapType()); - credential.setSimCredential(simCredential); - assertEquals(simCredential, credential.getSimCredential()); - config.setCredential(credential); - assertEquals(credential, config.getCredential()); - return config; - } - - /** - * Parse and verify all supported fields under PPS MO tree. - * - * @throws Exception - */ - public void testParsePPSMOTree() throws Exception { - String ppsMoTree = loadResourceFile(PPS_MO_XML_FILE); - PasspointConfiguration expectedConfig = generateConfigurationFromPPSMOTree(); - PasspointConfiguration actualConfig = PpsMoParser.parseMoText(ppsMoTree); - assertTrue(actualConfig.equals(expectedConfig)); - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java deleted file mode 100644 index 1977378c1a..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright (C) 2008 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.wifi.cts; - -import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; - -import java.nio.ByteBuffer; -import java.util.List; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.wifi.ScanResult; -import android.net.wifi.ScanResult.InformationElement; -import android.net.wifi.WifiInfo; -import android.net.wifi.WifiManager; -import android.net.wifi.WifiManager.WifiLock; -import android.platform.test.annotations.AppModeFull; -import android.test.AndroidTestCase; - -import com.android.compatibility.common.util.ShellIdentityUtils; -import com.android.compatibility.common.util.SystemUtil; - -@AppModeFull(reason = "Cannot get WifiManager in instant app mode") -public class ScanResultTest extends AndroidTestCase { - private static class MySync { - int expectedState = STATE_NULL; - } - - private WifiManager mWifiManager; - private WifiLock mWifiLock; - private static MySync mMySync; - private boolean mWasVerboseLoggingEnabled; - private boolean mWasScanThrottleEnabled; - - private static final int STATE_NULL = 0; - private static final int STATE_WIFI_CHANGING = 1; - private static final int STATE_WIFI_CHANGED = 2; - private static final int STATE_START_SCAN = 3; - private static final int STATE_SCAN_RESULTS_AVAILABLE = 4; - private static final int STATE_SCAN_FAILURE = 5; - - private static final String TAG = "WifiInfoTest"; - private static final int TIMEOUT_MSEC = 6000; - private static final int WAIT_MSEC = 60; - private static final int ENABLE_WAIT_MSEC = 10000; - private static final int SCAN_WAIT_MSEC = 10000; - private static final int SCAN_MAX_RETRY_COUNT = 6; - private static final int SCAN_FIND_BSSID_MAX_RETRY_COUNT = 5; - private static final long SCAN_FIND_BSSID_WAIT_MSEC = 5_000L; - - private static final String TEST_SSID = "TEST_SSID"; - public static final String TEST_BSSID = "04:ac:fe:45:34:10"; - public static final String TEST_CAPS = "CCMP"; - public static final int TEST_LEVEL = -56; - public static final int TEST_FREQUENCY = 2412; - public static final long TEST_TIMESTAMP = 4660L; - - private IntentFilter mIntentFilter; - private final BroadcastReceiver mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - final String action = intent.getAction(); - if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) { - synchronized (mMySync) { - mMySync.expectedState = STATE_WIFI_CHANGED; - mMySync.notify(); - } - } else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { - synchronized (mMySync) { - if (intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)) { - mMySync.expectedState = STATE_SCAN_RESULTS_AVAILABLE; - } else { - mMySync.expectedState = STATE_SCAN_FAILURE; - } - mMySync.notify(); - } - } - } - }; - - @Override - protected void setUp() throws Exception { - super.setUp(); - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - mMySync = new MySync(); - mIntentFilter = new IntentFilter(); - mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); - mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); - mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.ACTION_PICK_WIFI_NETWORK); - - mContext.registerReceiver(mReceiver, mIntentFilter); - mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); - assertThat(mWifiManager).isNotNull(); - - // turn on verbose logging for tests - mWasVerboseLoggingEnabled = ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.isVerboseLoggingEnabled()); - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.setVerboseLoggingEnabled(true)); - // Disable scan throttling for tests. - mWasScanThrottleEnabled = ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.isScanThrottleEnabled()); - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.setScanThrottleEnabled(false)); - - mWifiLock = mWifiManager.createWifiLock(TAG); - mWifiLock.acquire(); - if (!mWifiManager.isWifiEnabled()) - setWifiEnabled(true); - Thread.sleep(ENABLE_WAIT_MSEC); - assertThat(mWifiManager.isWifiEnabled()).isTrue(); - mMySync.expectedState = STATE_NULL; - } - - @Override - protected void tearDown() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - super.tearDown(); - return; - } - mWifiLock.release(); - mContext.unregisterReceiver(mReceiver); - if (!mWifiManager.isWifiEnabled()) - setWifiEnabled(true); - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.setScanThrottleEnabled(mWasScanThrottleEnabled)); - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled)); - Thread.sleep(ENABLE_WAIT_MSEC); - super.tearDown(); - } - - private void setWifiEnabled(boolean enable) throws Exception { - synchronized (mMySync) { - mMySync.expectedState = STATE_WIFI_CHANGING; - if (enable) { - SystemUtil.runShellCommand("svc wifi enable"); - } else { - SystemUtil.runShellCommand("svc wifi disable"); - } - waitForBroadcast(TIMEOUT_MSEC, STATE_WIFI_CHANGED); - } - } - - private boolean waitForBroadcast(long timeout, int expectedState) throws Exception { - long waitTime = System.currentTimeMillis() + timeout; - while (System.currentTimeMillis() < waitTime - && mMySync.expectedState != expectedState) - mMySync.wait(WAIT_MSEC); - return mMySync.expectedState == expectedState; - } - - public void testScanResultProperties() { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - // this test case should in Wifi environment - for (ScanResult scanResult : mWifiManager.getScanResults()) { - assertThat(scanResult.toString()).isNotNull(); - - for (InformationElement ie : scanResult.getInformationElements()) { - testInformationElementCopyConstructor(ie); - testInformationElementFields(ie); - } - - assertThat(scanResult.getWifiStandard()).isAnyOf( - ScanResult.WIFI_STANDARD_UNKNOWN, - ScanResult.WIFI_STANDARD_LEGACY, - ScanResult.WIFI_STANDARD_11N, - ScanResult.WIFI_STANDARD_11AC, - ScanResult.WIFI_STANDARD_11AX - ); - - scanResult.isPasspointNetwork(); - } - } - - private void testInformationElementCopyConstructor(InformationElement ie) { - InformationElement copy = new InformationElement(ie); - - assertThat(copy.getId()).isEqualTo(ie.getId()); - assertThat(copy.getIdExt()).isEqualTo(ie.getIdExt()); - assertThat(copy.getBytes()).isEqualTo(ie.getBytes()); - } - - private void testInformationElementFields(InformationElement ie) { - // id is 1 octet - int id = ie.getId(); - assertThat(id).isAtLeast(0); - assertThat(id).isAtMost(255); - - // idExt is 0 or 1 octet - int idExt = ie.getIdExt(); - assertThat(idExt).isAtLeast(0); - assertThat(idExt).isAtMost(255); - - ByteBuffer bytes = ie.getBytes(); - assertThat(bytes).isNotNull(); - } - - /* Multiple scans to ensure bssid is updated */ - private void scanAndWait() throws Exception { - synchronized (mMySync) { - for (int retry = 0; retry < SCAN_MAX_RETRY_COUNT; retry++) { - mMySync.expectedState = STATE_START_SCAN; - mWifiManager.startScan(); - if (waitForBroadcast(SCAN_WAIT_MSEC, STATE_SCAN_RESULTS_AVAILABLE)) { - break; - } - } - } - } - - public void testScanResultTimeStamp() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - - long timestamp = 0; - String BSSID = null; - - scanAndWait(); - - List scanResults = mWifiManager.getScanResults(); - for (ScanResult result : scanResults) { - BSSID = result.BSSID; - timestamp = result.timestamp; - assertThat(timestamp).isNotEqualTo(0); - break; - } - - scanAndWait(); - - scanResults = mWifiManager.getScanResults(); - for (ScanResult result : scanResults) { - if (result.BSSID.equals(BSSID)) { - long timeDiff = (result.timestamp - timestamp) / 1000; - assertThat(timeDiff).isGreaterThan(0L); - assertThat(timeDiff).isLessThan(6L * SCAN_WAIT_MSEC); - } - } - } - - /** Test that the copy constructor copies fields correctly. */ - public void testScanResultConstructors() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - - ScanResult scanResult = new ScanResult(); - scanResult.SSID = TEST_SSID; - scanResult.BSSID = TEST_BSSID; - scanResult.capabilities = TEST_CAPS; - scanResult.level = TEST_LEVEL; - scanResult.frequency = TEST_FREQUENCY; - scanResult.timestamp = TEST_TIMESTAMP; - - ScanResult scanResult2 = new ScanResult(scanResult); - assertThat(scanResult2.SSID).isEqualTo(TEST_SSID); - assertThat(scanResult2.BSSID).isEqualTo(TEST_BSSID); - assertThat(scanResult2.capabilities).isEqualTo(TEST_CAPS); - assertThat(scanResult2.level).isEqualTo(TEST_LEVEL); - assertThat(scanResult2.frequency).isEqualTo(TEST_FREQUENCY); - assertThat(scanResult2.timestamp).isEqualTo(TEST_TIMESTAMP); - } - - public void testScanResultMatchesWifiInfo() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - - // This test case should run while connected to Wifi - final WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); - assertThat(wifiInfo).isNotNull(); - - ScanResult currentNetwork = null; - for (int i = 0; i < SCAN_FIND_BSSID_MAX_RETRY_COUNT; i++) { - scanAndWait(); - final List scanResults = mWifiManager.getScanResults(); - currentNetwork = scanResults.stream().filter(r -> r.BSSID.equals(wifiInfo.getBSSID())) - .findAny().orElse(null); - - if (currentNetwork != null) { - break; - } - Thread.sleep(SCAN_FIND_BSSID_WAIT_MSEC); - } - assertWithMessage("Current network not found in scan results") - .that(currentNetwork).isNotNull(); - - String wifiInfoSsidQuoted = wifiInfo.getSSID(); - String scanResultSsidUnquoted = currentNetwork.SSID; - - assertWithMessage( - "SSID mismatch: make sure this isn't a hidden network or an SSID containing " - + "non-UTF-8 characters - neither is supported by this CTS test.") - .that("\"" + scanResultSsidUnquoted + "\"") - .isEqualTo(wifiInfoSsidQuoted); - assertThat(currentNetwork.frequency).isEqualTo(wifiInfo.getFrequency()); - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java b/tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java deleted file mode 100644 index 11edf7395b..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2008 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.wifi.cts; - -import android.net.wifi.SupplicantState; -import android.test.AndroidTestCase; - -public class SupplicantStateTest extends AndroidTestCase { - - public void testIsValidState() { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - assertTrue(SupplicantState.isValidState(SupplicantState.DISCONNECTED)); - assertTrue(SupplicantState.isValidState(SupplicantState.INACTIVE)); - assertTrue(SupplicantState.isValidState(SupplicantState.SCANNING)); - assertTrue(SupplicantState.isValidState(SupplicantState.ASSOCIATING)); - assertTrue(SupplicantState.isValidState(SupplicantState.ASSOCIATED)); - assertTrue(SupplicantState.isValidState(SupplicantState.FOUR_WAY_HANDSHAKE)); - assertTrue(SupplicantState.isValidState(SupplicantState.GROUP_HANDSHAKE)); - assertTrue(SupplicantState.isValidState(SupplicantState.COMPLETED)); - assertTrue(SupplicantState.isValidState(SupplicantState.DORMANT)); - assertFalse(SupplicantState.isValidState(SupplicantState.UNINITIALIZED)); - assertFalse(SupplicantState.isValidState(SupplicantState.INVALID)); - } - -} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java deleted file mode 100644 index a59c85e5ab..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2008 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.wifi.cts; - -import java.util.List; - -import android.content.Context; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiManager; -import android.platform.test.annotations.AppModeFull; -import android.test.AndroidTestCase; - -@AppModeFull(reason = "Cannot get WifiManager in instant app mode") -public class WifiConfigurationTest extends AndroidTestCase { - private WifiManager mWifiManager; - @Override - protected void setUp() throws Exception { - super.setUp(); - mWifiManager = (WifiManager) mContext - .getSystemService(Context.WIFI_SERVICE); - } - - public void testWifiConfiguration() { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - List wifiConfigurations = mWifiManager.getConfiguredNetworks(); - if (wifiConfigurations != null) { - for (int i = 0; i < wifiConfigurations.size(); i++) { - WifiConfiguration wifiConfiguration = wifiConfigurations.get(i); - assertNotNull(wifiConfiguration); - assertNotNull(wifiConfiguration.toString()); - } - } - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java deleted file mode 100644 index 45b9d97843..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java +++ /dev/null @@ -1,899 +0,0 @@ -/* - * Copyright (C) 2013 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.wifi.cts; - -import static com.google.common.truth.Truth.assertThat; - -import android.content.pm.PackageManager; -import android.net.wifi.WifiEnterpriseConfig; -import android.net.wifi.WifiEnterpriseConfig.Eap; -import android.net.wifi.WifiEnterpriseConfig.Phase2; -import android.platform.test.annotations.AppModeFull; -import android.test.AndroidTestCase; - -import java.io.ByteArrayInputStream; -import java.security.KeyFactory; -import java.security.PrivateKey; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.security.spec.PKCS8EncodedKeySpec; - -@AppModeFull(reason = "Cannot get WifiManager in instant app mode") -public class WifiEnterpriseConfigTest extends AndroidTestCase { - - private static final String IDENTITY = "identity"; - private static final String PASSWORD = "password"; - private static final String SUBJECT_MATCH = "subjectmatch"; - private static final String ALT_SUBJECT_MATCH = "altsubjectmatch"; - private static final String DOM_SUBJECT_MATCH = "domsubjectmatch"; - private static final String PLMN = "plmn"; - private static final String REALM = "realm"; - private static final String ANON_IDENTITY = "anonidentity"; - private static final String CERTIFICATE_ALIAS1 = "certificatealias1"; - private static final String CERTIFICATE_ALIAS2 = "certificatealias2"; - private static final String CA_PATH = "capath"; - private static final String CLIENT_CERTIFICATE_ALIAS = "clientcertificatealias"; - private static final String WAPI_CERT_SUITE = "wapicertsuite"; - - /* - * The keys and certificates below are generated with: - * - * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem - * openssl ecparam -name prime256v1 -out ecparam.pem - * openssl req -newkey ec:ecparam.pem -keyout userkey.pem -nodes -days 3650 -out userkey.req - * mkdir -p demoCA/newcerts - * touch demoCA/index.txt - * echo "01" > demoCA/serial - * openssl ca -out usercert.pem -in userkey.req -cert cacert.pem -keyfile cakey.pem -days 3650 - */ - - /** - * Generated from above and converted with: - * - * openssl x509 -outform d -in cacert.pem | xxd -i | sed 's/0x/(byte) 0x/g' - */ - - private static final byte[] FAKE_EC_1 = { - (byte) 0x30, (byte) 0x82, (byte) 0x04, (byte) 0x2f, (byte) 0x30, (byte) 0x82, - (byte) 0x03, (byte) 0x17, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01, - (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0xa7, (byte) 0xe4, - (byte) 0x70, (byte) 0x50, (byte) 0x9b, (byte) 0xd2, (byte) 0x68, (byte) 0x68, - (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, - (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, - (byte) 0x0b, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0xad, - (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41, - (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, - (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, - (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, - (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x12, - (byte) 0x30, (byte) 0x10, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, - (byte) 0x07, (byte) 0x0c, (byte) 0x09, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, - (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x69, (byte) 0x74, (byte) 0x79, - (byte) 0x31, (byte) 0x15, (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, (byte) 0x53, - (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x6f, - (byte) 0x6d, (byte) 0x70, (byte) 0x61, (byte) 0x6e, (byte) 0x79, (byte) 0x31, - (byte) 0x10, (byte) 0x30, (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x07, (byte) 0x53, (byte) 0x65, - (byte) 0x63, (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x31, - (byte) 0x21, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x18, (byte) 0x57, (byte) 0x69, - (byte) 0x66, (byte) 0x69, (byte) 0x45, (byte) 0x6e, (byte) 0x74, (byte) 0x65, - (byte) 0x72, (byte) 0x70, (byte) 0x72, (byte) 0x69, (byte) 0x73, (byte) 0x65, - (byte) 0x43, (byte) 0x6f, (byte) 0x6e, (byte) 0x66, (byte) 0x69, (byte) 0x67, - (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x31, (byte) 0x29, - (byte) 0x30, (byte) 0x27, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, - (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x09, - (byte) 0x01, (byte) 0x16, (byte) 0x1a, (byte) 0x61, (byte) 0x6e, (byte) 0x2d, - (byte) 0x65, (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6c, (byte) 0x2d, - (byte) 0x61, (byte) 0x64, (byte) 0x72, (byte) 0x65, (byte) 0x73, (byte) 0x73, - (byte) 0x40, (byte) 0x64, (byte) 0x6f, (byte) 0x6d, (byte) 0x61, (byte) 0x69, - (byte) 0x6e, (byte) 0x2e, (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, - (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x31, (byte) 0x36, (byte) 0x30, - (byte) 0x31, (byte) 0x31, (byte) 0x35, (byte) 0x31, (byte) 0x31, (byte) 0x31, - (byte) 0x38, (byte) 0x35, (byte) 0x31, (byte) 0x5a, (byte) 0x17, (byte) 0x0d, - (byte) 0x32, (byte) 0x36, (byte) 0x30, (byte) 0x31, (byte) 0x31, (byte) 0x32, - (byte) 0x31, (byte) 0x31, (byte) 0x31, (byte) 0x38, (byte) 0x35, (byte) 0x31, - (byte) 0x5a, (byte) 0x30, (byte) 0x81, (byte) 0xad, (byte) 0x31, (byte) 0x0b, - (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, - (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41, (byte) 0x55, (byte) 0x31, - (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x53, (byte) 0x6f, - (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x74, (byte) 0x61, - (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x12, (byte) 0x30, (byte) 0x10, - (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x0c, - (byte) 0x09, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, - (byte) 0x43, (byte) 0x69, (byte) 0x74, (byte) 0x79, (byte) 0x31, (byte) 0x15, - (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, - (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, - (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x6f, (byte) 0x6d, (byte) 0x70, - (byte) 0x61, (byte) 0x6e, (byte) 0x79, (byte) 0x31, (byte) 0x10, (byte) 0x30, - (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0b, - (byte) 0x0c, (byte) 0x07, (byte) 0x53, (byte) 0x65, (byte) 0x63, (byte) 0x74, - (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x31, (byte) 0x21, (byte) 0x30, - (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03, - (byte) 0x0c, (byte) 0x18, (byte) 0x57, (byte) 0x69, (byte) 0x66, (byte) 0x69, - (byte) 0x45, (byte) 0x6e, (byte) 0x74, (byte) 0x65, (byte) 0x72, (byte) 0x70, - (byte) 0x72, (byte) 0x69, (byte) 0x73, (byte) 0x65, (byte) 0x43, (byte) 0x6f, - (byte) 0x6e, (byte) 0x66, (byte) 0x69, (byte) 0x67, (byte) 0x54, (byte) 0x65, - (byte) 0x73, (byte) 0x74, (byte) 0x31, (byte) 0x29, (byte) 0x30, (byte) 0x27, - (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, - (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x09, (byte) 0x01, (byte) 0x16, - (byte) 0x1a, (byte) 0x61, (byte) 0x6e, (byte) 0x2d, (byte) 0x65, (byte) 0x6d, - (byte) 0x61, (byte) 0x69, (byte) 0x6c, (byte) 0x2d, (byte) 0x61, (byte) 0x64, - (byte) 0x72, (byte) 0x65, (byte) 0x73, (byte) 0x73, (byte) 0x40, (byte) 0x64, - (byte) 0x6f, (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6e, (byte) 0x2e, - (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, (byte) 0x82, (byte) 0x01, - (byte) 0x22, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, - (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, - (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x82, - (byte) 0x01, (byte) 0x0f, (byte) 0x00, (byte) 0x30, (byte) 0x82, (byte) 0x01, - (byte) 0x0a, (byte) 0x02, (byte) 0x82, (byte) 0x01, (byte) 0x01, (byte) 0x00, - (byte) 0xb4, (byte) 0x6e, (byte) 0x66, (byte) 0x24, (byte) 0xe7, (byte) 0x5c, - (byte) 0xd8, (byte) 0x6f, (byte) 0x08, (byte) 0xd3, (byte) 0x80, (byte) 0xa3, - (byte) 0xb9, (byte) 0xaf, (byte) 0x90, (byte) 0xef, (byte) 0x1c, (byte) 0x2a, - (byte) 0x5f, (byte) 0x39, (byte) 0x0b, (byte) 0xbd, (byte) 0x75, (byte) 0x0d, - (byte) 0x3e, (byte) 0x19, (byte) 0x2e, (byte) 0x47, (byte) 0x1e, (byte) 0x14, - (byte) 0xc2, (byte) 0x1a, (byte) 0x59, (byte) 0xcc, (byte) 0x1b, (byte) 0xb6, - (byte) 0x9b, (byte) 0x46, (byte) 0x1f, (byte) 0x7f, (byte) 0x71, (byte) 0xdd, - (byte) 0x38, (byte) 0xbe, (byte) 0x89, (byte) 0x30, (byte) 0xba, (byte) 0x88, - (byte) 0xfb, (byte) 0x3f, (byte) 0x57, (byte) 0x35, (byte) 0xe7, (byte) 0xa7, - (byte) 0x2f, (byte) 0x2c, (byte) 0x8d, (byte) 0x7c, (byte) 0xe2, (byte) 0xd8, - (byte) 0x0c, (byte) 0x0a, (byte) 0xe6, (byte) 0x62, (byte) 0x46, (byte) 0x8c, - (byte) 0xf4, (byte) 0x51, (byte) 0xfc, (byte) 0x6a, (byte) 0x79, (byte) 0xdd, - (byte) 0x0a, (byte) 0x41, (byte) 0x23, (byte) 0xd3, (byte) 0xe9, (byte) 0x5e, - (byte) 0x91, (byte) 0xcd, (byte) 0xbd, (byte) 0x55, (byte) 0x28, (byte) 0x71, - (byte) 0xec, (byte) 0x52, (byte) 0x19, (byte) 0x85, (byte) 0x0c, (byte) 0x1b, - (byte) 0xfa, (byte) 0xbf, (byte) 0xfe, (byte) 0xae, (byte) 0x5c, (byte) 0x3b, - (byte) 0x99, (byte) 0x42, (byte) 0xd4, (byte) 0xe7, (byte) 0x17, (byte) 0xec, - (byte) 0x41, (byte) 0x22, (byte) 0x2c, (byte) 0x1e, (byte) 0x7b, (byte) 0x53, - (byte) 0xad, (byte) 0x02, (byte) 0xfd, (byte) 0xf6, (byte) 0x4a, (byte) 0xb1, - (byte) 0x6e, (byte) 0x6c, (byte) 0x87, (byte) 0xf5, (byte) 0x7d, (byte) 0x9b, - (byte) 0x34, (byte) 0x0e, (byte) 0x3b, (byte) 0x0e, (byte) 0xaa, (byte) 0xc5, - (byte) 0xc4, (byte) 0xef, (byte) 0xf2, (byte) 0x5a, (byte) 0xa9, (byte) 0xac, - (byte) 0x19, (byte) 0xce, (byte) 0x5f, (byte) 0xc5, (byte) 0xcc, (byte) 0x0d, - (byte) 0xee, (byte) 0x7f, (byte) 0x32, (byte) 0xb4, (byte) 0xfe, (byte) 0xc1, - (byte) 0xca, (byte) 0x9b, (byte) 0x3f, (byte) 0xad, (byte) 0x2c, (byte) 0x7a, - (byte) 0xc5, (byte) 0x8d, (byte) 0x48, (byte) 0xa1, (byte) 0xc9, (byte) 0x74, - (byte) 0xfe, (byte) 0x8a, (byte) 0xe3, (byte) 0xb0, (byte) 0x92, (byte) 0xee, - (byte) 0x73, (byte) 0x09, (byte) 0x0a, (byte) 0xbc, (byte) 0xc8, (byte) 0x63, - (byte) 0xba, (byte) 0x0e, (byte) 0x26, (byte) 0xab, (byte) 0x1e, (byte) 0xff, - (byte) 0xbc, (byte) 0x24, (byte) 0x12, (byte) 0x26, (byte) 0x11, (byte) 0xe0, - (byte) 0x04, (byte) 0xcb, (byte) 0x96, (byte) 0x7d, (byte) 0x41, (byte) 0xf7, - (byte) 0x79, (byte) 0x32, (byte) 0x05, (byte) 0x33, (byte) 0x19, (byte) 0x6e, - (byte) 0xb9, (byte) 0x75, (byte) 0xf3, (byte) 0x50, (byte) 0xa4, (byte) 0xc3, - (byte) 0x55, (byte) 0x9d, (byte) 0x8f, (byte) 0xb6, (byte) 0xab, (byte) 0x97, - (byte) 0xe7, (byte) 0xe2, (byte) 0xe8, (byte) 0x15, (byte) 0xfc, (byte) 0x35, - (byte) 0xbd, (byte) 0xce, (byte) 0x17, (byte) 0xbe, (byte) 0xe3, (byte) 0x73, - (byte) 0xd4, (byte) 0x88, (byte) 0x39, (byte) 0x27, (byte) 0x7e, (byte) 0x6d, - (byte) 0xa2, (byte) 0x27, (byte) 0xfa, (byte) 0x96, (byte) 0xe3, (byte) 0x38, - (byte) 0xc0, (byte) 0xa1, (byte) 0x55, (byte) 0xc6, (byte) 0xf3, (byte) 0x20, - (byte) 0xea, (byte) 0x50, (byte) 0x8d, (byte) 0x6c, (byte) 0x94, (byte) 0x9a, - (byte) 0x43, (byte) 0x74, (byte) 0xc0, (byte) 0xfa, (byte) 0xef, (byte) 0xe0, - (byte) 0xb1, (byte) 0x1c, (byte) 0x6d, (byte) 0x5e, (byte) 0x44, (byte) 0x08, - (byte) 0xef, (byte) 0xd5, (byte) 0x80, (byte) 0xad, (byte) 0x02, (byte) 0x03, - (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3, (byte) 0x50, (byte) 0x30, - (byte) 0x4e, (byte) 0x30, (byte) 0x1d, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16, (byte) 0x04, (byte) 0x14, - (byte) 0xe9, (byte) 0xd0, (byte) 0x9e, (byte) 0x0e, (byte) 0x62, (byte) 0x31, - (byte) 0x02, (byte) 0x9a, (byte) 0x33, (byte) 0xd7, (byte) 0x4a, (byte) 0x93, - (byte) 0x0d, (byte) 0xf3, (byte) 0xd6, (byte) 0x74, (byte) 0xce, (byte) 0x69, - (byte) 0xe1, (byte) 0xef, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04, (byte) 0x18, (byte) 0x30, - (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0xe9, (byte) 0xd0, (byte) 0x9e, - (byte) 0x0e, (byte) 0x62, (byte) 0x31, (byte) 0x02, (byte) 0x9a, (byte) 0x33, - (byte) 0xd7, (byte) 0x4a, (byte) 0x93, (byte) 0x0d, (byte) 0xf3, (byte) 0xd6, - (byte) 0x74, (byte) 0xce, (byte) 0x69, (byte) 0xe1, (byte) 0xef, (byte) 0x30, - (byte) 0x0c, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13, - (byte) 0x04, (byte) 0x05, (byte) 0x30, (byte) 0x03, (byte) 0x01, (byte) 0x01, - (byte) 0xff, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, - (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, - (byte) 0x01, (byte) 0x0b, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x82, - (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x52, (byte) 0x70, (byte) 0xb6, - (byte) 0x10, (byte) 0x7f, (byte) 0xaa, (byte) 0x86, (byte) 0x8f, (byte) 0x02, - (byte) 0xb0, (byte) 0x97, (byte) 0x89, (byte) 0xb9, (byte) 0x04, (byte) 0x1d, - (byte) 0x79, (byte) 0xa3, (byte) 0x74, (byte) 0x7c, (byte) 0xdf, (byte) 0xad, - (byte) 0x87, (byte) 0xe4, (byte) 0x00, (byte) 0xd3, (byte) 0x3a, (byte) 0x5c, - (byte) 0x48, (byte) 0x3b, (byte) 0xfe, (byte) 0x77, (byte) 0xfd, (byte) 0xbe, - (byte) 0xce, (byte) 0x5b, (byte) 0xd2, (byte) 0xea, (byte) 0x3e, (byte) 0x7f, - (byte) 0xef, (byte) 0x20, (byte) 0x0d, (byte) 0x0b, (byte) 0xc7, (byte) 0xc4, - (byte) 0x25, (byte) 0x20, (byte) 0xe1, (byte) 0x8f, (byte) 0xc5, (byte) 0x19, - (byte) 0x37, (byte) 0x9c, (byte) 0xa0, (byte) 0x9d, (byte) 0x02, (byte) 0x30, - (byte) 0x5f, (byte) 0x49, (byte) 0x4e, (byte) 0x56, (byte) 0xc4, (byte) 0xab, - (byte) 0xcb, (byte) 0x5c, (byte) 0xe6, (byte) 0x40, (byte) 0x93, (byte) 0x92, - (byte) 0xee, (byte) 0xa1, (byte) 0x69, (byte) 0x7d, (byte) 0x10, (byte) 0x6b, - (byte) 0xd4, (byte) 0xf7, (byte) 0xec, (byte) 0xd9, (byte) 0xa5, (byte) 0x29, - (byte) 0x63, (byte) 0x29, (byte) 0xd9, (byte) 0x27, (byte) 0x2d, (byte) 0x5e, - (byte) 0x34, (byte) 0x37, (byte) 0xa9, (byte) 0xba, (byte) 0x0a, (byte) 0x7b, - (byte) 0x99, (byte) 0x1a, (byte) 0x7d, (byte) 0xa7, (byte) 0xa7, (byte) 0xf0, - (byte) 0xbf, (byte) 0x40, (byte) 0x29, (byte) 0x5d, (byte) 0x2f, (byte) 0x2e, - (byte) 0x0f, (byte) 0x35, (byte) 0x90, (byte) 0xb5, (byte) 0xc3, (byte) 0xfd, - (byte) 0x1e, (byte) 0xe2, (byte) 0xb3, (byte) 0xae, (byte) 0xf9, (byte) 0xde, - (byte) 0x9d, (byte) 0x76, (byte) 0xe1, (byte) 0x20, (byte) 0xf5, (byte) 0x1c, - (byte) 0x30, (byte) 0x42, (byte) 0x80, (byte) 0x2a, (byte) 0x4f, (byte) 0x85, - (byte) 0x5c, (byte) 0xb4, (byte) 0x49, (byte) 0x68, (byte) 0x6c, (byte) 0x7c, - (byte) 0x2a, (byte) 0xc8, (byte) 0xbc, (byte) 0x15, (byte) 0xed, (byte) 0x88, - (byte) 0xfd, (byte) 0x8a, (byte) 0x63, (byte) 0xe0, (byte) 0x93, (byte) 0xfd, - (byte) 0x86, (byte) 0xab, (byte) 0xa9, (byte) 0xf6, (byte) 0x63, (byte) 0xa5, - (byte) 0x29, (byte) 0xaf, (byte) 0xdc, (byte) 0x8f, (byte) 0xca, (byte) 0xc2, - (byte) 0x28, (byte) 0xe7, (byte) 0x26, (byte) 0x89, (byte) 0x75, (byte) 0xf1, - (byte) 0x3e, (byte) 0x2e, (byte) 0x86, (byte) 0x11, (byte) 0x8b, (byte) 0xfa, - (byte) 0xf5, (byte) 0xb4, (byte) 0xb4, (byte) 0x04, (byte) 0x02, (byte) 0xa3, - (byte) 0x85, (byte) 0x81, (byte) 0xad, (byte) 0xb3, (byte) 0xec, (byte) 0x2d, - (byte) 0x4b, (byte) 0x40, (byte) 0x59, (byte) 0x61, (byte) 0x0d, (byte) 0x59, - (byte) 0x09, (byte) 0x09, (byte) 0xee, (byte) 0xc7, (byte) 0x51, (byte) 0xef, - (byte) 0x6f, (byte) 0xd6, (byte) 0x9a, (byte) 0xa5, (byte) 0x45, (byte) 0xa2, - (byte) 0x89, (byte) 0xc2, (byte) 0x97, (byte) 0x93, (byte) 0xbc, (byte) 0x5b, - (byte) 0x37, (byte) 0x55, (byte) 0x73, (byte) 0x55, (byte) 0x0c, (byte) 0x9c, - (byte) 0xcb, (byte) 0x10, (byte) 0xec, (byte) 0x76, (byte) 0xfe, (byte) 0xa7, - (byte) 0x70, (byte) 0x4e, (byte) 0x9a, (byte) 0xa2, (byte) 0xf9, (byte) 0x40, - (byte) 0xdd, (byte) 0x96, (byte) 0x7d, (byte) 0x67, (byte) 0x5c, (byte) 0x8e, - (byte) 0x43, (byte) 0x1a, (byte) 0x26, (byte) 0xaa, (byte) 0xee, (byte) 0x38, - (byte) 0x11, (byte) 0x26, (byte) 0x3d, (byte) 0x69, (byte) 0xc7, (byte) 0x6a, - (byte) 0xe7, (byte) 0xbd, (byte) 0x67, (byte) 0x70, (byte) 0x35, (byte) 0xff, - (byte) 0x72, (byte) 0x2c, (byte) 0x87, (byte) 0x82, (byte) 0x68, (byte) 0x3f, - (byte) 0x8d - }; - - private static final byte[] FAKE_EC_2 = { - (byte) 0x30, (byte) 0x82, (byte) 0x04, (byte) 0x4f, (byte) 0x30, (byte) 0x82, - (byte) 0x03, (byte) 0x37, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01, - (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0xd9, (byte) 0xc4, - (byte) 0xe1, (byte) 0xfc, (byte) 0x3d, (byte) 0x02, (byte) 0x21, (byte) 0x1f, - (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, - (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, - (byte) 0x0b, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0xbd, - (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41, - (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, - (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, - (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, - (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x12, - (byte) 0x30, (byte) 0x10, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, - (byte) 0x07, (byte) 0x0c, (byte) 0x09, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, - (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x69, (byte) 0x74, (byte) 0x79, - (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x12, (byte) 0x53, - (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x4f, (byte) 0x74, - (byte) 0x68, (byte) 0x65, (byte) 0x72, (byte) 0x2d, (byte) 0x43, (byte) 0x6f, - (byte) 0x6d, (byte) 0x70, (byte) 0x61, (byte) 0x6e, (byte) 0x79, (byte) 0x31, - (byte) 0x15, (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x0c, (byte) 0x53, (byte) 0x6f, - (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x65, (byte) 0x63, - (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x31, (byte) 0x21, - (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, - (byte) 0x03, (byte) 0x0c, (byte) 0x18, (byte) 0x57, (byte) 0x69, (byte) 0x66, - (byte) 0x69, (byte) 0x45, (byte) 0x6e, (byte) 0x74, (byte) 0x65, (byte) 0x72, - (byte) 0x70, (byte) 0x72, (byte) 0x69, (byte) 0x73, (byte) 0x65, (byte) 0x43, - (byte) 0x6f, (byte) 0x6e, (byte) 0x66, (byte) 0x69, (byte) 0x67, (byte) 0x54, - (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x31, (byte) 0x2e, (byte) 0x30, - (byte) 0x2c, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, - (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x09, (byte) 0x01, - (byte) 0x16, (byte) 0x1f, (byte) 0x61, (byte) 0x6e, (byte) 0x2d, (byte) 0x65, - (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6c, (byte) 0x2d, (byte) 0x61, - (byte) 0x64, (byte) 0x72, (byte) 0x65, (byte) 0x73, (byte) 0x73, (byte) 0x40, - (byte) 0x73, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x64, - (byte) 0x6f, (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6e, (byte) 0x2e, - (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, (byte) 0x1e, (byte) 0x17, - (byte) 0x0d, (byte) 0x31, (byte) 0x36, (byte) 0x30, (byte) 0x31, (byte) 0x31, - (byte) 0x35, (byte) 0x31, (byte) 0x31, (byte) 0x33, (byte) 0x32, (byte) 0x34, - (byte) 0x36, (byte) 0x5a, (byte) 0x17, (byte) 0x0d, (byte) 0x32, (byte) 0x36, - (byte) 0x30, (byte) 0x31, (byte) 0x31, (byte) 0x32, (byte) 0x31, (byte) 0x31, - (byte) 0x33, (byte) 0x32, (byte) 0x34, (byte) 0x36, (byte) 0x5a, (byte) 0x30, - (byte) 0x81, (byte) 0xbd, (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, - (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, - (byte) 0x02, (byte) 0x41, (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30, - (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, - (byte) 0x0c, (byte) 0x0a, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, - (byte) 0x2d, (byte) 0x53, (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65, - (byte) 0x31, (byte) 0x12, (byte) 0x30, (byte) 0x10, (byte) 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x0c, (byte) 0x09, (byte) 0x53, - (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x69, - (byte) 0x74, (byte) 0x79, (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, - (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, - (byte) 0x12, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, - (byte) 0x4f, (byte) 0x74, (byte) 0x68, (byte) 0x65, (byte) 0x72, (byte) 0x2d, - (byte) 0x43, (byte) 0x6f, (byte) 0x6d, (byte) 0x70, (byte) 0x61, (byte) 0x6e, - (byte) 0x79, (byte) 0x31, (byte) 0x15, (byte) 0x30, (byte) 0x13, (byte) 0x06, - (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x0c, - (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, - (byte) 0x65, (byte) 0x63, (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e, - (byte) 0x31, (byte) 0x21, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x18, (byte) 0x57, - (byte) 0x69, (byte) 0x66, (byte) 0x69, (byte) 0x45, (byte) 0x6e, (byte) 0x74, - (byte) 0x65, (byte) 0x72, (byte) 0x70, (byte) 0x72, (byte) 0x69, (byte) 0x73, - (byte) 0x65, (byte) 0x43, (byte) 0x6f, (byte) 0x6e, (byte) 0x66, (byte) 0x69, - (byte) 0x67, (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x31, - (byte) 0x2e, (byte) 0x30, (byte) 0x2c, (byte) 0x06, (byte) 0x09, (byte) 0x2a, - (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, - (byte) 0x09, (byte) 0x01, (byte) 0x16, (byte) 0x1f, (byte) 0x61, (byte) 0x6e, - (byte) 0x2d, (byte) 0x65, (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6c, - (byte) 0x2d, (byte) 0x61, (byte) 0x64, (byte) 0x72, (byte) 0x65, (byte) 0x73, - (byte) 0x73, (byte) 0x40, (byte) 0x73, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, - (byte) 0x2d, (byte) 0x64, (byte) 0x6f, (byte) 0x6d, (byte) 0x61, (byte) 0x69, - (byte) 0x6e, (byte) 0x2e, (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, - (byte) 0x82, (byte) 0x01, (byte) 0x22, (byte) 0x30, (byte) 0x0d, (byte) 0x06, - (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, - (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, - (byte) 0x03, (byte) 0x82, (byte) 0x01, (byte) 0x0f, (byte) 0x00, (byte) 0x30, - (byte) 0x82, (byte) 0x01, (byte) 0x0a, (byte) 0x02, (byte) 0x82, (byte) 0x01, - (byte) 0x01, (byte) 0x00, (byte) 0xa9, (byte) 0xa3, (byte) 0x21, (byte) 0xfd, - (byte) 0xa6, (byte) 0xc1, (byte) 0x04, (byte) 0x48, (byte) 0xc2, (byte) 0xc8, - (byte) 0x44, (byte) 0x50, (byte) 0xc4, (byte) 0x6d, (byte) 0x35, (byte) 0x24, - (byte) 0xf0, (byte) 0x6d, (byte) 0x69, (byte) 0xfb, (byte) 0xd1, (byte) 0xfc, - (byte) 0xde, (byte) 0xe9, (byte) 0xdb, (byte) 0xca, (byte) 0xee, (byte) 0x24, - (byte) 0x3d, (byte) 0x85, (byte) 0x8d, (byte) 0x84, (byte) 0xb4, (byte) 0x73, - (byte) 0xd1, (byte) 0x09, (byte) 0x37, (byte) 0x16, (byte) 0x80, (byte) 0x70, - (byte) 0x6b, (byte) 0x61, (byte) 0xcc, (byte) 0xf2, (byte) 0x98, (byte) 0xbd, - (byte) 0x53, (byte) 0x3a, (byte) 0x68, (byte) 0x60, (byte) 0x02, (byte) 0xba, - (byte) 0x0c, (byte) 0x53, (byte) 0x96, (byte) 0xfb, (byte) 0x80, (byte) 0xd1, - (byte) 0x5b, (byte) 0xc3, (byte) 0xcb, (byte) 0x7a, (byte) 0x81, (byte) 0x00, - (byte) 0x5d, (byte) 0x20, (byte) 0x72, (byte) 0xc0, (byte) 0xe4, (byte) 0x48, - (byte) 0x0e, (byte) 0xa2, (byte) 0xcd, (byte) 0xa2, (byte) 0x63, (byte) 0x8c, - (byte) 0x05, (byte) 0x7c, (byte) 0x63, (byte) 0x5b, (byte) 0xda, (byte) 0x0e, - (byte) 0xa7, (byte) 0x05, (byte) 0x09, (byte) 0x6d, (byte) 0xd5, (byte) 0xe4, - (byte) 0x3a, (byte) 0x4e, (byte) 0xa1, (byte) 0xf5, (byte) 0xfd, (byte) 0x47, - (byte) 0xee, (byte) 0x7b, (byte) 0xa3, (byte) 0x4c, (byte) 0x8c, (byte) 0xd3, - (byte) 0xbb, (byte) 0x58, (byte) 0x0f, (byte) 0x1c, (byte) 0x56, (byte) 0x80, - (byte) 0x80, (byte) 0xb5, (byte) 0xf9, (byte) 0x80, (byte) 0xc2, (byte) 0xd1, - (byte) 0x1d, (byte) 0x3f, (byte) 0xe8, (byte) 0x2a, (byte) 0x63, (byte) 0x0b, - (byte) 0x54, (byte) 0x5f, (byte) 0xd4, (byte) 0xcb, (byte) 0xb7, (byte) 0x94, - (byte) 0xe2, (byte) 0x35, (byte) 0x65, (byte) 0x59, (byte) 0xd1, (byte) 0x72, - (byte) 0xa4, (byte) 0xb8, (byte) 0xee, (byte) 0x82, (byte) 0x11, (byte) 0x7a, - (byte) 0x4c, (byte) 0x26, (byte) 0x66, (byte) 0x9b, (byte) 0x27, (byte) 0x3d, - (byte) 0x14, (byte) 0x4b, (byte) 0x4b, (byte) 0xc8, (byte) 0xf0, (byte) 0x6e, - (byte) 0x43, (byte) 0x8f, (byte) 0xee, (byte) 0x1f, (byte) 0xeb, (byte) 0x20, - (byte) 0xe2, (byte) 0x4c, (byte) 0x79, (byte) 0xbf, (byte) 0x21, (byte) 0x0d, - (byte) 0x36, (byte) 0xed, (byte) 0x5f, (byte) 0xcc, (byte) 0x70, (byte) 0x68, - (byte) 0x8a, (byte) 0x05, (byte) 0x7c, (byte) 0x2f, (byte) 0x1b, (byte) 0xe9, - (byte) 0xec, (byte) 0x83, (byte) 0x6e, (byte) 0x9a, (byte) 0x78, (byte) 0x31, - (byte) 0x3d, (byte) 0xf4, (byte) 0xde, (byte) 0x1b, (byte) 0xd2, (byte) 0x76, - (byte) 0x32, (byte) 0x6c, (byte) 0x1e, (byte) 0xc9, (byte) 0x90, (byte) 0x7f, - (byte) 0xc4, (byte) 0x30, (byte) 0xc0, (byte) 0xae, (byte) 0xab, (byte) 0x70, - (byte) 0x08, (byte) 0x78, (byte) 0xbf, (byte) 0x2e, (byte) 0x8b, (byte) 0x07, - (byte) 0xab, (byte) 0x8f, (byte) 0x03, (byte) 0xc5, (byte) 0xd3, (byte) 0xeb, - (byte) 0x98, (byte) 0x19, (byte) 0x50, (byte) 0x83, (byte) 0x52, (byte) 0xf7, - (byte) 0xff, (byte) 0xf5, (byte) 0x89, (byte) 0xe6, (byte) 0xe7, (byte) 0xa7, - (byte) 0xcb, (byte) 0xdf, (byte) 0x96, (byte) 0x9d, (byte) 0x14, (byte) 0x04, - (byte) 0x5e, (byte) 0x45, (byte) 0x82, (byte) 0xf7, (byte) 0x23, (byte) 0x1a, - (byte) 0xb6, (byte) 0x64, (byte) 0x57, (byte) 0xe8, (byte) 0x7e, (byte) 0xa1, - (byte) 0xaf, (byte) 0x58, (byte) 0x68, (byte) 0x70, (byte) 0xc5, (byte) 0x0f, - (byte) 0x8d, (byte) 0x54, (byte) 0xf3, (byte) 0x49, (byte) 0xa3, (byte) 0x97, - (byte) 0x32, (byte) 0xa7, (byte) 0x2a, (byte) 0x79, (byte) 0xbe, (byte) 0xcd, - (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3, - (byte) 0x50, (byte) 0x30, (byte) 0x4e, (byte) 0x30, (byte) 0x1d, (byte) 0x06, - (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16, - (byte) 0x04, (byte) 0x14, (byte) 0xac, (byte) 0xf3, (byte) 0x73, (byte) 0x9a, - (byte) 0x25, (byte) 0x08, (byte) 0x01, (byte) 0x07, (byte) 0x86, (byte) 0x8b, - (byte) 0xc4, (byte) 0xed, (byte) 0xb1, (byte) 0x6b, (byte) 0x53, (byte) 0xa3, - (byte) 0x21, (byte) 0xb4, (byte) 0xb4, (byte) 0x46, (byte) 0x30, (byte) 0x1f, - (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04, - (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0xac, - (byte) 0xf3, (byte) 0x73, (byte) 0x9a, (byte) 0x25, (byte) 0x08, (byte) 0x01, - (byte) 0x07, (byte) 0x86, (byte) 0x8b, (byte) 0xc4, (byte) 0xed, (byte) 0xb1, - (byte) 0x6b, (byte) 0x53, (byte) 0xa3, (byte) 0x21, (byte) 0xb4, (byte) 0xb4, - (byte) 0x46, (byte) 0x30, (byte) 0x0c, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x1d, (byte) 0x13, (byte) 0x04, (byte) 0x05, (byte) 0x30, (byte) 0x03, - (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x30, (byte) 0x0d, (byte) 0x06, - (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, - (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x0b, (byte) 0x05, (byte) 0x00, - (byte) 0x03, (byte) 0x82, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x16, - (byte) 0xf6, (byte) 0xd0, (byte) 0xe1, (byte) 0x14, (byte) 0x2d, (byte) 0x52, - (byte) 0x47, (byte) 0xa2, (byte) 0x89, (byte) 0xe6, (byte) 0x7f, (byte) 0xac, - (byte) 0x88, (byte) 0x04, (byte) 0x15, (byte) 0x21, (byte) 0x00, (byte) 0x72, - (byte) 0xf9, (byte) 0xee, (byte) 0xb2, (byte) 0x1b, (byte) 0x8e, (byte) 0x46, - (byte) 0x8b, (byte) 0x90, (byte) 0x20, (byte) 0x4f, (byte) 0xa7, (byte) 0xae, - (byte) 0x30, (byte) 0xb6, (byte) 0x24, (byte) 0xc5, (byte) 0x54, (byte) 0xaf, - (byte) 0x6c, (byte) 0x1e, (byte) 0xd6, (byte) 0x73, (byte) 0x22, (byte) 0x48, - (byte) 0x07, (byte) 0xb5, (byte) 0x13, (byte) 0x35, (byte) 0xbb, (byte) 0x9e, - (byte) 0xd9, (byte) 0x19, (byte) 0x79, (byte) 0xda, (byte) 0x76, (byte) 0x7f, - (byte) 0xf7, (byte) 0x87, (byte) 0xc9, (byte) 0xc3, (byte) 0x0b, (byte) 0x38, - (byte) 0x20, (byte) 0x26, (byte) 0xfc, (byte) 0x7f, (byte) 0x32, (byte) 0x2a, - (byte) 0xd5, (byte) 0x09, (byte) 0x87, (byte) 0xda, (byte) 0x23, (byte) 0x1f, - (byte) 0x71, (byte) 0x83, (byte) 0x00, (byte) 0x17, (byte) 0xf6, (byte) 0xb9, - (byte) 0x57, (byte) 0x21, (byte) 0xdf, (byte) 0x29, (byte) 0xcc, (byte) 0xdb, - (byte) 0xe9, (byte) 0x2c, (byte) 0xba, (byte) 0x86, (byte) 0x34, (byte) 0x53, - (byte) 0x29, (byte) 0x09, (byte) 0xc7, (byte) 0x3c, (byte) 0x8e, (byte) 0xa3, - (byte) 0x86, (byte) 0x81, (byte) 0x26, (byte) 0x7b, (byte) 0xa1, (byte) 0xbe, - (byte) 0xbc, (byte) 0xc9, (byte) 0x83, (byte) 0xb5, (byte) 0x36, (byte) 0x65, - (byte) 0x51, (byte) 0xb4, (byte) 0x41, (byte) 0xf0, (byte) 0x05, (byte) 0x78, - (byte) 0x3a, (byte) 0xa6, (byte) 0xad, (byte) 0x4b, (byte) 0x08, (byte) 0xd1, - (byte) 0xe4, (byte) 0xf1, (byte) 0x2e, (byte) 0xc7, (byte) 0x23, (byte) 0x6d, - (byte) 0xf0, (byte) 0x9d, (byte) 0x60, (byte) 0x6d, (byte) 0xe7, (byte) 0x11, - (byte) 0xaf, (byte) 0x41, (byte) 0x68, (byte) 0xee, (byte) 0x06, (byte) 0x76, - (byte) 0x82, (byte) 0x48, (byte) 0xee, (byte) 0x41, (byte) 0xc4, (byte) 0xf8, - (byte) 0xe1, (byte) 0x83, (byte) 0xbc, (byte) 0xa8, (byte) 0xbd, (byte) 0x9c, - (byte) 0x17, (byte) 0x45, (byte) 0xf4, (byte) 0x36, (byte) 0x67, (byte) 0x47, - (byte) 0x0e, (byte) 0x32, (byte) 0x13, (byte) 0x6e, (byte) 0xc1, (byte) 0x1e, - (byte) 0x08, (byte) 0xef, (byte) 0x10, (byte) 0xdf, (byte) 0x45, (byte) 0xbf, - (byte) 0x5a, (byte) 0xc4, (byte) 0x44, (byte) 0x4c, (byte) 0xd0, (byte) 0xd5, - (byte) 0x23, (byte) 0xde, (byte) 0xd7, (byte) 0x83, (byte) 0x1e, (byte) 0xb0, - (byte) 0x27, (byte) 0x4d, (byte) 0x57, (byte) 0xa3, (byte) 0xe8, (byte) 0x36, - (byte) 0x52, (byte) 0x1c, (byte) 0x48, (byte) 0x0a, (byte) 0xc4, (byte) 0xd8, - (byte) 0x32, (byte) 0xfc, (byte) 0xd0, (byte) 0x26, (byte) 0x6f, (byte) 0xa4, - (byte) 0x61, (byte) 0x2c, (byte) 0x3a, (byte) 0xa9, (byte) 0xfe, (byte) 0xa4, - (byte) 0x7a, (byte) 0x58, (byte) 0x54, (byte) 0x58, (byte) 0x96, (byte) 0x2b, - (byte) 0x6e, (byte) 0x9c, (byte) 0xc9, (byte) 0x00, (byte) 0xda, (byte) 0xc6, - (byte) 0xbb, (byte) 0x97, (byte) 0xc4, (byte) 0x95, (byte) 0x32, (byte) 0x6b, - (byte) 0x03, (byte) 0x6f, (byte) 0x33, (byte) 0x59, (byte) 0xd4, (byte) 0xa4, - (byte) 0x4a, (byte) 0x29, (byte) 0x29, (byte) 0x9a, (byte) 0xf4, (byte) 0x87, - (byte) 0x26, (byte) 0xe6, (byte) 0xee, (byte) 0x5c, (byte) 0x0b, (byte) 0xe9, - (byte) 0x98, (byte) 0x5d, (byte) 0xab, (byte) 0x31, (byte) 0xa1, (byte) 0x63, - (byte) 0xaa, (byte) 0x1a, (byte) 0xea, (byte) 0x61, (byte) 0x27, (byte) 0x5e, - (byte) 0x9e, (byte) 0x34, (byte) 0x73 - }; - - /** - * Client certificate generated from above and converted with: - * - * openssl x509 -outform d -in usercert.pem | xxd -i | sed 's/0x/(byte) 0x/g' - */ - private static final byte[] FAKE_EC_3 = { - (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0xdf, (byte) 0x30, (byte) 0x82, - (byte) 0x01, (byte) 0xc7, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01, - (byte) 0x02, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x30, (byte) 0x0d, - (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, - (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x0b, (byte) 0x05, - (byte) 0x00, (byte) 0x30, (byte) 0x64, (byte) 0x31, (byte) 0x0b, (byte) 0x30, - (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06, - (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x0b, - (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, - (byte) 0x08, (byte) 0x0c, (byte) 0x02, (byte) 0x43, (byte) 0x41, (byte) 0x31, - (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x04, (byte) 0x07, (byte) 0x0c, (byte) 0x0d, (byte) 0x4d, (byte) 0x6f, - (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6e, - (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77, (byte) 0x31, - (byte) 0x0f, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x06, (byte) 0x47, (byte) 0x6f, - (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, (byte) 0x31, (byte) 0x10, - (byte) 0x30, (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, - (byte) 0x0b, (byte) 0x0c, (byte) 0x07, (byte) 0x41, (byte) 0x6e, (byte) 0x64, - (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x31, (byte) 0x0d, - (byte) 0x30, (byte) 0x0b, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, - (byte) 0x03, (byte) 0x0c, (byte) 0x04, (byte) 0x54, (byte) 0x45, (byte) 0x53, - (byte) 0x54, (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x31, - (byte) 0x37, (byte) 0x30, (byte) 0x31, (byte) 0x32, (byte) 0x37, (byte) 0x31, - (byte) 0x37, (byte) 0x35, (byte) 0x38, (byte) 0x31, (byte) 0x32, (byte) 0x5a, - (byte) 0x17, (byte) 0x0d, (byte) 0x32, (byte) 0x37, (byte) 0x30, (byte) 0x31, - (byte) 0x32, (byte) 0x35, (byte) 0x31, (byte) 0x37, (byte) 0x35, (byte) 0x38, - (byte) 0x31, (byte) 0x32, (byte) 0x5a, (byte) 0x30, (byte) 0x50, (byte) 0x31, - (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, - (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, - (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x02, (byte) 0x43, - (byte) 0x41, (byte) 0x31, (byte) 0x0f, (byte) 0x30, (byte) 0x0d, (byte) 0x06, - (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x06, - (byte) 0x47, (byte) 0x6f, (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, - (byte) 0x31, (byte) 0x10, (byte) 0x30, (byte) 0x0e, (byte) 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x07, (byte) 0x41, - (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, - (byte) 0x31, (byte) 0x11, (byte) 0x30, (byte) 0x0f, (byte) 0x06, (byte) 0x03, - (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x08, (byte) 0x54, - (byte) 0x45, (byte) 0x53, (byte) 0x54, (byte) 0x2d, (byte) 0x55, (byte) 0x53, - (byte) 0x52, (byte) 0x30, (byte) 0x59, (byte) 0x30, (byte) 0x13, (byte) 0x06, - (byte) 0x07, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, - (byte) 0x02, (byte) 0x01, (byte) 0x06, (byte) 0x08, (byte) 0x2a, (byte) 0x86, - (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x03, (byte) 0x01, (byte) 0x07, - (byte) 0x03, (byte) 0x42, (byte) 0x00, (byte) 0x04, (byte) 0x4a, (byte) 0xb8, - (byte) 0x60, (byte) 0x17, (byte) 0x40, (byte) 0x91, (byte) 0x30, (byte) 0xf7, - (byte) 0xdf, (byte) 0x36, (byte) 0x83, (byte) 0x31, (byte) 0xb5, (byte) 0x3a, - (byte) 0xf4, (byte) 0xd4, (byte) 0xa1, (byte) 0xce, (byte) 0xd5, (byte) 0x54, - (byte) 0x97, (byte) 0x93, (byte) 0x7e, (byte) 0x7b, (byte) 0x08, (byte) 0x63, - (byte) 0x37, (byte) 0x62, (byte) 0xf1, (byte) 0x4e, (byte) 0x6a, (byte) 0x2e, - (byte) 0x35, (byte) 0x4e, (byte) 0x9f, (byte) 0x48, (byte) 0xcd, (byte) 0x09, - (byte) 0x17, (byte) 0xb3, (byte) 0xc1, (byte) 0x58, (byte) 0x02, (byte) 0x49, - (byte) 0x7b, (byte) 0x4c, (byte) 0xf7, (byte) 0x9b, (byte) 0xbb, (byte) 0x1b, - (byte) 0x2b, (byte) 0x9c, (byte) 0xe9, (byte) 0x36, (byte) 0xc4, (byte) 0x00, - (byte) 0x81, (byte) 0x2c, (byte) 0x28, (byte) 0xd9, (byte) 0x6b, (byte) 0xad, - (byte) 0xe3, (byte) 0xe8, (byte) 0xa3, (byte) 0x7b, (byte) 0x30, (byte) 0x79, - (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, - (byte) 0x13, (byte) 0x04, (byte) 0x02, (byte) 0x30, (byte) 0x00, (byte) 0x30, - (byte) 0x2c, (byte) 0x06, (byte) 0x09, (byte) 0x60, (byte) 0x86, (byte) 0x48, - (byte) 0x01, (byte) 0x86, (byte) 0xf8, (byte) 0x42, (byte) 0x01, (byte) 0x0d, - (byte) 0x04, (byte) 0x1f, (byte) 0x16, (byte) 0x1d, (byte) 0x4f, (byte) 0x70, - (byte) 0x65, (byte) 0x6e, (byte) 0x53, (byte) 0x53, (byte) 0x4c, (byte) 0x20, - (byte) 0x47, (byte) 0x65, (byte) 0x6e, (byte) 0x65, (byte) 0x72, (byte) 0x61, - (byte) 0x74, (byte) 0x65, (byte) 0x64, (byte) 0x20, (byte) 0x43, (byte) 0x65, - (byte) 0x72, (byte) 0x74, (byte) 0x69, (byte) 0x66, (byte) 0x69, (byte) 0x63, - (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x30, (byte) 0x1d, (byte) 0x06, - (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16, - (byte) 0x04, (byte) 0x14, (byte) 0xef, (byte) 0xf0, (byte) 0x15, (byte) 0xd7, - (byte) 0xc9, (byte) 0x3e, (byte) 0x9a, (byte) 0x73, (byte) 0xfa, (byte) 0x38, - (byte) 0xc5, (byte) 0x81, (byte) 0x84, (byte) 0x74, (byte) 0xd3, (byte) 0x83, - (byte) 0x74, (byte) 0x26, (byte) 0xf1, (byte) 0x0b, (byte) 0x30, (byte) 0x1f, - (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04, - (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0x38, - (byte) 0x6a, (byte) 0x9b, (byte) 0xf8, (byte) 0x3c, (byte) 0x0d, (byte) 0x54, - (byte) 0x9f, (byte) 0xdf, (byte) 0xf8, (byte) 0x53, (byte) 0x32, (byte) 0xa8, - (byte) 0xf7, (byte) 0x09, (byte) 0x15, (byte) 0x08, (byte) 0x76, (byte) 0xab, - (byte) 0x8d, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, - (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, - (byte) 0x01, (byte) 0x0b, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x82, - (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0xa6, (byte) 0x6c, (byte) 0x18, - (byte) 0xa9, (byte) 0x67, (byte) 0x16, (byte) 0x6a, (byte) 0x9e, (byte) 0x23, - (byte) 0xb3, (byte) 0x2a, (byte) 0xb8, (byte) 0x16, (byte) 0x7b, (byte) 0xb4, - (byte) 0xc8, (byte) 0xbc, (byte) 0x51, (byte) 0xe0, (byte) 0x6f, (byte) 0x05, - (byte) 0x66, (byte) 0xa1, (byte) 0x6f, (byte) 0x96, (byte) 0xde, (byte) 0x5b, - (byte) 0x41, (byte) 0x60, (byte) 0xe5, (byte) 0x29, (byte) 0x99, (byte) 0x12, - (byte) 0xfc, (byte) 0xa9, (byte) 0x91, (byte) 0x23, (byte) 0xb7, (byte) 0x9e, - (byte) 0x00, (byte) 0x5f, (byte) 0x93, (byte) 0xd4, (byte) 0xf7, (byte) 0x27, - (byte) 0x29, (byte) 0x77, (byte) 0xfb, (byte) 0x53, (byte) 0x09, (byte) 0xdc, - (byte) 0xe9, (byte) 0xd0, (byte) 0x5c, (byte) 0x92, (byte) 0x6d, (byte) 0xb7, - (byte) 0xcf, (byte) 0x04, (byte) 0xab, (byte) 0xf1, (byte) 0x39, (byte) 0xb9, - (byte) 0x49, (byte) 0x23, (byte) 0x7c, (byte) 0x0f, (byte) 0x15, (byte) 0x27, - (byte) 0xcd, (byte) 0x65, (byte) 0x3c, (byte) 0x6b, (byte) 0x91, (byte) 0x42, - (byte) 0x5a, (byte) 0xfe, (byte) 0xbe, (byte) 0xb8, (byte) 0xa2, (byte) 0xfd, - (byte) 0x67, (byte) 0x43, (byte) 0x4b, (byte) 0xc9, (byte) 0x28, (byte) 0x65, - (byte) 0x1b, (byte) 0x82, (byte) 0x5b, (byte) 0x25, (byte) 0x20, (byte) 0x9b, - (byte) 0xea, (byte) 0x99, (byte) 0xbb, (byte) 0x66, (byte) 0xc1, (byte) 0x8e, - (byte) 0x46, (byte) 0x0b, (byte) 0x4e, (byte) 0x06, (byte) 0xdd, (byte) 0x50, - (byte) 0x51, (byte) 0x64, (byte) 0xe8, (byte) 0x83, (byte) 0x99, (byte) 0x8e, - (byte) 0x53, (byte) 0xe9, (byte) 0x48, (byte) 0x47, (byte) 0x0e, (byte) 0x08, - (byte) 0x5e, (byte) 0x0d, (byte) 0x4a, (byte) 0x54, (byte) 0x17, (byte) 0xc1, - (byte) 0xf8, (byte) 0xcf, (byte) 0xba, (byte) 0x5c, (byte) 0x38, (byte) 0x70, - (byte) 0x33, (byte) 0x31, (byte) 0x22, (byte) 0x03, (byte) 0x6f, (byte) 0x54, - (byte) 0x3c, (byte) 0x41, (byte) 0xf0, (byte) 0x89, (byte) 0x85, (byte) 0xbc, - (byte) 0x77, (byte) 0x3c, (byte) 0xe8, (byte) 0xec, (byte) 0xb4, (byte) 0x35, - (byte) 0x7a, (byte) 0xcc, (byte) 0x8c, (byte) 0x5f, (byte) 0xa1, (byte) 0xed, - (byte) 0xa6, (byte) 0x28, (byte) 0x14, (byte) 0xc7, (byte) 0x8a, (byte) 0xef, - (byte) 0x56, (byte) 0x26, (byte) 0x35, (byte) 0x46, (byte) 0xab, (byte) 0xb0, - (byte) 0x97, (byte) 0xd2, (byte) 0xbd, (byte) 0xa9, (byte) 0x6a, (byte) 0xe4, - (byte) 0x3e, (byte) 0x87, (byte) 0xfb, (byte) 0xe1, (byte) 0x09, (byte) 0x8d, - (byte) 0x33, (byte) 0x12, (byte) 0xcf, (byte) 0xf0, (byte) 0xc0, (byte) 0xb8, - (byte) 0x9b, (byte) 0x9f, (byte) 0xb1, (byte) 0xcb, (byte) 0xac, (byte) 0x76, - (byte) 0xa8, (byte) 0x05, (byte) 0x6b, (byte) 0xcc, (byte) 0x41, (byte) 0xd2, - (byte) 0x26, (byte) 0x73, (byte) 0xfa, (byte) 0x69, (byte) 0xd3, (byte) 0x1f, - (byte) 0xa9, (byte) 0x0c, (byte) 0x6a, (byte) 0xd6, (byte) 0xc9, (byte) 0x35, - (byte) 0xc5, (byte) 0xad, (byte) 0xa1, (byte) 0x98, (byte) 0xc9, (byte) 0x78, - (byte) 0xa0, (byte) 0xe8, (byte) 0x02, (byte) 0x69, (byte) 0x80, (byte) 0x44, - (byte) 0xd9, (byte) 0xe6, (byte) 0xe5, (byte) 0x26, (byte) 0x4f, (byte) 0xcf, - (byte) 0x38, (byte) 0xcb, (byte) 0x55, (byte) 0x8c, (byte) 0x7d, (byte) 0x3c, - (byte) 0xa8, (byte) 0x82, (byte) 0x69, (byte) 0xa3, (byte) 0xdf, (byte) 0x0a, - (byte) 0x79, (byte) 0x7b, (byte) 0xdd, (byte) 0x24, (byte) 0x6a, (byte) 0x21, - (byte) 0x7b, (byte) 0x20, (byte) 0x94, (byte) 0xcd, (byte) 0x15, (byte) 0x92, - (byte) 0xad, (byte) 0x4a, (byte) 0x72, (byte) 0x0b, (byte) 0x0e, (byte) 0xb2, - (byte) 0xc9 - }; - - private static final byte[] FAKE_KEY_3 = { - (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x02, (byte) 0x01, - (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, - (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, - (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82, - (byte) 0x02, (byte) 0x62, (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5e, - (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81, - (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6, (byte) 0x5b, - (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c, (byte) 0x66, - (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86, (byte) 0x8a, - (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3, (byte) 0x02, - (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08, (byte) 0xf3, - (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04, (byte) 0x6d, - (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f, (byte) 0x67, - (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c, (byte) 0xcb, - (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30, (byte) 0xe2, - (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5, (byte) 0x79, - (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b, (byte) 0xce, - (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb, (byte) 0x08, - (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff, (byte) 0x3b, - (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9, (byte) 0xc4, - (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29, (byte) 0x0d, - (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b, (byte) 0x23, - (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78, (byte) 0x08, - (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5, (byte) 0xf1, - (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19, (byte) 0xb4, - (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03, (byte) 0x16, - (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce, (byte) 0x9e, - (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03, (byte) 0x01, - (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x16, - (byte) 0x59, (byte) 0xc3, (byte) 0x24, (byte) 0x1d, (byte) 0x33, (byte) 0x98, - (byte) 0x9c, (byte) 0xc9, (byte) 0xc8, (byte) 0x2c, (byte) 0x88, (byte) 0xbf, - (byte) 0x0a, (byte) 0x01, (byte) 0xce, (byte) 0xfb, (byte) 0x34, (byte) 0x7a, - (byte) 0x58, (byte) 0x7a, (byte) 0xb0, (byte) 0xbf, (byte) 0xa6, (byte) 0xb2, - (byte) 0x60, (byte) 0xbe, (byte) 0x70, (byte) 0x21, (byte) 0xf5, (byte) 0xfc, - (byte) 0x85, (byte) 0x0d, (byte) 0x33, (byte) 0x58, (byte) 0xa1, (byte) 0xe5, - (byte) 0x09, (byte) 0x36, (byte) 0x84, (byte) 0xb2, (byte) 0x04, (byte) 0x0a, - (byte) 0x02, (byte) 0xd3, (byte) 0x88, (byte) 0x1f, (byte) 0x0c, (byte) 0x2b, - (byte) 0x1d, (byte) 0xe9, (byte) 0x3d, (byte) 0xe7, (byte) 0x79, (byte) 0xf9, - (byte) 0x32, (byte) 0x5c, (byte) 0x8a, (byte) 0x75, (byte) 0x49, (byte) 0x12, - (byte) 0xe4, (byte) 0x05, (byte) 0x26, (byte) 0xd4, (byte) 0x2e, (byte) 0x9e, - (byte) 0x1f, (byte) 0xcc, (byte) 0x54, (byte) 0xad, (byte) 0x33, (byte) 0x8d, - (byte) 0x99, (byte) 0x00, (byte) 0xdc, (byte) 0xf5, (byte) 0xb4, (byte) 0xa2, - (byte) 0x2f, (byte) 0xba, (byte) 0xe5, (byte) 0x62, (byte) 0x30, (byte) 0x6d, - (byte) 0xe6, (byte) 0x3d, (byte) 0xeb, (byte) 0x24, (byte) 0xc2, (byte) 0xdc, - (byte) 0x5f, (byte) 0xb7, (byte) 0x16, (byte) 0x35, (byte) 0xa3, (byte) 0x98, - (byte) 0x98, (byte) 0xa8, (byte) 0xef, (byte) 0xe8, (byte) 0xc4, (byte) 0x96, - (byte) 0x6d, (byte) 0x38, (byte) 0xab, (byte) 0x26, (byte) 0x6d, (byte) 0x30, - (byte) 0xc2, (byte) 0xa0, (byte) 0x44, (byte) 0xe4, (byte) 0xff, (byte) 0x7e, - (byte) 0xbe, (byte) 0x7c, (byte) 0x33, (byte) 0xa5, (byte) 0x10, (byte) 0xad, - (byte) 0xd7, (byte) 0x1e, (byte) 0x13, (byte) 0x20, (byte) 0xb3, (byte) 0x1f, - (byte) 0x41, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xf1, (byte) 0x89, - (byte) 0x07, (byte) 0x0f, (byte) 0xe8, (byte) 0xcf, (byte) 0xab, (byte) 0x13, - (byte) 0x2a, (byte) 0x8f, (byte) 0x88, (byte) 0x80, (byte) 0x11, (byte) 0x9a, - (byte) 0x79, (byte) 0xb6, (byte) 0x59, (byte) 0x3a, (byte) 0x50, (byte) 0x6e, - (byte) 0x57, (byte) 0x37, (byte) 0xab, (byte) 0x2a, (byte) 0xd2, (byte) 0xaa, - (byte) 0xd9, (byte) 0x72, (byte) 0x73, (byte) 0xff, (byte) 0x8b, (byte) 0x47, - (byte) 0x76, (byte) 0xdd, (byte) 0xdc, (byte) 0xf5, (byte) 0x97, (byte) 0x44, - (byte) 0x3a, (byte) 0x78, (byte) 0xbe, (byte) 0x17, (byte) 0xb4, (byte) 0x22, - (byte) 0x6f, (byte) 0xe5, (byte) 0x23, (byte) 0x70, (byte) 0x1d, (byte) 0x10, - (byte) 0x5d, (byte) 0xba, (byte) 0x16, (byte) 0x81, (byte) 0xf1, (byte) 0x45, - (byte) 0xce, (byte) 0x30, (byte) 0xb4, (byte) 0xab, (byte) 0x80, (byte) 0xe4, - (byte) 0x98, (byte) 0x31, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xda, - (byte) 0x82, (byte) 0x9d, (byte) 0x3f, (byte) 0xca, (byte) 0x2f, (byte) 0xe1, - (byte) 0xd4, (byte) 0x86, (byte) 0x77, (byte) 0x48, (byte) 0xa6, (byte) 0xab, - (byte) 0xab, (byte) 0x1c, (byte) 0x42, (byte) 0x5c, (byte) 0xd5, (byte) 0xc7, - (byte) 0x46, (byte) 0x59, (byte) 0x91, (byte) 0x3f, (byte) 0xfc, (byte) 0xcc, - (byte) 0xec, (byte) 0xc2, (byte) 0x40, (byte) 0x12, (byte) 0x2c, (byte) 0x8d, - (byte) 0x1f, (byte) 0xa2, (byte) 0x18, (byte) 0x88, (byte) 0xee, (byte) 0x82, - (byte) 0x4a, (byte) 0x5a, (byte) 0x5e, (byte) 0x88, (byte) 0x20, (byte) 0xe3, - (byte) 0x7b, (byte) 0xe0, (byte) 0xd8, (byte) 0x3a, (byte) 0x52, (byte) 0x9a, - (byte) 0x26, (byte) 0x6a, (byte) 0x04, (byte) 0xec, (byte) 0xe8, (byte) 0xb9, - (byte) 0x48, (byte) 0x40, (byte) 0xe1, (byte) 0xe1, (byte) 0x83, (byte) 0xa6, - (byte) 0x67, (byte) 0xa6, (byte) 0xfd, (byte) 0x02, (byte) 0x41, (byte) 0x00, - (byte) 0x89, (byte) 0x72, (byte) 0x3e, (byte) 0xb0, (byte) 0x90, (byte) 0xfd, - (byte) 0x4c, (byte) 0x0e, (byte) 0xd6, (byte) 0x13, (byte) 0x63, (byte) 0xcb, - (byte) 0xed, (byte) 0x38, (byte) 0x88, (byte) 0xb6, (byte) 0x79, (byte) 0xc4, - (byte) 0x33, (byte) 0x6c, (byte) 0xf6, (byte) 0xf8, (byte) 0xd8, (byte) 0xd0, - (byte) 0xbf, (byte) 0x9d, (byte) 0x35, (byte) 0xac, (byte) 0x69, (byte) 0xd2, - (byte) 0x2b, (byte) 0xc1, (byte) 0xf9, (byte) 0x24, (byte) 0x7b, (byte) 0xce, - (byte) 0xcd, (byte) 0xcb, (byte) 0xa7, (byte) 0xb2, (byte) 0x7a, (byte) 0x0a, - (byte) 0x27, (byte) 0x19, (byte) 0xc9, (byte) 0xaf, (byte) 0x0d, (byte) 0x21, - (byte) 0x89, (byte) 0x88, (byte) 0x7c, (byte) 0xad, (byte) 0x9e, (byte) 0x8d, - (byte) 0x47, (byte) 0x6d, (byte) 0x3f, (byte) 0xce, (byte) 0x7b, (byte) 0xa1, - (byte) 0x74, (byte) 0xf1, (byte) 0xa0, (byte) 0xa1, (byte) 0x02, (byte) 0x41, - (byte) 0x00, (byte) 0xd9, (byte) 0xa8, (byte) 0xf5, (byte) 0xfe, (byte) 0xce, - (byte) 0xe6, (byte) 0x77, (byte) 0x6b, (byte) 0xfe, (byte) 0x2d, (byte) 0xe0, - (byte) 0x1e, (byte) 0xb6, (byte) 0x2e, (byte) 0x12, (byte) 0x4e, (byte) 0x40, - (byte) 0xaf, (byte) 0x6a, (byte) 0x7b, (byte) 0x37, (byte) 0x49, (byte) 0x2a, - (byte) 0x96, (byte) 0x25, (byte) 0x83, (byte) 0x49, (byte) 0xd4, (byte) 0x0c, - (byte) 0xc6, (byte) 0x78, (byte) 0x25, (byte) 0x24, (byte) 0x90, (byte) 0x90, - (byte) 0x06, (byte) 0x15, (byte) 0x9e, (byte) 0xfe, (byte) 0xf9, (byte) 0xdf, - (byte) 0x5b, (byte) 0xf3, (byte) 0x7e, (byte) 0x38, (byte) 0x70, (byte) 0xeb, - (byte) 0x57, (byte) 0xd0, (byte) 0xd9, (byte) 0xa7, (byte) 0x0e, (byte) 0x14, - (byte) 0xf7, (byte) 0x95, (byte) 0x68, (byte) 0xd5, (byte) 0xc8, (byte) 0xab, - (byte) 0x9d, (byte) 0x3a, (byte) 0x2b, (byte) 0x51, (byte) 0xf9, (byte) 0x02, - (byte) 0x41, (byte) 0x00, (byte) 0x96, (byte) 0xdf, (byte) 0xe9, (byte) 0x67, - (byte) 0x6c, (byte) 0xdc, (byte) 0x90, (byte) 0x14, (byte) 0xb4, (byte) 0x1d, - (byte) 0x22, (byte) 0x33, (byte) 0x4a, (byte) 0x31, (byte) 0xc1, (byte) 0x9d, - (byte) 0x2e, (byte) 0xff, (byte) 0x9a, (byte) 0x2a, (byte) 0x95, (byte) 0x4b, - (byte) 0x27, (byte) 0x74, (byte) 0xcb, (byte) 0x21, (byte) 0xc3, (byte) 0xd2, - (byte) 0x0b, (byte) 0xb2, (byte) 0x46, (byte) 0x87, (byte) 0xf8, (byte) 0x28, - (byte) 0x01, (byte) 0x8b, (byte) 0xd8, (byte) 0xb9, (byte) 0x4b, (byte) 0xcd, - (byte) 0x9a, (byte) 0x96, (byte) 0x41, (byte) 0x0e, (byte) 0x36, (byte) 0x6d, - (byte) 0x40, (byte) 0x42, (byte) 0xbc, (byte) 0xd9, (byte) 0xd3, (byte) 0x7b, - (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1, - (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51 - }; - - private boolean hasWifi() { - return getContext().getPackageManager().hasSystemFeature( - PackageManager.FEATURE_WIFI); - } - - public void testSettersAndGetters() throws Exception { - if (!hasWifi()) { - return; - } - - WifiEnterpriseConfig config = new WifiEnterpriseConfig(); - assertTrue(config.getEapMethod() == Eap.NONE); - config.setEapMethod(Eap.PEAP); - assertTrue(config.getEapMethod() == Eap.PEAP); - config.setEapMethod(Eap.PWD); - assertTrue(config.getEapMethod() == Eap.PWD); - config.setEapMethod(Eap.TLS); - assertTrue(config.getEapMethod() == Eap.TLS); - config.setEapMethod(Eap.TTLS); - assertTrue(config.getEapMethod() == Eap.TTLS); - assertTrue(config.getPhase2Method() == Phase2.NONE); - config.setPhase2Method(Phase2.PAP); - assertTrue(config.getPhase2Method() == Phase2.PAP); - config.setPhase2Method(Phase2.MSCHAP); - assertTrue(config.getPhase2Method() == Phase2.MSCHAP); - config.setPhase2Method(Phase2.MSCHAPV2); - assertTrue(config.getPhase2Method() == Phase2.MSCHAPV2); - config.setPhase2Method(Phase2.GTC); - assertTrue(config.getPhase2Method() == Phase2.GTC); - config.setIdentity(IDENTITY); - assertTrue(config.getIdentity().equals(IDENTITY)); - config.setAnonymousIdentity(ANON_IDENTITY); - assertTrue(config.getAnonymousIdentity().equals(ANON_IDENTITY)); - config.setPassword(PASSWORD); - assertTrue(config.getPassword().equals(PASSWORD)); - CertificateFactory factory = CertificateFactory.getInstance("X.509"); - X509Certificate cert1 = (X509Certificate) factory.generateCertificate( - new ByteArrayInputStream(FAKE_EC_1)); - X509Certificate cert2 = (X509Certificate) factory.generateCertificate( - new ByteArrayInputStream(FAKE_EC_2)); - config.setCaCertificate(cert1); - assertTrue(config.getCaCertificate().getSerialNumber().equals(cert1.getSerialNumber())); - config.setCaCertificates(new X509Certificate[]{cert1, cert2}); - X509Certificate[] certs = config.getCaCertificates(); - assertTrue(cert1.getSerialNumber().equals(certs[0].getSerialNumber())); - assertTrue(cert2.getSerialNumber().equals(certs[1].getSerialNumber())); - - X509Certificate clientCert = (X509Certificate) factory.generateCertificate( - new ByteArrayInputStream(FAKE_EC_3)); - KeyFactory kf = KeyFactory.getInstance("RSA"); - PrivateKey clientKey = kf.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_3)); - - config.setClientKeyEntry(clientKey, clientCert); - X509Certificate testClientCert = config.getClientCertificate(); - X509Certificate[] testClientCertChain = config.getClientCertificateChain(); - assertTrue(clientCert.getSerialNumber().equals(testClientCert.getSerialNumber())); - assertTrue(testClientCertChain.length == 1); - assertTrue(testClientCertChain[0] == testClientCert); - - config.setClientKeyEntry(null, null); - assertTrue(config.getClientCertificate() == null); - assertTrue(config.getClientCertificateChain() == null); - - config.setClientKeyEntryWithCertificateChain(clientKey, - new X509Certificate[]{clientCert, cert1}); - testClientCert = config.getClientCertificate(); - testClientCertChain = config.getClientCertificateChain(); - assertTrue(clientCert.getSerialNumber().equals(testClientCert.getSerialNumber())); - assertTrue(testClientCertChain.length == 2); - assertTrue(testClientCertChain[0] == testClientCert); - assertTrue(testClientCertChain[1] == cert1); - assertSame(clientKey, config.getClientPrivateKey()); - - config.setSubjectMatch(SUBJECT_MATCH); - assertTrue(config.getSubjectMatch().equals(SUBJECT_MATCH)); - // Hotspot 2.0 related attributes - config.setPlmn(PLMN); - assertTrue(config.getPlmn().equals(PLMN)); - config.setRealm(REALM); - assertTrue(config.getRealm().equals(REALM)); - config.setAltSubjectMatch(ALT_SUBJECT_MATCH); - assertTrue(config.getAltSubjectMatch().equals(ALT_SUBJECT_MATCH)); - config.setDomainSuffixMatch(DOM_SUBJECT_MATCH); - assertTrue(config.getDomainSuffixMatch().equals(DOM_SUBJECT_MATCH)); - } - - public void testEnterpriseConfigDoesNotPrintPassword() { - if(!hasWifi()) { - return; - } - WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); - final String identity = "IdentityIsOkayToBeDisplayedHere"; - final String password = "PasswordIsNotOkayToBeDisplayedHere"; - enterpriseConfig.setIdentity(identity); - enterpriseConfig.setPassword(password); - final String stringRepresentation = enterpriseConfig.toString(); - assertTrue(stringRepresentation.contains(identity)); - assertFalse(stringRepresentation.contains(password)); - } - - public void testGetSetCaCertificateAliases() { - if (!hasWifi()) { - return; - } - WifiEnterpriseConfig config = new WifiEnterpriseConfig(); - - config.setCaCertificateAliases(null); - assertThat(config.getCaCertificateAliases()).isNull(); - - config.setCaCertificateAliases(new String[]{CERTIFICATE_ALIAS1}); - assertThat(config.getCaCertificateAliases()).isEqualTo(new String[]{CERTIFICATE_ALIAS1}); - - config.setCaCertificateAliases(new String[]{CERTIFICATE_ALIAS1, CERTIFICATE_ALIAS2}); - assertThat(config.getCaCertificateAliases()) - .isEqualTo(new String[]{CERTIFICATE_ALIAS1, CERTIFICATE_ALIAS2}); - } - - public void testGetSetCaPath() { - if (!hasWifi()) { - return; - } - WifiEnterpriseConfig config = new WifiEnterpriseConfig(); - - config.setCaPath(""); - assertThat(config.getCaPath()).isEmpty(); - - config.setCaPath(CA_PATH); - assertThat(config.getCaPath()).isEqualTo(CA_PATH); - } - - public void testGetSetClientCertificateAlias() { - if (!hasWifi()) { - return; - } - WifiEnterpriseConfig config = new WifiEnterpriseConfig(); - - config.setClientCertificateAlias(""); - assertThat(config.getClientCertificateAlias()).isEmpty(); - - config.setClientCertificateAlias(CLIENT_CERTIFICATE_ALIAS); - assertThat(config.getClientCertificateAlias()).isEqualTo(CLIENT_CERTIFICATE_ALIAS); - } - - public void testGetSetOcsp() { - if (!hasWifi()) { - return; - } - WifiEnterpriseConfig config = new WifiEnterpriseConfig(); - - config.setOcsp(WifiEnterpriseConfig.OCSP_NONE); - assertThat(config.getOcsp()).isEqualTo(WifiEnterpriseConfig.OCSP_NONE); - - config.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS); - assertThat(config.getOcsp()) - .isEqualTo(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS); - - try { - config.setOcsp(-1); - fail("WifiEnterpriseConfig.setOcsp(-1) did not throw an IllegalArgumentException!"); - } catch (IllegalArgumentException expected) {} - } - - public void testGetSetWapiCertSuite() { - if (!hasWifi()) { - return; - } - WifiEnterpriseConfig config = new WifiEnterpriseConfig(); - - config.setWapiCertSuite(""); - assertThat(config.getWapiCertSuite()).isEmpty(); - - config.setWapiCertSuite(WAPI_CERT_SUITE); - assertThat(config.getWapiCertSuite()).isEqualTo(WAPI_CERT_SUITE); - } - - public void testIsAuthenticationSimBased() { - if (!hasWifi()) { - return; - } - WifiEnterpriseConfig config = new WifiEnterpriseConfig(); - - config.setEapMethod(Eap.AKA); - assertThat(config.isAuthenticationSimBased()).isTrue(); - - config.setEapMethod(Eap.PWD); - assertThat(config.isAuthenticationSimBased()).isFalse(); - - config.setEapMethod(Eap.PEAP); - config.setPhase2Method(Phase2.SIM); - assertThat(config.isAuthenticationSimBased()).isTrue(); - - config.setEapMethod(Eap.PEAP); - config.setPhase2Method(Phase2.NONE); - assertThat(config.isAuthenticationSimBased()).isFalse(); - } - - public void testCopyConstructor() { - if (!hasWifi()) { - return; - } - WifiEnterpriseConfig config = new WifiEnterpriseConfig(); - config.setEapMethod(Eap.WAPI_CERT); - config.setWapiCertSuite(WAPI_CERT_SUITE); - config.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS); - config.setCaPath(CA_PATH); - config.setPassword(PASSWORD); - config.setRealm(REALM); - - WifiEnterpriseConfig copy = new WifiEnterpriseConfig(config); - assertThat(copy.getEapMethod()).isEqualTo(Eap.WAPI_CERT); - assertThat(copy.getWapiCertSuite()).isEqualTo(WAPI_CERT_SUITE); - assertThat(copy.getOcsp()) - .isEqualTo(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS); - assertThat(copy.getCaPath()).isEqualTo(CA_PATH); - assertThat(copy.getPassword()).isEqualTo(PASSWORD); - assertThat(copy.getRealm()).isEqualTo(REALM); - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiFeature.java b/tests/cts/net/src/android/net/wifi/cts/WifiFeature.java deleted file mode 100644 index 3e9fef406e..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/WifiFeature.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2012 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.wifi.cts; - -import android.content.Context; -import android.content.pm.PackageManager; - -public class WifiFeature { - public static boolean isWifiSupported(Context context) { - PackageManager packageManager = context.getPackageManager(); - return packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI); - } - - public static boolean isP2pSupported(Context context) { - PackageManager packageManager = context.getPackageManager(); - return packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT); - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiFrameworkInitializerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiFrameworkInitializerTest.java deleted file mode 100644 index d714ed6b35..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/WifiFrameworkInitializerTest.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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.wifi.cts; - -import android.net.wifi.WifiFrameworkInitializer; -import android.test.AndroidTestCase; - -public class WifiFrameworkInitializerTest extends AndroidTestCase { - /** - * WifiFrameworkInitializer.registerServiceWrappers() should only be called by - * SystemServiceRegistry during boot up when Wifi is first initialized. Calling this API at - * any other time should throw an exception. - */ - public void testRegisterServiceWrappers_failsWhenCalledOutsideOfSystemServiceRegistry() { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - try { - WifiFrameworkInitializer.registerServiceWrappers(); - fail("Expected exception when calling " - + "WifiFrameworkInitializer.registerServiceWrappers() outside of " - + "SystemServiceRegistry!"); - } catch (IllegalStateException expected) {} - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiHotspot2Test.java b/tests/cts/net/src/android/net/wifi/cts/WifiHotspot2Test.java deleted file mode 100644 index a05b81b932..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/WifiHotspot2Test.java +++ /dev/null @@ -1,488 +0,0 @@ -/* - * 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.wifi.cts; - -import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NONE; - -import android.net.Uri; -import android.net.wifi.hotspot2.OsuProvider; -import android.net.wifi.hotspot2.PasspointConfiguration; -import android.net.wifi.hotspot2.pps.Credential; -import android.net.wifi.hotspot2.pps.HomeSp; -import android.test.AndroidTestCase; -import android.text.TextUtils; - -import java.lang.reflect.Constructor; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.cert.CertificateEncodingException; -import java.security.cert.X509Certificate; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -public class WifiHotspot2Test extends AndroidTestCase { - static final int SIM_CREDENTIAL = 0; - static final int USER_CREDENTIAL = 1; - static final int CERT_CREDENTIAL = 2; - private static final String TEST_SSID = "TEST SSID"; - private static final String TEST_FRIENDLY_NAME = "Friendly Name"; - private static final Map TEST_FRIENDLY_NAMES = - new HashMap() { - { - put("en", TEST_FRIENDLY_NAME); - put("kr", TEST_FRIENDLY_NAME + 2); - put("jp", TEST_FRIENDLY_NAME + 3); - } - }; - private static final String TEST_SERVICE_DESCRIPTION = "Dummy Service"; - private static final Uri TEST_SERVER_URI = Uri.parse("https://test.com"); - private static final String TEST_NAI = "test.access.com"; - private static final List TEST_METHOD_LIST = - Arrays.asList(1 /* METHOD_SOAP_XML_SPP */); - @Override - protected void setUp() throws Exception { - super.setUp(); - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - } - - /** - * Tests {@link PasspointConfiguration#getMeteredOverride()} method. - *

    - * Test default value - */ - public void testGetMeteredOverride() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - PasspointConfiguration passpointConfiguration = new PasspointConfiguration(); - assertEquals(METERED_OVERRIDE_NONE, passpointConfiguration.getMeteredOverride()); - } - - /** - * Tests {@link PasspointConfiguration#getSubscriptionExpirationTimeMillis()} method. - *

    - * Test default value - */ - public void testGetSubscriptionExpirationTimeMillis() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - PasspointConfiguration passpointConfiguration = new PasspointConfiguration(); - assertEquals(Long.MIN_VALUE, - passpointConfiguration.getSubscriptionExpirationTimeMillis()); - } - - /** - * Tests {@link PasspointConfiguration#getUniqueId()} method. - *

    - * Test unique identifier is not null - */ - public void testGetUniqueId() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - - // Create a configuration and make sure the unique ID is not null - PasspointConfiguration passpointConfiguration1 = createConfig(SIM_CREDENTIAL, "123456*", - 18 /* EAP_SIM */); - String uniqueId1 = passpointConfiguration1.getUniqueId(); - assertNotNull(uniqueId1); - - // Create another configuration and make sure the unique ID is not null - PasspointConfiguration passpointConfiguration2 = createConfig(SIM_CREDENTIAL, "567890*", - 23 /* EAP_AKA */); - String uniqueId2 = passpointConfiguration2.getUniqueId(); - assertNotNull(uniqueId2); - - // Make sure the IDs are not equal - assertFalse(uniqueId1.equals(uniqueId2)); - - passpointConfiguration2 = createConfig(USER_CREDENTIAL); - assertFalse(uniqueId1.equals(passpointConfiguration2.getUniqueId())); - - passpointConfiguration2 = createConfig(CERT_CREDENTIAL); - assertFalse(uniqueId1.equals(passpointConfiguration2.getUniqueId())); - } - - /** - * Tests {@link PasspointConfiguration#isAutojoinEnabled()} method. - *

    - * Test default value - */ - public void testIsAutojoinEnabled() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - PasspointConfiguration passpointConfiguration = new PasspointConfiguration(); - assertTrue(passpointConfiguration.isAutojoinEnabled()); - } - - /** - * Tests {@link PasspointConfiguration#isMacRandomizationEnabled()} method. - *

    - * Test default value - */ - public void testIsMacRandomizationEnabled() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - PasspointConfiguration passpointConfiguration = new PasspointConfiguration(); - assertTrue(passpointConfiguration.isMacRandomizationEnabled()); - } - - /** - * Tests {@link PasspointConfiguration#isOsuProvisioned()} method. - *

    - * Test default value - */ - public void testIsOsuProvisioned() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - PasspointConfiguration passpointConfiguration = createConfig(USER_CREDENTIAL); - assertFalse(passpointConfiguration.isOsuProvisioned()); - } - - /** - * Tests {@link PasspointConfiguration#PasspointConfiguration(PasspointConfiguration)} method. - *

    - * Test the PasspointConfiguration copy constructor - */ - public void testPasspointConfigurationCopyConstructor() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - PasspointConfiguration passpointConfiguration = createConfig(USER_CREDENTIAL); - PasspointConfiguration copyOfPasspointConfiguration = - new PasspointConfiguration(passpointConfiguration); - assertEquals(passpointConfiguration, copyOfPasspointConfiguration); - } - - /** - * Tests {@link HomeSp#HomeSp(HomeSp)} method. - *

    - * Test the HomeSp copy constructor - */ - public void testHomeSpCopyConstructor() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - HomeSp homeSp = createHomeSp(); - HomeSp copyOfHomeSp = new HomeSp(homeSp); - assertEquals(copyOfHomeSp, homeSp); - } - - /** - * Tests {@link Credential#Credential(Credential)} method. - *

    - * Test the Credential copy constructor - */ - public void testCredentialCopyConstructor() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - Credential credential = createCredentialWithSimCredential("123456*", 18 /* EAP_SIM */); - Credential copyOfCredential = new Credential(credential); - assertEquals(copyOfCredential, credential); - } - - /** - * Tests {@link Credential.UserCredential#UserCredential(Credential.UserCredential)} method. - *

    - * Test the Credential.UserCredential copy constructor - */ - public void testUserCredentialCopyConstructor() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - Credential.UserCredential userCredential = new Credential.UserCredential(); - userCredential.setUsername("username"); - userCredential.setPassword("password"); - userCredential.setEapType(21 /* EAP_TTLS */); - userCredential.setNonEapInnerMethod("MS-CHAP"); - - Credential.UserCredential copyOfUserCredential = - new Credential.UserCredential(userCredential); - assertEquals(copyOfUserCredential, userCredential); - } - - /** - * Tests - * {@link Credential.CertificateCredential#CertificateCredential(Credential.CertificateCredential)} - * method. - *

    - * Test the Credential.CertificateCredential copy constructor - */ - public void testCertCredentialCopyConstructor() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - Credential.CertificateCredential certCredential = new Credential.CertificateCredential(); - certCredential.setCertType("x509v3"); - - Credential.CertificateCredential copyOfCertificateCredential = - new Credential.CertificateCredential(certCredential); - assertEquals(copyOfCertificateCredential, certCredential); - } - - /** - * Tests {@link Credential.SimCredential#SimCredential(Credential.SimCredential)} method. - *

    - * Test the Credential.SimCredential copy constructor - */ - public void testSimCredentialCopyConstructor() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - Credential.SimCredential simCredential = new Credential.SimCredential(); - simCredential.setImsi("1234*"); - simCredential.setEapType(18/* EAP_SIM */); - - Credential.SimCredential copyOfSimCredential = new Credential.SimCredential(simCredential); - assertEquals(copyOfSimCredential, simCredential); - } - - /** - * Tests {@link Credential#getCaCertificate()} method. - *

    - * Test that getting a set certificate produces the same value - */ - public void testCredentialGetCertificate() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - Credential credential = new Credential(); - credential.setCaCertificate(FakeKeys.CA_CERT0); - - assertEquals(FakeKeys.CA_CERT0, credential.getCaCertificate()); - } - - /** - * Tests {@link Credential#getClientCertificateChain()} and {@link - * Credential#setCaCertificates(X509Certificate[])} methods. - *

    - * Test that getting a set client certificate chain produces the same value - */ - public void testCredentialClientCertificateChain() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - Credential credential = new Credential(); - X509Certificate[] certificates = new X509Certificate[]{FakeKeys.CLIENT_CERT}; - credential.setClientCertificateChain(certificates); - - assertTrue(Arrays.equals(certificates, credential.getClientCertificateChain())); - } - - /** - * Tests {@link Credential#getClientPrivateKey()} and - * {@link Credential#setClientPrivateKey(PrivateKey)} - * methods. - *

    - * Test that getting a set client private key produces the same value - */ - public void testCredentialSetGetClientPrivateKey() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - Credential credential = new Credential(); - credential.setClientPrivateKey(FakeKeys.RSA_KEY1); - - assertEquals(FakeKeys.RSA_KEY1, credential.getClientPrivateKey()); - } - - /** - * Tests {@link Credential#getClientPrivateKey()} and - * {@link Credential#setClientPrivateKey(PrivateKey)} - * methods. - *

    - * Test that getting a set client private key produces the same value - */ - public void testCredentialGetClientPrivateKey() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - Credential credential = new Credential(); - credential.setClientPrivateKey(FakeKeys.RSA_KEY1); - - assertEquals(FakeKeys.RSA_KEY1, credential.getClientPrivateKey()); - } - - private static PasspointConfiguration createConfig(int type) throws Exception { - return createConfig(type, "123456*", 18 /* EAP_SIM */); - } - - private static PasspointConfiguration createConfig(int type, String imsi, int eapType) - throws Exception { - PasspointConfiguration config = new PasspointConfiguration(); - config.setHomeSp(createHomeSp()); - switch (type) { - default: - case SIM_CREDENTIAL: - config.setCredential( - createCredentialWithSimCredential(imsi, eapType)); - break; - case USER_CREDENTIAL: - config.setCredential(createCredentialWithUserCredential()); - break; - case CERT_CREDENTIAL: - config.setCredential(createCredentialWithCertificateCredential()); - break; - } - - return config; - } - - /** - * Helper function for generating HomeSp for testing. - * - * @return {@link HomeSp} - */ - private static HomeSp createHomeSp() { - HomeSp homeSp = new HomeSp(); - homeSp.setFqdn("test.com"); - homeSp.setFriendlyName("friendly name"); - homeSp.setRoamingConsortiumOis(new long[]{0x55, 0x66}); - return homeSp; - } - - /** - * Helper function for generating Credential for testing. - * - * @param userCred Instance of UserCredential - * @param certCred Instance of CertificateCredential - * @param simCred Instance of SimCredential - * @param clientCertificateChain Chain of client certificates - * @param clientPrivateKey Client private key - * @param caCerts CA certificates - * @return {@link Credential} - */ - private static Credential createCredential(Credential.UserCredential userCred, - Credential.CertificateCredential certCred, - Credential.SimCredential simCred, - X509Certificate[] clientCertificateChain, PrivateKey clientPrivateKey, - X509Certificate... caCerts) { - Credential cred = new Credential(); - cred.setRealm("realm"); - cred.setUserCredential(userCred); - cred.setCertCredential(certCred); - cred.setSimCredential(simCred); - return cred; - } - - /** - * Helper function for generating certificate credential for testing. - * - * @return {@link Credential} - */ - private static Credential createCredentialWithCertificateCredential() - throws NoSuchAlgorithmException, CertificateEncodingException { - Credential.CertificateCredential certCred = new Credential.CertificateCredential(); - certCred.setCertType("x509v3"); - certCred.setCertSha256Fingerprint( - MessageDigest.getInstance("SHA-256").digest( - FakeKeys.CLIENT_CERT.getEncoded())); - return createCredential(null, certCred, null, new X509Certificate[]{ - FakeKeys.CLIENT_CERT}, - FakeKeys.RSA_KEY1, FakeKeys.CA_CERT0, - FakeKeys.CA_CERT1); - } - - /** - * Helper function for generating SIM credential for testing. - * - * @return {@link Credential} - */ - private static Credential createCredentialWithSimCredential(String imsi, int eapType) { - Credential.SimCredential simCred = new Credential.SimCredential(); - simCred.setImsi(imsi); - simCred.setEapType(eapType); - return createCredential(null, null, simCred, null, null, (X509Certificate[]) null); - } - - /** - * Helper function for generating user credential for testing. - * - * @return {@link Credential} - */ - private static Credential createCredentialWithUserCredential() { - Credential.UserCredential userCred = new Credential.UserCredential(); - userCred.setUsername("username"); - userCred.setPassword("password"); - userCred.setEapType(21 /* EAP_TTLS */); - userCred.setNonEapInnerMethod("MS-CHAP"); - return createCredential(userCred, null, null, null, null, - FakeKeys.CA_CERT0); - } - - /** - * Tests {@link OsuProvider#getFriendlyName()} and {@link OsuProvider#getServerUri()} methods. - *

    - * Test that getting a set friendly name and server URI produces the same value - */ - public void testOsuProviderGetters() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - - // Using Java reflection to construct an OsuProvider instance because its constructor is - // hidden and not available to apps. - Class osuProviderClass = Class.forName("android.net.wifi.hotspot2.OsuProvider"); - Constructor osuProviderClassConstructor = osuProviderClass.getConstructor(String.class, - Map.class, String.class, Uri.class, String.class, List.class); - - OsuProvider osuProvider = (OsuProvider) osuProviderClassConstructor.newInstance(TEST_SSID, - TEST_FRIENDLY_NAMES, TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, - TEST_METHOD_LIST); - String lang = Locale.getDefault().getLanguage(); - String friendlyName = TEST_FRIENDLY_NAMES.get(lang); - if (TextUtils.isEmpty(friendlyName)) { - friendlyName = TEST_FRIENDLY_NAMES.get("en"); - } - assertEquals(friendlyName, osuProvider.getFriendlyName()); - assertEquals(TEST_SERVER_URI, osuProvider.getServerUri()); - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java deleted file mode 100644 index 557710dcba..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (C) 2008 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.wifi.cts; - -import static com.google.common.truth.Truth.assertThat; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.wifi.ScanResult; -import android.net.wifi.SupplicantState; -import android.net.wifi.WifiInfo; -import android.net.wifi.WifiManager; -import android.net.wifi.WifiManager.WifiLock; -import android.platform.test.annotations.AppModeFull; -import android.test.AndroidTestCase; - -import com.android.compatibility.common.util.PollingCheck; -import com.android.compatibility.common.util.SystemUtil; - -import java.nio.charset.StandardCharsets; -import java.util.concurrent.Callable; - -@AppModeFull(reason = "Cannot get WifiManager in instant app mode") -public class WifiInfoTest extends AndroidTestCase { - private static class MySync { - int expectedState = STATE_NULL; - } - - private WifiManager mWifiManager; - private WifiLock mWifiLock; - private static MySync mMySync; - - private static final int STATE_NULL = 0; - private static final int STATE_WIFI_CHANGING = 1; - private static final int STATE_WIFI_CHANGED = 2; - - private static final String TEST_SSID = "Test123"; - private static final String TEST_BSSID = "12:12:12:12:12:12"; - private static final int TEST_RSSI = -60; - private static final int TEST_NETWORK_ID = 5; - private static final int TEST_NETWORK_ID2 = 6; - - private static final String TAG = "WifiInfoTest"; - private static final int TIMEOUT_MSEC = 6000; - private static final int WAIT_MSEC = 60; - private static final int DURATION = 10000; - private IntentFilter mIntentFilter; - private final BroadcastReceiver mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - final String action = intent.getAction(); - if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { - synchronized (mMySync) { - mMySync.expectedState = STATE_WIFI_CHANGED; - mMySync.notify(); - } - } - } - }; - - @Override - protected void setUp() throws Exception { - super.setUp(); - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - mMySync = new MySync(); - mIntentFilter = new IntentFilter(); - mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); - - mContext.registerReceiver(mReceiver, mIntentFilter); - mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); - assertThat(mWifiManager).isNotNull(); - mWifiLock = mWifiManager.createWifiLock(TAG); - mWifiLock.acquire(); - if (!mWifiManager.isWifiEnabled()) - setWifiEnabled(true); - Thread.sleep(DURATION); - assertThat(mWifiManager.isWifiEnabled()).isTrue(); - mMySync.expectedState = STATE_NULL; - } - - @Override - protected void tearDown() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - super.tearDown(); - return; - } - mWifiLock.release(); - mContext.unregisterReceiver(mReceiver); - if (!mWifiManager.isWifiEnabled()) - setWifiEnabled(true); - Thread.sleep(DURATION); - super.tearDown(); - } - - private void setWifiEnabled(boolean enable) throws Exception { - synchronized (mMySync) { - mMySync.expectedState = STATE_WIFI_CHANGING; - if (enable) { - SystemUtil.runShellCommand("svc wifi enable"); - } else { - SystemUtil.runShellCommand("svc wifi disable"); - } - long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; - while (System.currentTimeMillis() < timeout - && mMySync.expectedState == STATE_WIFI_CHANGING) - mMySync.wait(WAIT_MSEC); - } - } - - public void testWifiInfoProperties() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - - // wait for Wifi to be connected - PollingCheck.check( - "Wifi not connected - Please ensure there is a saved network in range of this " - + "device", - 20000, - () -> mWifiManager.getConnectionInfo().getNetworkId() != -1); - - // this test case should in Wifi environment - WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); - - testWifiInfoPropertiesWhileConnected(wifiInfo); - - setWifiEnabled(false); - - PollingCheck.check("getNetworkId not -1", 20000, new Callable() { - @Override - public Boolean call() throws Exception { - WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); - return wifiInfo.getNetworkId() == -1; - } - }); - - PollingCheck.check("getWifiState not disabled", 20000, new Callable() { - @Override - public Boolean call() throws Exception { - return mWifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLED; - } - }); - } - - private void testWifiInfoPropertiesWhileConnected(WifiInfo wifiInfo) { - assertThat(wifiInfo).isNotNull(); - assertThat(wifiInfo.toString()).isNotNull(); - SupplicantState.isValidState(wifiInfo.getSupplicantState()); - WifiInfo.getDetailedStateOf(SupplicantState.DISCONNECTED); - String ssid = wifiInfo.getSSID(); - if (!ssid.startsWith("0x") && !ssid.equals(WifiManager.UNKNOWN_SSID)) { - // Non-hex string should be quoted - assertThat(ssid).startsWith("\""); - assertThat(ssid).endsWith("\""); - } - - assertThat(wifiInfo.getBSSID()).isNotNull(); - assertThat(wifiInfo.getFrequency()).isGreaterThan(0); - assertThat(wifiInfo.getMacAddress()).isNotNull(); - - wifiInfo.getRssi(); - wifiInfo.getIpAddress(); - wifiInfo.getHiddenSSID(); - wifiInfo.getScore(); - - // null for saved networks - assertThat(wifiInfo.getRequestingPackageName()).isNull(); - assertThat(wifiInfo.getPasspointFqdn()).isNull(); - assertThat(wifiInfo.getPasspointProviderFriendlyName()).isNull(); - - // false for saved networks - assertThat(wifiInfo.isEphemeral()).isFalse(); - assertThat(wifiInfo.isOsuAp()).isFalse(); - assertThat(wifiInfo.isPasspointAp()).isFalse(); - - assertThat(wifiInfo.getWifiStandard()).isAnyOf( - ScanResult.WIFI_STANDARD_UNKNOWN, - ScanResult.WIFI_STANDARD_LEGACY, - ScanResult.WIFI_STANDARD_11N, - ScanResult.WIFI_STANDARD_11AC, - ScanResult.WIFI_STANDARD_11AX - ); - - assertThat(wifiInfo.getLostTxPacketsPerSecond()).isAtLeast(0.0); - assertThat(wifiInfo.getRetriedTxPacketsPerSecond()).isAtLeast(0.0); - assertThat(wifiInfo.getSuccessfulRxPacketsPerSecond()).isAtLeast(0.0); - assertThat(wifiInfo.getSuccessfulTxPacketsPerSecond()).isAtLeast(0.0); - - // Can be -1 if link speed is unknown - assertThat(wifiInfo.getLinkSpeed()).isAtLeast(-1); - assertThat(wifiInfo.getTxLinkSpeedMbps()).isAtLeast(-1); - assertThat(wifiInfo.getRxLinkSpeedMbps()).isAtLeast(-1); - assertThat(wifiInfo.getMaxSupportedTxLinkSpeedMbps()).isAtLeast(-1); - assertThat(wifiInfo.getMaxSupportedRxLinkSpeedMbps()).isAtLeast(-1); - } - - /** - * Test that the WifiInfo Builder returns the same values that was set, and that - * calling build multiple times returns different instances. - */ - public void testWifiInfoBuilder() throws Exception { - WifiInfo.Builder builder = new WifiInfo.Builder() - .setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8)) - .setBssid(TEST_BSSID) - .setRssi(TEST_RSSI) - .setNetworkId(TEST_NETWORK_ID); - - WifiInfo info1 = builder.build(); - - assertThat(info1.getSSID()).isEqualTo("\"" + TEST_SSID + "\""); - assertThat(info1.getBSSID()).isEqualTo(TEST_BSSID); - assertThat(info1.getRssi()).isEqualTo(TEST_RSSI); - assertThat(info1.getNetworkId()).isEqualTo(TEST_NETWORK_ID); - - WifiInfo info2 = builder - .setNetworkId(TEST_NETWORK_ID2) - .build(); - - // different instances - assertThat(info1).isNotSameAs(info2); - - // assert that info1 didn't change - assertThat(info1.getSSID()).isEqualTo("\"" + TEST_SSID + "\""); - assertThat(info1.getBSSID()).isEqualTo(TEST_BSSID); - assertThat(info1.getRssi()).isEqualTo(TEST_RSSI); - assertThat(info1.getNetworkId()).isEqualTo(TEST_NETWORK_ID); - - // assert that info2 changed - assertThat(info2.getSSID()).isEqualTo("\"" + TEST_SSID + "\""); - assertThat(info2.getBSSID()).isEqualTo(TEST_BSSID); - assertThat(info2.getRssi()).isEqualTo(TEST_RSSI); - assertThat(info2.getNetworkId()).isEqualTo(TEST_NETWORK_ID2); - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiLockTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiLockTest.java deleted file mode 100644 index fee9ef026a..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/WifiLockTest.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2008 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.wifi.cts; - -import android.content.Context; -import android.net.wifi.WifiManager; -import android.net.wifi.WifiManager.WifiLock; -import android.os.WorkSource; -import android.platform.test.annotations.AppModeFull; -import android.test.AndroidTestCase; - -@AppModeFull(reason = "Cannot get WifiManager in instant app mode") -public class WifiLockTest extends AndroidTestCase { - - private static final String WIFI_TAG = "WifiLockTest"; - - /** - * Verify acquire and release of High Performance wifi locks - */ - public void testHiPerfWifiLock() { - testWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF); - } - - /** - * Verify acquire and release of Low latency wifi locks - */ - public void testLowLatencyWifiLock() { - testWifiLock(WifiManager.WIFI_MODE_FULL_LOW_LATENCY); - } - - private void testWifiLock(int lockType) { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - WifiManager wm = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); - WifiLock wl = wm.createWifiLock(lockType, WIFI_TAG); - - wl.setReferenceCounted(true); - wl.setWorkSource(new WorkSource()); - assertFalse(wl.isHeld()); - wl.acquire(); - assertTrue(wl.isHeld()); - wl.release(); - assertFalse(wl.isHeld()); - wl.acquire(); - wl.acquire(); - assertTrue(wl.isHeld()); - wl.release(); - assertTrue(wl.isHeld()); - wl.release(); - assertFalse(wl.isHeld()); - assertNotNull(wl.toString()); - try { - wl.release(); - fail("should throw out exception because release is called" - +" a greater number of times than acquire"); - } catch (RuntimeException e) { - // expected - } - - wl = wm.createWifiLock(lockType, WIFI_TAG); - wl.setReferenceCounted(false); - assertFalse(wl.isHeld()); - wl.acquire(); - assertTrue(wl.isHeld()); - wl.release(); - assertFalse(wl.isHeld()); - wl.acquire(); - wl.acquire(); - assertTrue(wl.isHeld()); - wl.release(); - assertFalse(wl.isHeld()); - assertNotNull(wl.toString()); - // releasing again after release: but ignored for non-referenced locks - wl.release(); - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java deleted file mode 100644 index 0cf984c08f..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java +++ /dev/null @@ -1,2532 +0,0 @@ -/* - * Copyright (C) 2009 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.wifi.cts; - -import static android.net.NetworkCapabilities.TRANSPORT_WIFI; -import static android.net.wifi.WifiConfiguration.INVALID_NETWORK_ID; -import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_INOUT; - -import static com.google.common.truth.Truth.assertWithMessage; - -import static org.junit.Assert.assertNotEquals; - -import android.app.UiAutomation; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.net.ConnectivityManager; -import android.net.LinkProperties; -import android.net.MacAddress; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.NetworkInfo; -import android.net.NetworkRequest; -import android.net.TetheringManager; -import android.net.Uri; -import android.net.util.MacAddressUtils; -import android.net.wifi.ScanResult; -import android.net.wifi.SoftApCapability; -import android.net.wifi.SoftApConfiguration; -import android.net.wifi.SoftApInfo; -import android.net.wifi.WifiClient; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiInfo; -import android.net.wifi.WifiManager; -import android.net.wifi.WifiManager.WifiLock; -import android.net.wifi.WifiNetworkConnectionStatistics; -import android.net.wifi.hotspot2.ConfigParser; -import android.net.wifi.hotspot2.OsuProvider; -import android.net.wifi.hotspot2.PasspointConfiguration; -import android.net.wifi.hotspot2.ProvisioningCallback; -import android.net.wifi.hotspot2.pps.Credential; -import android.net.wifi.hotspot2.pps.HomeSp; -import android.os.Handler; -import android.os.HandlerExecutor; -import android.os.HandlerThread; -import android.os.Process; -import android.os.SystemClock; -import android.os.UserHandle; -import android.platform.test.annotations.AppModeFull; -import android.provider.Settings; -import android.support.test.uiautomator.UiDevice; -import android.telephony.TelephonyManager; -import android.test.AndroidTestCase; -import android.text.TextUtils; -import android.util.ArraySet; -import android.util.Log; - -import androidx.test.platform.app.InstrumentationRegistry; - -import com.android.compatibility.common.util.PollingCheck; -import com.android.compatibility.common.util.ShellIdentityUtils; -import com.android.compatibility.common.util.SystemUtil; -import com.android.compatibility.common.util.ThrowingRunnable; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.lang.reflect.Constructor; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -@AppModeFull(reason = "Cannot get WifiManager in instant app mode") -public class WifiManagerTest extends AndroidTestCase { - private static class MySync { - int expectedState = STATE_NULL; - } - - private WifiManager mWifiManager; - private ConnectivityManager mConnectivityManager; - private TetheringManager mTetheringManager; - private WifiLock mWifiLock; - private static MySync mMySync; - private List mScanResults = null; - private NetworkInfo mNetworkInfo; - private final Object mLock = new Object(); - private UiDevice mUiDevice; - private boolean mWasVerboseLoggingEnabled; - private boolean mWasScanThrottleEnabled; - private SoftApConfiguration mOriginalSoftApConfig = null; - - // Please refer to WifiManager - private static final int MIN_RSSI = -100; - private static final int MAX_RSSI = -55; - - private static final int STATE_NULL = 0; - private static final int STATE_WIFI_CHANGING = 1; - private static final int STATE_WIFI_ENABLED = 2; - private static final int STATE_WIFI_DISABLED = 3; - private static final int STATE_SCANNING = 4; - private static final int STATE_SCAN_DONE = 5; - - private static final String TAG = "WifiManagerTest"; - private static final String SSID1 = "\"WifiManagerTest\""; - // A full single scan duration is about 6-7 seconds if country code is set - // to US. If country code is set to world mode (00), we would expect a scan - // duration of roughly 8 seconds. So we set scan timeout as 9 seconds here. - private static final int SCAN_TIMEOUT_MSEC = 9000; - private static final int TIMEOUT_MSEC = 6000; - private static final int WAIT_MSEC = 60; - private static final int TEST_WAIT_DURATION_MS = 10_000; - private static final int DURATION_SCREEN_TOGGLE = 2000; - private static final int DURATION_SETTINGS_TOGGLE = 1_000; - private static final int WIFI_SCAN_TEST_INTERVAL_MILLIS = 60 * 1000; - private static final int WIFI_SCAN_TEST_CACHE_DELAY_MILLIS = 3 * 60 * 1000; - private static final int WIFI_SCAN_TEST_ITERATIONS = 5; - - private static final int ENFORCED_NUM_NETWORK_SUGGESTIONS_PER_APP = 50; - - private static final String TEST_PAC_URL = "http://www.example.com/proxy.pac"; - private static final String MANAGED_PROVISIONING_PACKAGE_NAME - = "com.android.managedprovisioning"; - - private static final String TEST_SSID_UNQUOTED = "testSsid1"; - private static final MacAddress TEST_MAC = MacAddress.fromString("aa:bb:cc:dd:ee:ff"); - private static final String TEST_PASSPHRASE = "passphrase"; - private static final String PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT = - "assets/ValidPasspointProfile.base64"; - private static final String TYPE_WIFI_CONFIG = "application/x-wifi-config"; - - private IntentFilter mIntentFilter; - private final BroadcastReceiver mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - final String action = intent.getAction(); - if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { - - synchronized (mMySync) { - if (intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)) { - mScanResults = mWifiManager.getScanResults(); - } else { - mScanResults = null; - } - mMySync.expectedState = STATE_SCAN_DONE; - mMySync.notifyAll(); - } - } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { - int newState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, - WifiManager.WIFI_STATE_UNKNOWN); - synchronized (mMySync) { - if (newState == WifiManager.WIFI_STATE_ENABLED) { - Log.d(TAG, "*** New WiFi state is ENABLED ***"); - mMySync.expectedState = STATE_WIFI_ENABLED; - mMySync.notifyAll(); - } else if (newState == WifiManager.WIFI_STATE_DISABLED) { - Log.d(TAG, "*** New WiFi state is DISABLED ***"); - mMySync.expectedState = STATE_WIFI_DISABLED; - mMySync.notifyAll(); - } - } - } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { - synchronized (mMySync) { - mNetworkInfo = - (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); - if (mNetworkInfo.getState() == NetworkInfo.State.CONNECTED) - mMySync.notifyAll(); - } - } - } - }; - // Initialize with an invalid status value (0) - private int mProvisioningStatus = 0; - // Initialize with an invalid status value (0) - private int mProvisioningFailureStatus = 0; - private boolean mProvisioningComplete = false; - private ProvisioningCallback mProvisioningCallback = new ProvisioningCallback() { - @Override - public void onProvisioningFailure(int status) { - synchronized (mLock) { - mProvisioningFailureStatus = status; - mLock.notify(); - } - } - - @Override - public void onProvisioningStatus(int status) { - synchronized (mLock) { - mProvisioningStatus = status; - mLock.notify(); - } - } - - @Override - public void onProvisioningComplete() { - mProvisioningComplete = true; - } - }; - private static final String TEST_SSID = "TEST SSID"; - private static final String TEST_FRIENDLY_NAME = "Friendly Name"; - private static final Map TEST_FRIENDLY_NAMES = - new HashMap() { - { - put("en", TEST_FRIENDLY_NAME); - put("kr", TEST_FRIENDLY_NAME + 2); - put("jp", TEST_FRIENDLY_NAME + 3); - } - }; - private static final String TEST_SERVICE_DESCRIPTION = "Dummy Service"; - private static final Uri TEST_SERVER_URI = Uri.parse("https://test.com"); - private static final String TEST_NAI = "test.access.com"; - private static final List TEST_METHOD_LIST = - Arrays.asList(1 /* METHOD_SOAP_XML_SPP */); - private final HandlerThread mHandlerThread = new HandlerThread("WifiManagerTest"); - protected final Executor mExecutor; - { - mHandlerThread.start(); - mExecutor = new HandlerExecutor(new Handler(mHandlerThread.getLooper())); - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - mMySync = new MySync(); - mIntentFilter = new IntentFilter(); - mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); - mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); - mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION); - mIntentFilter.addAction(WifiManager.ACTION_PICK_WIFI_NETWORK); - - mContext.registerReceiver(mReceiver, mIntentFilter); - mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); - mConnectivityManager = getContext().getSystemService(ConnectivityManager.class); - mTetheringManager = getContext().getSystemService(TetheringManager.class); - assertNotNull(mWifiManager); - assertNotNull(mTetheringManager); - - // turn on verbose logging for tests - mWasVerboseLoggingEnabled = ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.isVerboseLoggingEnabled()); - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.setVerboseLoggingEnabled(true)); - // Disable scan throttling for tests. - mWasScanThrottleEnabled = ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.isScanThrottleEnabled()); - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.setScanThrottleEnabled(false)); - - mWifiLock = mWifiManager.createWifiLock(TAG); - mWifiLock.acquire(); - if (!mWifiManager.isWifiEnabled()) - setWifiEnabled(true); - mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); - turnScreenOnNoDelay(); - Thread.sleep(TEST_WAIT_DURATION_MS); - assertTrue(mWifiManager.isWifiEnabled()); - synchronized (mMySync) { - mMySync.expectedState = STATE_NULL; - } - - List savedNetworks = ShellIdentityUtils.invokeWithShellPermissions( - mWifiManager::getConfiguredNetworks); - assertFalse("Need at least one saved network", savedNetworks.isEmpty()); - - // Get original config for restore - mOriginalSoftApConfig = ShellIdentityUtils.invokeWithShellPermissions( - mWifiManager::getSoftApConfiguration); - } - - @Override - protected void tearDown() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - super.tearDown(); - return; - } - if (!mWifiManager.isWifiEnabled()) - setWifiEnabled(true); - mWifiLock.release(); - mContext.unregisterReceiver(mReceiver); - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.setScanThrottleEnabled(mWasScanThrottleEnabled)); - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled)); - // restore original softap config - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.setSoftApConfiguration(mOriginalSoftApConfig)); - Thread.sleep(TEST_WAIT_DURATION_MS); - super.tearDown(); - } - - private void setWifiEnabled(boolean enable) throws Exception { - synchronized (mMySync) { - if (mWifiManager.isWifiEnabled() != enable) { - // the new state is different, we expect it to change - mMySync.expectedState = STATE_WIFI_CHANGING; - } else { - mMySync.expectedState = (enable ? STATE_WIFI_ENABLED : STATE_WIFI_DISABLED); - } - // now trigger the change using shell commands. - SystemUtil.runShellCommand("svc wifi " + (enable ? "enable" : "disable")); - waitForExpectedWifiState(enable); - } - } - - private void waitForExpectedWifiState(boolean enabled) throws InterruptedException { - synchronized (mMySync) { - long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; - int expected = (enabled ? STATE_WIFI_ENABLED : STATE_WIFI_DISABLED); - while (System.currentTimeMillis() < timeout - && mMySync.expectedState != expected) { - mMySync.wait(WAIT_MSEC); - } - } - } - - // Get the current scan status from sticky broadcast. - private boolean isScanCurrentlyAvailable() { - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(WifiManager.ACTION_WIFI_SCAN_AVAILABILITY_CHANGED); - Intent intent = mContext.registerReceiver(null, intentFilter); - assertNotNull(intent); - if (intent.getAction().equals(WifiManager.ACTION_WIFI_SCAN_AVAILABILITY_CHANGED)) { - return intent.getBooleanExtra(WifiManager.EXTRA_SCAN_AVAILABLE, false); - } - return false; - } - - private void startScan() throws Exception { - synchronized (mMySync) { - mMySync.expectedState = STATE_SCANNING; - mScanResults = null; - assertTrue(mWifiManager.startScan()); - long timeout = System.currentTimeMillis() + SCAN_TIMEOUT_MSEC; - while (System.currentTimeMillis() < timeout && mMySync.expectedState == STATE_SCANNING) - mMySync.wait(WAIT_MSEC); - } - } - - private void waitForNetworkInfoState(NetworkInfo.State state) throws Exception { - synchronized (mMySync) { - if (mNetworkInfo.getState() == state) return; - long timeout = System.currentTimeMillis() + TIMEOUT_MSEC; - while (System.currentTimeMillis() < timeout - && mNetworkInfo.getState() != state) - mMySync.wait(WAIT_MSEC); - assertTrue(mNetworkInfo.getState() == state); - } - - } - - private void waitForConnection() throws Exception { - waitForNetworkInfoState(NetworkInfo.State.CONNECTED); - } - - private void waitForDisconnection() throws Exception { - waitForNetworkInfoState(NetworkInfo.State.DISCONNECTED); - } - - private boolean existSSID(String ssid) { - for (final WifiConfiguration w : mWifiManager.getConfiguredNetworks()) { - if (w.SSID.equals(ssid)) - return true; - } - return false; - } - - private int findConfiguredNetworks(String SSID, List networks) { - for (final WifiConfiguration w : networks) { - if (w.SSID.equals(SSID)) - return networks.indexOf(w); - } - return -1; - } - - /** - * Test creation of WifiManager Lock. - */ - public void testWifiManagerLock() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - final String TAG = "Test"; - assertNotNull(mWifiManager.createWifiLock(TAG)); - assertNotNull(mWifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, TAG)); - } - - /** - * Test wifi scanning when location scan is turned off. - */ - public void testWifiManagerScanWhenWifiOffLocationTurnedOn() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - if (!hasLocationFeature()) { - Log.d(TAG, "Skipping test as location is not supported"); - return; - } - if (!isLocationEnabled()) { - fail("Please enable location for this test - since Marshmallow WiFi scan results are" - + " empty when location is disabled!"); - } - setWifiEnabled(false); - Thread.sleep(TEST_WAIT_DURATION_MS); - startScan(); - if (mWifiManager.isScanAlwaysAvailable() && isScanCurrentlyAvailable()) { - // Make sure at least one AP is found. - assertNotNull("mScanResult should not be null!", mScanResults); - assertFalse("empty scan results!", mScanResults.isEmpty()); - } else { - // Make sure no scan results are available. - assertNull("mScanResult should be null!", mScanResults); - } - final String TAG = "Test"; - assertNotNull(mWifiManager.createWifiLock(TAG)); - assertNotNull(mWifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, TAG)); - } - - /** - * test point of wifiManager properties: - * 1.enable properties - * 2.DhcpInfo properties - * 3.wifi state - * 4.ConnectionInfo - */ - public void testWifiManagerProperties() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - setWifiEnabled(true); - assertTrue(mWifiManager.isWifiEnabled()); - assertNotNull(mWifiManager.getDhcpInfo()); - assertEquals(WifiManager.WIFI_STATE_ENABLED, mWifiManager.getWifiState()); - mWifiManager.getConnectionInfo(); - setWifiEnabled(false); - assertFalse(mWifiManager.isWifiEnabled()); - } - - /** - * Test WiFi scan timestamp - fails when WiFi scan timestamps are inconsistent with - * {@link SystemClock#elapsedRealtime()} on device.

    - * To run this test in cts-tradefed: - * run cts --class android.net.wifi.cts.WifiManagerTest --method testWifiScanTimestamp - */ - public void testWifiScanTimestamp() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - Log.d(TAG, "Skipping test as WiFi is not supported"); - return; - } - if (!hasLocationFeature()) { - Log.d(TAG, "Skipping test as location is not supported"); - return; - } - if (!isLocationEnabled()) { - fail("Please enable location for this test - since Marshmallow WiFi scan results are" - + " empty when location is disabled!"); - } - if (!mWifiManager.isWifiEnabled()) { - setWifiEnabled(true); - } - // Scan multiple times to make sure scan timestamps increase with device timestamp. - for (int i = 0; i < WIFI_SCAN_TEST_ITERATIONS; ++i) { - startScan(); - // Make sure at least one AP is found. - assertTrue("mScanResult should not be null. This may be due to a scan timeout", - mScanResults != null); - assertFalse("empty scan results!", mScanResults.isEmpty()); - long nowMillis = SystemClock.elapsedRealtime(); - // Keep track of how many APs are fresh in one scan. - int numFreshAps = 0; - for (ScanResult result : mScanResults) { - long scanTimeMillis = TimeUnit.MICROSECONDS.toMillis(result.timestamp); - if (Math.abs(nowMillis - scanTimeMillis) < WIFI_SCAN_TEST_CACHE_DELAY_MILLIS) { - numFreshAps++; - } - } - // At least half of the APs in the scan should be fresh. - int numTotalAps = mScanResults.size(); - String msg = "Stale AP count: " + (numTotalAps - numFreshAps) + ", fresh AP count: " - + numFreshAps; - assertTrue(msg, numFreshAps * 2 >= mScanResults.size()); - if (i < WIFI_SCAN_TEST_ITERATIONS - 1) { - // Wait before running next iteration. - Thread.sleep(WIFI_SCAN_TEST_INTERVAL_MILLIS); - } - } - } - - // Return true if location is enabled. - private boolean isLocationEnabled() { - return Settings.Secure.getInt(getContext().getContentResolver(), - Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF) != - Settings.Secure.LOCATION_MODE_OFF; - } - - // Returns true if the device has location feature. - private boolean hasLocationFeature() { - return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION); - } - - private boolean hasAutomotiveFeature() { - return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); - } - - public void testSignal() { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - final int numLevels = 9; - int expectLevel = 0; - assertEquals(expectLevel, WifiManager.calculateSignalLevel(MIN_RSSI, numLevels)); - assertEquals(numLevels - 1, WifiManager.calculateSignalLevel(MAX_RSSI, numLevels)); - expectLevel = 4; - assertEquals(expectLevel, WifiManager.calculateSignalLevel((MIN_RSSI + MAX_RSSI) / 2, - numLevels)); - int rssiA = 4; - int rssiB = 5; - assertTrue(WifiManager.compareSignalLevel(rssiA, rssiB) < 0); - rssiB = 4; - assertTrue(WifiManager.compareSignalLevel(rssiA, rssiB) == 0); - rssiA = 5; - rssiB = 4; - assertTrue(WifiManager.compareSignalLevel(rssiA, rssiB) > 0); - } - - /** - * Test that {@link WifiManager#calculateSignalLevel(int)} returns a value in the range - * [0, {@link WifiManager#getMaxSignalLevel()}], and its value is monotonically increasing as - * the RSSI increases. - */ - public void testCalculateSignalLevel() { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - - int maxSignalLevel = mWifiManager.getMaxSignalLevel(); - - int prevSignalLevel = 0; - for (int rssi = -150; rssi <= 50; rssi++) { - int signalLevel = mWifiManager.calculateSignalLevel(rssi); - - // between [0, maxSignalLevel] - assertWithMessage("For RSSI=%s", rssi).that(signalLevel).isAtLeast(0); - assertWithMessage("For RSSI=%s", rssi).that(signalLevel).isAtMost(maxSignalLevel); - - // calculateSignalLevel(rssi) <= calculateSignalLevel(rssi + 1) - assertWithMessage("For RSSI=%s", rssi).that(signalLevel).isAtLeast(prevSignalLevel); - prevSignalLevel = signalLevel; - } - } - - public class TestSoftApCallback implements WifiManager.SoftApCallback { - Object softApLock; - int currentState; - int currentFailureReason; - List currentClientList; - SoftApInfo currentSoftApInfo; - SoftApCapability currentSoftApCapability; - MacAddress lastBlockedClientMacAddress; - int lastBlockedClientReason; - boolean onStateChangedCalled = false; - boolean onSoftapInfoChangedCalled = false; - boolean onSoftApCapabilityChangedCalled = false; - boolean onConnectedClientCalled = false; - boolean onBlockedClientConnectingCalled = false; - - TestSoftApCallback(Object lock) { - softApLock = lock; - } - - public boolean getOnStateChangedCalled() { - synchronized(softApLock) { - return onStateChangedCalled; - } - } - - public boolean getOnSoftapInfoChangedCalled() { - synchronized(softApLock) { - return onSoftapInfoChangedCalled; - } - } - - public boolean getOnSoftApCapabilityChangedCalled() { - synchronized(softApLock) { - return onSoftApCapabilityChangedCalled; - } - } - - public boolean getOnConnectedClientCalled() { - synchronized(softApLock) { - return onConnectedClientCalled; - } - } - - public boolean getOnBlockedClientConnectingCalled() { - synchronized(softApLock) { - return onBlockedClientConnectingCalled; - } - } - - public int getCurrentState() { - synchronized(softApLock) { - return currentState; - } - } - - public int getCurrentStateFailureReason() { - synchronized(softApLock) { - return currentFailureReason; - } - } - - public List getCurrentClientList() { - synchronized(softApLock) { - return currentClientList; - } - } - - public SoftApInfo getCurrentSoftApInfo() { - synchronized(softApLock) { - return currentSoftApInfo; - } - } - - public SoftApCapability getCurrentSoftApCapability() { - synchronized(softApLock) { - return currentSoftApCapability; - } - } - - public MacAddress getLastBlockedClientMacAddress() { - synchronized(softApLock) { - return lastBlockedClientMacAddress; - } - } - - public int getLastBlockedClientReason() { - synchronized(softApLock) { - return lastBlockedClientReason; - } - } - - @Override - public void onStateChanged(int state, int failureReason) { - synchronized(softApLock) { - currentState = state; - currentFailureReason = failureReason; - onStateChangedCalled = true; - } - } - - @Override - public void onConnectedClientsChanged(List clients) { - synchronized(softApLock) { - currentClientList = new ArrayList<>(clients); - onConnectedClientCalled = true; - } - } - - @Override - public void onInfoChanged(SoftApInfo softApInfo) { - synchronized(softApLock) { - currentSoftApInfo = softApInfo; - onSoftapInfoChangedCalled = true; - } - } - - @Override - public void onCapabilityChanged(SoftApCapability softApCapability) { - synchronized(softApLock) { - currentSoftApCapability = softApCapability; - onSoftApCapabilityChangedCalled = true; - } - } - - @Override - public void onBlockedClientConnecting(WifiClient client, int blockedReason) { - synchronized(softApLock) { - lastBlockedClientMacAddress = client.getMacAddress(); - lastBlockedClientReason = blockedReason; - onBlockedClientConnectingCalled = true; - } - } - } - - private static class TestLocalOnlyHotspotCallback extends WifiManager.LocalOnlyHotspotCallback { - Object hotspotLock; - WifiManager.LocalOnlyHotspotReservation reservation = null; - boolean onStartedCalled = false; - boolean onStoppedCalled = false; - boolean onFailedCalled = false; - int failureReason = -1; - - TestLocalOnlyHotspotCallback(Object lock) { - hotspotLock = lock; - } - - @Override - public void onStarted(WifiManager.LocalOnlyHotspotReservation r) { - synchronized (hotspotLock) { - reservation = r; - onStartedCalled = true; - hotspotLock.notify(); - } - } - - @Override - public void onStopped() { - synchronized (hotspotLock) { - onStoppedCalled = true; - hotspotLock.notify(); - } - } - - @Override - public void onFailed(int reason) { - synchronized (hotspotLock) { - onFailedCalled = true; - failureReason = reason; - hotspotLock.notify(); - } - } - } - - private TestLocalOnlyHotspotCallback startLocalOnlyHotspot() { - // Location mode must be enabled for this test - if (!isLocationEnabled()) { - fail("Please enable location for this test"); - } - - TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(mLock); - synchronized (mLock) { - try { - mWifiManager.startLocalOnlyHotspot(callback, null); - // now wait for callback - mLock.wait(TEST_WAIT_DURATION_MS); - } catch (InterruptedException e) { - } - // check if we got the callback - assertTrue(callback.onStartedCalled); - - SoftApConfiguration softApConfig = callback.reservation.getSoftApConfiguration(); - assertNotNull(softApConfig); - assertNotNull(softApConfig.toWifiConfiguration()); - if (!hasAutomotiveFeature()) { - assertEquals( - SoftApConfiguration.BAND_2GHZ, - callback.reservation.getSoftApConfiguration().getBand()); - } - assertFalse(callback.onFailedCalled); - assertFalse(callback.onStoppedCalled); - } - return callback; - } - - private void stopLocalOnlyHotspot(TestLocalOnlyHotspotCallback callback, boolean wifiEnabled) { - synchronized (mMySync) { - // we are expecting a new state - mMySync.expectedState = STATE_WIFI_CHANGING; - - // now shut down LocalOnlyHotspot - callback.reservation.close(); - - try { - waitForExpectedWifiState(wifiEnabled); - } catch (InterruptedException e) {} - } - } - - /** - * Verify that calls to startLocalOnlyHotspot succeed with proper permissions. - * - * Note: Location mode must be enabled for this test. - */ - public void testStartLocalOnlyHotspotSuccess() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - // check that softap mode is supported by the device - if (!mWifiManager.isPortableHotspotSupported()) { - return; - } - - boolean wifiEnabled = mWifiManager.isWifiEnabled(); - - TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot(); - - // add sleep to avoid calling stopLocalOnlyHotspot before TetherController initialization. - // TODO: remove this sleep as soon as b/124330089 is fixed. - Log.d(TAG, "Sleeping for 2 seconds"); - Thread.sleep(2000); - - stopLocalOnlyHotspot(callback, wifiEnabled); - - // wifi should either stay on, or come back on - assertEquals(wifiEnabled, mWifiManager.isWifiEnabled()); - } - - /** - * Verify calls to deprecated API's all fail for non-settings apps targeting >= Q SDK. - */ - public void testDeprecatedApis() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - setWifiEnabled(true); - waitForConnection(); // ensures that there is at-least 1 saved network on the device. - - WifiConfiguration wifiConfiguration = new WifiConfiguration(); - wifiConfiguration.SSID = SSID1; - wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); - - assertEquals(INVALID_NETWORK_ID, - mWifiManager.addNetwork(wifiConfiguration)); - assertEquals(INVALID_NETWORK_ID, - mWifiManager.updateNetwork(wifiConfiguration)); - assertFalse(mWifiManager.enableNetwork(0, true)); - assertFalse(mWifiManager.disableNetwork(0)); - assertFalse(mWifiManager.removeNetwork(0)); - assertFalse(mWifiManager.disconnect()); - assertFalse(mWifiManager.reconnect()); - assertFalse(mWifiManager.reassociate()); - assertTrue(mWifiManager.getConfiguredNetworks().isEmpty()); - - boolean wifiEnabled = mWifiManager.isWifiEnabled(); - // now we should fail to toggle wifi state. - assertFalse(mWifiManager.setWifiEnabled(!wifiEnabled)); - Thread.sleep(TEST_WAIT_DURATION_MS); - assertEquals(wifiEnabled, mWifiManager.isWifiEnabled()); - } - - /** - * Verify that applications can only have one registered LocalOnlyHotspot request at a time. - * - * Note: Location mode must be enabled for this test. - */ - public void testStartLocalOnlyHotspotSingleRequestByApps() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - // check that softap mode is supported by the device - if (!mWifiManager.isPortableHotspotSupported()) { - return; - } - - boolean caughtException = false; - - boolean wifiEnabled = mWifiManager.isWifiEnabled(); - - TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot(); - - // now make a second request - this should fail. - TestLocalOnlyHotspotCallback callback2 = new TestLocalOnlyHotspotCallback(mLock); - try { - mWifiManager.startLocalOnlyHotspot(callback2, null); - } catch (IllegalStateException e) { - Log.d(TAG, "Caught the IllegalStateException we expected: called startLOHS twice"); - caughtException = true; - } - if (!caughtException) { - // second start did not fail, should clean up the hotspot. - - // add sleep to avoid calling stopLocalOnlyHotspot before TetherController initialization. - // TODO: remove this sleep as soon as b/124330089 is fixed. - Log.d(TAG, "Sleeping for 2 seconds"); - Thread.sleep(2000); - - stopLocalOnlyHotspot(callback2, wifiEnabled); - } - assertTrue(caughtException); - - // add sleep to avoid calling stopLocalOnlyHotspot before TetherController initialization. - // TODO: remove this sleep as soon as b/124330089 is fixed. - Log.d(TAG, "Sleeping for 2 seconds"); - Thread.sleep(2000); - - stopLocalOnlyHotspot(callback, wifiEnabled); - } - - private static class TestExecutor implements Executor { - private ConcurrentLinkedQueue tasks = new ConcurrentLinkedQueue<>(); - - @Override - public void execute(Runnable task) { - tasks.add(task); - } - - private void runAll() { - Runnable task = tasks.poll(); - while (task != null) { - task.run(); - task = tasks.poll(); - } - } - } - - public void testStartLocalOnlyHotspotWithConfig() throws Exception { - SoftApConfiguration customConfig = new SoftApConfiguration.Builder() - .setBssid(TEST_MAC) - .setSsid(TEST_SSID_UNQUOTED) - .setPassphrase(TEST_PASSPHRASE, SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) - .build(); - TestExecutor executor = new TestExecutor(); - TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(mLock); - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - try { - uiAutomation.adoptShellPermissionIdentity(); - - boolean wifiEnabled = mWifiManager.isWifiEnabled(); - mWifiManager.startLocalOnlyHotspot(customConfig, executor, callback); - Log.d(TAG, "Sleeping for 2 seconds"); - Thread.sleep(2000); - - // Verify callback is run on the supplied executor - assertFalse(callback.onStartedCalled); - executor.runAll(); - assertTrue(callback.onStartedCalled); - - assertNotNull(callback.reservation); - SoftApConfiguration softApConfig = callback.reservation.getSoftApConfiguration(); - assertNotNull(softApConfig); - assertEquals(TEST_MAC, softApConfig.getBssid()); - assertEquals(TEST_SSID_UNQUOTED, softApConfig.getSsid()); - assertEquals(TEST_PASSPHRASE, softApConfig.getPassphrase()); - - // clean up - stopLocalOnlyHotspot(callback, wifiEnabled); - } finally { - uiAutomation.dropShellPermissionIdentity(); - } - } - - /** - * Read the content of the given resource file into a String. - * - * @param filename String name of the file - * @return String - * @throws IOException - */ - private String loadResourceFile(String filename) throws IOException { - InputStream in = getClass().getClassLoader().getResourceAsStream(filename); - BufferedReader reader = new BufferedReader(new InputStreamReader(in)); - StringBuilder builder = new StringBuilder(); - String line; - while ((line = reader.readLine()) != null) { - builder.append(line).append("\n"); - } - return builder.toString(); - } - - /** - * Verify that changing the mac randomization setting of a Passpoint configuration. - */ - public void testMacRandomizationSettingPasspoint() throws Exception { - String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT); - PasspointConfiguration config = - ConfigParser.parsePasspointConfig(TYPE_WIFI_CONFIG, configStr.getBytes()); - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - try { - uiAutomation.adoptShellPermissionIdentity(); - - mWifiManager.addOrUpdatePasspointConfiguration(config); - List passpointConfigs = - mWifiManager.getPasspointConfigurations(); - PasspointConfiguration passpointConfig = passpointConfigs.get(0); - assertEquals(1, passpointConfigs.size()); - assertTrue("Mac randomization should be enabled for passpoint networks by default.", - passpointConfig.isMacRandomizationEnabled()); - - String fqdn = passpointConfig.getHomeSp().getFqdn(); - mWifiManager.setMacRandomizationSettingPasspointEnabled(fqdn, false); - assertFalse("Mac randomization should be disabled by the API call.", - mWifiManager.getPasspointConfigurations().get(0).isMacRandomizationEnabled()); - } finally { - uiAutomation.dropShellPermissionIdentity(); - } - } - /** - * Verify that the {@link android.Manifest.permission#NETWORK_STACK} permission is never held by - * any package. - *

    - * No apps should ever attempt to acquire this permission, since it would give those - * apps extremely broad access to connectivity functionality. - */ - public void testNetworkStackPermission() { - final PackageManager pm = getContext().getPackageManager(); - - final List holding = pm.getPackagesHoldingPermissions(new String[] { - android.Manifest.permission.NETWORK_STACK - }, PackageManager.MATCH_UNINSTALLED_PACKAGES); - for (PackageInfo pi : holding) { - fail("The NETWORK_STACK permission must not be held by " + pi.packageName - + " and must be revoked for security reasons"); - } - } - - /** - * Verify that the {@link android.Manifest.permission#NETWORK_SETTINGS} permission is - * never held by any package. - *

    - * Only Settings, SysUi, NetworkStack and shell apps should ever attempt to acquire - * this permission, since it would give those apps extremely broad access to connectivity - * functionality. The permission is intended to be granted to only those apps with direct user - * access and no others. - */ - public void testNetworkSettingsPermission() { - final PackageManager pm = getContext().getPackageManager(); - - final ArraySet allowedPackages = new ArraySet(); - final ArraySet allowedUIDs = new ArraySet(); - // explicitly add allowed UIDs - allowedUIDs.add(Process.SYSTEM_UID); - allowedUIDs.add(Process.SHELL_UID); - allowedUIDs.add(Process.PHONE_UID); - allowedUIDs.add(Process.NETWORK_STACK_UID); - allowedUIDs.add(Process.NFC_UID); - - // only quick settings is allowed to bind to the BIND_QUICK_SETTINGS_TILE permission, using - // this fact to determined allowed package name for sysui. This is a signature permission, - // so allow any package with this permission. - final List sysuiPackages = pm.getPackagesHoldingPermissions(new String[] { - android.Manifest.permission.BIND_QUICK_SETTINGS_TILE - }, PackageManager.MATCH_UNINSTALLED_PACKAGES); - for (PackageInfo info : sysuiPackages) { - allowedPackages.add(info.packageName); - } - - // the captive portal flow also currently holds the NETWORK_SETTINGS permission - final Intent intent = new Intent(ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN); - final ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DISABLED_COMPONENTS); - if (ri != null) { - allowedPackages.add(ri.activityInfo.packageName); - } - - final List holding = pm.getPackagesHoldingPermissions(new String[] { - android.Manifest.permission.NETWORK_SETTINGS - }, PackageManager.MATCH_UNINSTALLED_PACKAGES); - StringBuilder stringBuilder = new StringBuilder(); - for (PackageInfo pi : holding) { - String packageName = pi.packageName; - - // this is an explicitly allowed package - if (allowedPackages.contains(packageName)) continue; - - // now check if the packages are from allowed UIDs - int uid = -1; - try { - uid = pm.getPackageUidAsUser(packageName, UserHandle.USER_SYSTEM); - } catch (PackageManager.NameNotFoundException e) { - continue; - } - if (!allowedUIDs.contains(uid)) { - stringBuilder.append("The NETWORK_SETTINGS permission must not be held by " - + packageName + ":" + uid + " and must be revoked for security reasons\n"); - } - } - if (stringBuilder.length() > 0) { - fail(stringBuilder.toString()); - } - } - - /** - * Verify that the {@link android.Manifest.permission#NETWORK_SETUP_WIZARD} permission is - * only held by the device setup wizard application. - *

    - * Only the SetupWizard app should ever attempt to acquire this - * permission, since it would give those apps extremely broad access to connectivity - * functionality. The permission is intended to be granted to only the device setup wizard. - */ - public void testNetworkSetupWizardPermission() { - final ArraySet allowedPackages = new ArraySet(); - - final PackageManager pm = getContext().getPackageManager(); - - final Intent intent = new Intent(Intent.ACTION_MAIN); - intent.addCategory(Intent.CATEGORY_SETUP_WIZARD); - final ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DISABLED_COMPONENTS); - String validPkg = ""; - if (ri != null) { - allowedPackages.add(ri.activityInfo.packageName); - validPkg = ri.activityInfo.packageName; - } - - final Intent preIntent = new Intent("com.android.setupwizard.OEM_PRE_SETUP"); - preIntent.addCategory(Intent.CATEGORY_DEFAULT); - final ResolveInfo preRi = pm - .resolveActivity(preIntent, PackageManager.MATCH_DISABLED_COMPONENTS); - String prePackageName = ""; - if (null != preRi) { - prePackageName = preRi.activityInfo.packageName; - } - - final Intent postIntent = new Intent("com.android.setupwizard.OEM_POST_SETUP"); - postIntent.addCategory(Intent.CATEGORY_DEFAULT); - final ResolveInfo postRi = pm - .resolveActivity(postIntent, PackageManager.MATCH_DISABLED_COMPONENTS); - String postPackageName = ""; - if (null != postRi) { - postPackageName = postRi.activityInfo.packageName; - } - if (!TextUtils.isEmpty(prePackageName) && !TextUtils.isEmpty(postPackageName) - && prePackageName.equals(postPackageName)) { - allowedPackages.add(prePackageName); - } - - final List holding = pm.getPackagesHoldingPermissions(new String[]{ - android.Manifest.permission.NETWORK_SETUP_WIZARD - }, PackageManager.MATCH_UNINSTALLED_PACKAGES); - for (PackageInfo pi : holding) { - if (!allowedPackages.contains(pi.packageName)) { - fail("The NETWORK_SETUP_WIZARD permission must not be held by " + pi.packageName - + " and must be revoked for security reasons [" + validPkg + "]"); - } - } - } - - /** - * Verify that the {@link android.Manifest.permission#NETWORK_MANAGED_PROVISIONING} permission - * is only held by the device managed provisioning application. - *

    - * Only the ManagedProvisioning app should ever attempt to acquire this - * permission, since it would give those apps extremely broad access to connectivity - * functionality. The permission is intended to be granted to only the device managed - * provisioning. - */ - public void testNetworkManagedProvisioningPermission() { - final PackageManager pm = getContext().getPackageManager(); - - // TODO(b/115980767): Using hardcoded package name. Need a better mechanism to find the - // managed provisioning app. - // Ensure that the package exists. - final Intent intent = new Intent(Intent.ACTION_MAIN); - intent.setPackage(MANAGED_PROVISIONING_PACKAGE_NAME); - final ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DISABLED_COMPONENTS); - String validPkg = ""; - if (ri != null) { - validPkg = ri.activityInfo.packageName; - } - - final List holding = pm.getPackagesHoldingPermissions(new String[] { - android.Manifest.permission.NETWORK_MANAGED_PROVISIONING - }, PackageManager.MATCH_UNINSTALLED_PACKAGES); - for (PackageInfo pi : holding) { - if (!Objects.equals(pi.packageName, validPkg)) { - fail("The NETWORK_MANAGED_PROVISIONING permission must not be held by " - + pi.packageName + " and must be revoked for security reasons [" - + validPkg +"]"); - } - } - } - - /** - * Verify that the {@link android.Manifest.permission#WIFI_SET_DEVICE_MOBILITY_STATE} permission - * is held by at most one application. - */ - public void testWifiSetDeviceMobilityStatePermission() { - final PackageManager pm = getContext().getPackageManager(); - - final List holding = pm.getPackagesHoldingPermissions(new String[] { - android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE - }, PackageManager.MATCH_UNINSTALLED_PACKAGES); - - List uniquePackageNames = holding - .stream() - .map(pi -> pi.packageName) - .distinct() - .collect(Collectors.toList()); - - if (uniquePackageNames.size() > 1) { - fail("The WIFI_SET_DEVICE_MOBILITY_STATE permission must not be held by more than one " - + "application, but is held by " + uniquePackageNames.size() + " applications: " - + String.join(", ", uniquePackageNames)); - } - } - - /** - * Verify that the {@link android.Manifest.permission#NETWORK_CARRIER_PROVISIONING} permission - * is held by at most one application. - */ - public void testNetworkCarrierProvisioningPermission() { - final PackageManager pm = getContext().getPackageManager(); - - final List holding = pm.getPackagesHoldingPermissions(new String[] { - android.Manifest.permission.NETWORK_CARRIER_PROVISIONING - }, PackageManager.MATCH_UNINSTALLED_PACKAGES); - - List uniquePackageNames = holding - .stream() - .map(pi -> pi.packageName) - .distinct() - .collect(Collectors.toList()); - - if (uniquePackageNames.size() > 2) { - fail("The NETWORK_CARRIER_PROVISIONING permission must not be held by more than two " - + "applications, but is held by " + uniquePackageNames.size() + " applications: " - + String.join(", ", uniquePackageNames)); - } - } - - /** - * Verify that the {@link android.Manifest.permission#WIFI_UPDATE_USABILITY_STATS_SCORE} - * permission is held by at most one application. - */ - public void testUpdateWifiUsabilityStatsScorePermission() { - final PackageManager pm = getContext().getPackageManager(); - - final List holding = pm.getPackagesHoldingPermissions(new String[] { - android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE - }, PackageManager.MATCH_UNINSTALLED_PACKAGES); - - List uniquePackageNames = holding - .stream() - .map(pi -> pi.packageName) - .distinct() - .collect(Collectors.toList()); - - if (uniquePackageNames.size() > 1) { - fail("The WIFI_UPDATE_USABILITY_STATS_SCORE permission must not be held by more than " - + "one application, but is held by " + uniquePackageNames.size() + " applications: " - + String.join(", ", uniquePackageNames)); - } - } - - private void turnScreenOnNoDelay() throws Exception { - mUiDevice.executeShellCommand("input keyevent KEYCODE_WAKEUP"); - mUiDevice.executeShellCommand("wm dismiss-keyguard"); - } - - private void turnScreenOn() throws Exception { - turnScreenOnNoDelay(); - // Since the screen on/off intent is ordered, they will not be sent right now. - Thread.sleep(DURATION_SCREEN_TOGGLE); - } - - private void turnScreenOffNoDelay() throws Exception { - mUiDevice.executeShellCommand("input keyevent KEYCODE_SLEEP"); - } - - private void turnScreenOff() throws Exception { - turnScreenOffNoDelay(); - // Since the screen on/off intent is ordered, they will not be sent right now. - Thread.sleep(DURATION_SCREEN_TOGGLE); - } - - private void assertWifiScanningIsOn() { - if (!mWifiManager.isScanAlwaysAvailable()) { - fail("Wi-Fi scanning should be on."); - } - } - - private void runWithScanningEnabled(ThrowingRunnable r) throws Exception { - boolean wasScanEnabledForTest = false; - if (!mWifiManager.isScanAlwaysAvailable()) { - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.setScanAlwaysAvailable(true)); - wasScanEnabledForTest = true; - } - try { - r.run(); - } finally { - if (wasScanEnabledForTest) { - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.setScanAlwaysAvailable(false)); - } - } - } - - /** - * Verify that Wi-Fi scanning is not turned off when the screen turns off while wifi is disabled - * but location is on. - * @throws Exception - */ - public void testScreenOffDoesNotTurnOffWifiScanningWhenWifiDisabled() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - if (!hasLocationFeature()) { - // skip the test if location is not supported - return; - } - if (!isLocationEnabled()) { - fail("Please enable location for this test - since Marshmallow WiFi scan results are" - + " empty when location is disabled!"); - } - runWithScanningEnabled(() -> { - setWifiEnabled(false); - turnScreenOn(); - assertWifiScanningIsOn(); - // Toggle screen and verify Wi-Fi scanning is still on. - turnScreenOff(); - assertWifiScanningIsOn(); - turnScreenOn(); - assertWifiScanningIsOn(); - }); - } - - /** - * Verify that Wi-Fi scanning is not turned off when the screen turns off while wifi is enabled. - * @throws Exception - */ - public void testScreenOffDoesNotTurnOffWifiScanningWhenWifiEnabled() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - if (!hasLocationFeature()) { - // skip the test if location is not supported - return; - } - if (!isLocationEnabled()) { - fail("Please enable location for this test - since Marshmallow WiFi scan results are" - + " empty when location is disabled!"); - } - runWithScanningEnabled(() -> { - setWifiEnabled(true); - turnScreenOn(); - assertWifiScanningIsOn(); - // Toggle screen and verify Wi-Fi scanning is still on. - turnScreenOff(); - assertWifiScanningIsOn(); - turnScreenOn(); - assertWifiScanningIsOn(); - }); - } - - /** - * Verify that the platform supports a reasonable number of suggestions per app. - * @throws Exception - */ - public void testMaxNumberOfNetworkSuggestionsPerApp() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - assertTrue(mWifiManager.getMaxNumberOfNetworkSuggestionsPerApp() - > ENFORCED_NUM_NETWORK_SUGGESTIONS_PER_APP); - } - - private void verifyRegisterSoftApCallback(TestExecutor executor, TestSoftApCallback callback) - throws Exception{ - // Register callback to get SoftApCapability - mWifiManager.registerSoftApCallback(executor, callback); - PollingCheck.check( - "SoftAp register failed!", 1_000, - () -> { executor.runAll(); - // Verify callback is run on the supplied executor and called - return callback.getOnStateChangedCalled() && - callback.getOnSoftapInfoChangedCalled() && - callback.getOnSoftApCapabilityChangedCalled() && - callback.getOnConnectedClientCalled(); - }); - } - - private void verifySetGetSoftApConfig(SoftApConfiguration targetConfig) { - mWifiManager.setSoftApConfiguration(targetConfig); - // Bssid set dodesn't support for tethered hotspot - SoftApConfiguration currentConfig = mWifiManager.getSoftApConfiguration(); - compareSoftApConfiguration(targetConfig, currentConfig); - } - - private void compareSoftApConfiguration(SoftApConfiguration currentConfig, - SoftApConfiguration testSoftApConfig) { - assertEquals(currentConfig.getSsid(), testSoftApConfig.getSsid()); - assertEquals(currentConfig.getBssid(), testSoftApConfig.getBssid()); - assertEquals(currentConfig.getSecurityType(), testSoftApConfig.getSecurityType()); - assertEquals(currentConfig.getPassphrase(), testSoftApConfig.getPassphrase()); - assertEquals(currentConfig.isHiddenSsid(), testSoftApConfig.isHiddenSsid()); - assertEquals(currentConfig.getBand(), testSoftApConfig.getBand()); - assertEquals(currentConfig.getChannel(), testSoftApConfig.getChannel()); - assertEquals(currentConfig.getMaxNumberOfClients(), - testSoftApConfig.getMaxNumberOfClients()); - assertEquals(currentConfig.isAutoShutdownEnabled(), - testSoftApConfig.isAutoShutdownEnabled()); - assertEquals(currentConfig.getShutdownTimeoutMillis(), - testSoftApConfig.getShutdownTimeoutMillis()); - assertEquals(currentConfig.isClientControlByUserEnabled(), - testSoftApConfig.isClientControlByUserEnabled()); - assertEquals(currentConfig.getAllowedClientList(), - testSoftApConfig.getAllowedClientList()); - assertEquals(currentConfig.getBlockedClientList(), - testSoftApConfig.getBlockedClientList()); - } - - private void turnOffWifiAndTetheredHotspotIfEnabled() throws Exception { - if (mWifiManager.isWifiEnabled()) { - Log.d(TAG, "Turn off WiFi"); - mWifiManager.setWifiEnabled(false); - PollingCheck.check( - "Wifi turn off failed!", 2_000, - () -> mWifiManager.isWifiEnabled() == false); - } - if (mWifiManager.isWifiApEnabled()) { - mTetheringManager.stopTethering(ConnectivityManager.TETHERING_WIFI); - Log.d(TAG, "Turn off tethered Hotspot"); - PollingCheck.check( - "SoftAp turn off failed!", 2_000, - () -> mWifiManager.isWifiApEnabled() == false); - mTetheringManager.stopTethering(ConnectivityManager.TETHERING_WIFI); - } - } - - /** - * Verify that the configuration from getSoftApConfiguration is same as the configuration which - * set by setSoftApConfiguration. And depends softap capability callback to test different - * configuration. - * @throws Exception - */ - public void testSetGetSoftApConfigurationAndSoftApCapabilityCallback() throws Exception { - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - TestExecutor executor = new TestExecutor(); - TestSoftApCallback callback = new TestSoftApCallback(mLock); - try { - uiAutomation.adoptShellPermissionIdentity(); - turnOffWifiAndTetheredHotspotIfEnabled(); - verifyRegisterSoftApCallback(executor, callback); - - SoftApConfiguration.Builder softApConfigBuilder = new SoftApConfiguration.Builder() - .setSsid(TEST_SSID_UNQUOTED) - .setBssid(TEST_MAC) - .setPassphrase(TEST_PASSPHRASE, SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) - .setAutoShutdownEnabled(true) - .setShutdownTimeoutMillis(100000) - .setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ) - .setHiddenSsid(false); - - // Test SoftApConfiguration set and get - verifySetGetSoftApConfig(softApConfigBuilder.build()); - - // Test CLIENT_FORCE_DISCONNECT supported config. - if (callback.getCurrentSoftApCapability() - .areFeaturesSupported( - SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT)) { - softApConfigBuilder.setMaxNumberOfClients(10); - softApConfigBuilder.setClientControlByUserEnabled(true); - softApConfigBuilder.setBlockedClientList(new ArrayList<>()); - softApConfigBuilder.setAllowedClientList(new ArrayList<>()); - verifySetGetSoftApConfig(softApConfigBuilder.build()); - } - - // Test SAE config - if (callback.getCurrentSoftApCapability() - .areFeaturesSupported(SoftApCapability.SOFTAP_FEATURE_WPA3_SAE)) { - softApConfigBuilder - .setPassphrase(TEST_PASSPHRASE, - SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION); - verifySetGetSoftApConfig(softApConfigBuilder.build()); - softApConfigBuilder - .setPassphrase(TEST_PASSPHRASE, - SoftApConfiguration.SECURITY_TYPE_WPA3_SAE); - verifySetGetSoftApConfig(softApConfigBuilder.build()); - } - } finally { - mWifiManager.unregisterSoftApCallback(callback); - uiAutomation.dropShellPermissionIdentity(); - } - } - - /** - * Verify that startTetheredHotspot with specific channel config. - * @throws Exception - */ - public void testStartTetheredHotspotWithChannelConfigAndSoftApStateAndInfoCallback() - throws Exception { - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - TestExecutor executor = new TestExecutor(); - TestSoftApCallback callback = new TestSoftApCallback(mLock); - try { - uiAutomation.adoptShellPermissionIdentity(); - turnOffWifiAndTetheredHotspotIfEnabled(); - verifyRegisterSoftApCallback(executor, callback); - - SoftApConfiguration testSoftApConfig = new SoftApConfiguration.Builder() - .setSsid(TEST_SSID_UNQUOTED) - .setPassphrase(TEST_PASSPHRASE, SoftApConfiguration.SECURITY_TYPE_WPA2_PSK) - .setChannel(11, SoftApConfiguration.BAND_2GHZ) // Channel 11 = Freq 2462 - .build(); - - mWifiManager.setSoftApConfiguration(testSoftApConfig); - - // start tethering which used to verify startTetheredHotspot - mTetheringManager.startTethering(ConnectivityManager.TETHERING_WIFI, executor, - new TetheringManager.StartTetheringCallback() { - @Override - public void onTetheringFailed(final int result) { - } - }); - - // Verify state and info callback value as expected - PollingCheck.check( - "SoftAp channel and state mismatch!!!", 5_000, - () -> { executor.runAll(); - return WifiManager.WIFI_AP_STATE_ENABLED == callback.getCurrentState() && - 2462 == callback.getCurrentSoftApInfo().getFrequency(); - }); - - // stop tethering which used to verify stopSoftAp - mTetheringManager.stopTethering(ConnectivityManager.TETHERING_WIFI); - - // Verify clean up - PollingCheck.check( - "Stop Softap failed", 2_000, - () -> { executor.runAll(); - return WifiManager.WIFI_AP_STATE_DISABLED == callback.getCurrentState() && - 0 == callback.getCurrentSoftApInfo().getBandwidth() && - 0 == callback.getCurrentSoftApInfo().getFrequency(); - }); - } finally { - mWifiManager.unregisterSoftApCallback(callback); - uiAutomation.dropShellPermissionIdentity(); - } - } - - private static class TestActionListener implements WifiManager.ActionListener { - private final Object mLock; - public boolean onSuccessCalled = false; - public boolean onFailedCalled = false; - public int failureReason = -1; - - TestActionListener(Object lock) { - mLock = lock; - } - - @Override - public void onSuccess() { - synchronized (mLock) { - onSuccessCalled = true; - mLock.notify(); - } - } - - @Override - public void onFailure(int reason) { - synchronized (mLock) { - onFailedCalled = true; - failureReason = reason; - mLock.notify(); - } - } - } - - /** - * Triggers connection to one of the saved networks using {@link WifiManager#connect( - * int, WifiManager.ActionListener)} or {@link WifiManager#connect(WifiConfiguration, - * WifiManager.ActionListener)} - * - * @param withNetworkId Use networkId for triggering connection, false for using - * WifiConfiguration. - * @throws Exception - */ - private void testConnect(boolean withNetworkId) throws Exception { - TestActionListener actionListener = new TestActionListener(mLock); - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - List savedNetworks = null; - try { - uiAutomation.adoptShellPermissionIdentity(); - // These below API's only work with privileged permissions (obtained via shell identity - // for test) - savedNetworks = mWifiManager.getConfiguredNetworks(); - - // Disable all the saved networks to trigger disconnect & disable autojoin. - for (WifiConfiguration network : savedNetworks) { - assertTrue(mWifiManager.disableNetwork(network.networkId)); - } - waitForDisconnection(); - - // Now trigger connection to the first saved network. - synchronized (mLock) { - try { - if (withNetworkId) { - mWifiManager.connect(savedNetworks.get(0).networkId, actionListener); - } else { - mWifiManager.connect(savedNetworks.get(0), actionListener); - } - // now wait for callback - mLock.wait(TEST_WAIT_DURATION_MS); - } catch (InterruptedException e) { - } - } - // check if we got the success callback - assertTrue(actionListener.onSuccessCalled); - // Wait for connection to complete & ensure we are connected to the saved network. - waitForConnection(); - assertEquals(savedNetworks.get(0).networkId, - mWifiManager.getConnectionInfo().getNetworkId()); - } finally { - // Re-enable all saved networks before exiting. - if (savedNetworks != null) { - for (WifiConfiguration network : savedNetworks) { - mWifiManager.enableNetwork(network.networkId, false); - } - } - uiAutomation.dropShellPermissionIdentity(); - } - } - - /** - * Tests {@link WifiManager#connect(int, WifiManager.ActionListener)} to an existing saved - * network. - */ - public void testConnectWithNetworkId() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - testConnect(true); - } - - /** - * Tests {@link WifiManager#connect(WifiConfiguration, WifiManager.ActionListener)} to an - * existing saved network. - */ - public void testConnectWithWifiConfiguration() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - testConnect(false); - - } - - private static class TestNetworkCallback extends ConnectivityManager.NetworkCallback { - private final Object mLock; - public boolean onAvailableCalled = false; - public Network network; - public NetworkCapabilities networkCapabilities; - - TestNetworkCallback(Object lock) { - mLock = lock; - } - - @Override - public void onAvailable(Network network, NetworkCapabilities networkCapabilities, - LinkProperties linkProperties, boolean blocked) { - synchronized (mLock) { - onAvailableCalled = true; - this.network = network; - this.networkCapabilities = networkCapabilities; - mLock.notify(); - } - } - } - - private void waitForNetworkCallbackAndCheckForMeteredness(boolean expectMetered) { - TestNetworkCallback networkCallbackListener = new TestNetworkCallback(mLock); - synchronized (mLock) { - try { - // File a request for wifi network. - mConnectivityManager.registerNetworkCallback( - new NetworkRequest.Builder() - .addTransportType(TRANSPORT_WIFI) - .build(), - networkCallbackListener); - // now wait for callback - mLock.wait(TEST_WAIT_DURATION_MS); - } catch (InterruptedException e) { - } - } - assertTrue(networkCallbackListener.onAvailableCalled); - assertNotEquals(expectMetered, networkCallbackListener.networkCapabilities.hasCapability( - NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); - } - - /** - * Tests {@link WifiManager#save(WifiConfiguration, WifiManager.ActionListener)} by marking - * an existing saved network metered. - */ - public void testSave() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - TestActionListener actionListener = new TestActionListener(mLock); - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - List savedNetworks = null; - WifiConfiguration savedNetwork = null; - try { - uiAutomation.adoptShellPermissionIdentity(); - // These below API's only work with privileged permissions (obtained via shell identity - // for test) - savedNetworks = mWifiManager.getConfiguredNetworks(); - - // Ensure that the saved network is not metered. - savedNetwork = savedNetworks.get(0); - assertNotEquals("Ensure that the saved network is configured as unmetered", - savedNetwork.meteredOverride, - WifiConfiguration.METERED_OVERRIDE_METERED); - - // Trigger a scan & wait for connection to one of the saved networks. - mWifiManager.startScan(); - waitForConnection(); - - // Check the network capabilities to ensure that the network is marked not metered. - waitForNetworkCallbackAndCheckForMeteredness(false); - - // Now mark the network metered and save. - synchronized (mLock) { - try { - WifiConfiguration modSavedNetwork = new WifiConfiguration(savedNetwork); - modSavedNetwork.meteredOverride = WifiConfiguration.METERED_OVERRIDE_METERED; - mWifiManager.save(modSavedNetwork, actionListener); - // now wait for callback - mLock.wait(TEST_WAIT_DURATION_MS); - } catch (InterruptedException e) { - } - } - // check if we got the success callback - assertTrue(actionListener.onSuccessCalled); - // Check the network capabilities to ensure that the network is marked metered now. - waitForNetworkCallbackAndCheckForMeteredness(true); - - } finally { - // Restore original network config (restore the meteredness back); - if (savedNetwork != null) { - mWifiManager.updateNetwork(savedNetwork); - } - uiAutomation.dropShellPermissionIdentity(); - } - } - - /** - * Tests {@link WifiManager#forget(int, WifiManager.ActionListener)} by adding/removing a new - * network. - */ - public void testForget() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - TestActionListener actionListener = new TestActionListener(mLock); - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - int newNetworkId = INVALID_NETWORK_ID; - try { - uiAutomation.adoptShellPermissionIdentity(); - // These below API's only work with privileged permissions (obtained via shell identity - // for test) - List savedNetworks = mWifiManager.getConfiguredNetworks(); - - WifiConfiguration newOpenNetwork = new WifiConfiguration(); - newOpenNetwork.SSID = "\"" + TEST_SSID_UNQUOTED + "\""; - newNetworkId = mWifiManager.addNetwork(newOpenNetwork); - assertNotEquals(INVALID_NETWORK_ID, newNetworkId); - - assertEquals(savedNetworks.size() + 1, mWifiManager.getConfiguredNetworks().size()); - - // Now remove the network - synchronized (mLock) { - try { - mWifiManager.forget(newNetworkId, actionListener); - // now wait for callback - mLock.wait(TEST_WAIT_DURATION_MS); - } catch (InterruptedException e) { - } - } - // check if we got the success callback - assertTrue(actionListener.onSuccessCalled); - - // Ensure that the new network has been successfully removed. - assertEquals(savedNetworks.size(), mWifiManager.getConfiguredNetworks().size()); - } finally { - // For whatever reason, if the forget fails, try removing using the public remove API. - if (newNetworkId != INVALID_NETWORK_ID) mWifiManager.removeNetwork(newNetworkId); - uiAutomation.dropShellPermissionIdentity(); - } - } - - /** - * Tests {@link WifiManager#getFactoryMacAddresses()} returns at least one valid MAC address. - */ - public void testGetFactoryMacAddresses() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - TestActionListener actionListener = new TestActionListener(mLock); - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - int newNetworkId = INVALID_NETWORK_ID; - try { - uiAutomation.adoptShellPermissionIdentity(); - // Obtain the factory MAC address - String[] macAddresses = mWifiManager.getFactoryMacAddresses(); - assertTrue("At list one MAC address should be returned.", macAddresses.length > 0); - try { - MacAddress mac = MacAddress.fromString(macAddresses[0]); - assertNotEquals(WifiInfo.DEFAULT_MAC_ADDRESS, mac); - assertFalse(MacAddressUtils.isMulticastAddress(mac)); - } catch (IllegalArgumentException e) { - fail("Factory MAC address is invalid"); - } - } finally { - uiAutomation.dropShellPermissionIdentity(); - } - } - - /** - * Tests {@link WifiManager#isApMacRandomizationSupported()} does not crash. - */ - public void testIsApMacRandomizationSupported() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - mWifiManager.isApMacRandomizationSupported(); - } - - /** - * Tests {@link WifiManager#isConnectedMacRandomizationSupported()} does not crash. - */ - public void testIsConnectedMacRandomizationSupported() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - mWifiManager.isConnectedMacRandomizationSupported(); - } - - /** - * Tests {@link WifiManager#isPreferredNetworkOffloadSupported()} does not crash. - */ - public void testIsPreferredNetworkOffloadSupported() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - mWifiManager.isPreferredNetworkOffloadSupported(); - } - - /** Test that PNO scans reconnects us when the device is disconnected and the screen is off. */ - public void testPnoScan() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - if (!mWifiManager.isPreferredNetworkOffloadSupported()) { - // skip the test if PNO scanning is not supported - return; - } - - // make sure we're connected - waitForConnection(); - - WifiInfo currentNetwork = ShellIdentityUtils.invokeWithShellPermissions( - mWifiManager::getConnectionInfo); - - // disable all networks that aren't already disabled - List savedNetworks = ShellIdentityUtils.invokeWithShellPermissions( - mWifiManager::getConfiguredNetworks); - Set disabledNetworkIds = new HashSet<>(); - for (WifiConfiguration config : savedNetworks) { - if (config.getNetworkSelectionStatus().getNetworkSelectionDisableReason() - == WifiConfiguration.NetworkSelectionStatus.DISABLED_NONE) { - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.disableNetwork(config.networkId)); - disabledNetworkIds.add(config.networkId); - } - } - - try { - // wait for disconnection from current network - waitForDisconnection(); - - // turn screen off - turnScreenOffNoDelay(); - - // re-enable the current network - this will trigger PNO - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.enableNetwork(currentNetwork.getNetworkId(), false)); - disabledNetworkIds.remove(currentNetwork.getNetworkId()); - - // PNO should reconnect us back to the network we disconnected from - waitForConnection(); - } finally { - // re-enable disabled networks - for (int disabledNetworkId : disabledNetworkIds) { - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.enableNetwork(disabledNetworkId, false)); - } - } - } - - /** - * Tests {@link WifiManager#isTdlsSupported()} does not crash. - */ - public void testIsTdlsSupported() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - mWifiManager.isTdlsSupported(); - } - - /** - * Tests {@link WifiManager#isStaApConcurrencySupported(). - */ - public void testIsStaApConcurrencySupported() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - // check that softap mode is supported by the device - if (!mWifiManager.isPortableHotspotSupported()) { - return; - } - assertTrue(mWifiManager.isWifiEnabled()); - - boolean isStaApConcurrencySupported = mWifiManager.isStaApConcurrencySupported(); - // start local only hotspot. - TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot(); - if (isStaApConcurrencySupported) { - assertTrue(mWifiManager.isWifiEnabled()); - } else { - // no concurrency, wifi should be disabled. - assertFalse(mWifiManager.isWifiEnabled()); - } - stopLocalOnlyHotspot(callback, true); - - assertTrue(mWifiManager.isWifiEnabled()); - } - - private static class TestTrafficStateCallback implements WifiManager.TrafficStateCallback { - private final Object mLock; - private final int mWaitForState; - public boolean onStateChangedCalled = false; - public int state = -1; - - TestTrafficStateCallback(Object lock, int waitForState) { - mLock = lock; - mWaitForState = waitForState; - } - - @Override - public void onStateChanged(int state) { - synchronized (mLock) { - onStateChangedCalled = true; - this.state = state; - if (mWaitForState == state) { // only notify if we got the expected state. - mLock.notify(); - } - } - } - } - - private void sendTraffic() { - for (int i = 0; i < 10; i ++) { - // Do some network operations - HttpURLConnection connection = null; - try { - URL url = new URL("http://www.google.com/"); - connection = (HttpURLConnection) url.openConnection(); - connection.setInstanceFollowRedirects(false); - connection.setConnectTimeout(TIMEOUT_MSEC); - connection.setReadTimeout(TIMEOUT_MSEC); - connection.setUseCaches(false); - connection.getInputStream(); - } catch (Exception e) { - // ignore - } finally { - if (connection != null) connection.disconnect(); - } - } - } - - /** - * Tests {@link WifiManager#registerTrafficStateCallback(Executor, - * WifiManager.TrafficStateCallback)} by sending some traffic. - */ - public void testTrafficStateCallback() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - TestTrafficStateCallback trafficStateCallback = - new TestTrafficStateCallback(mLock, DATA_ACTIVITY_INOUT); - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - try { - uiAutomation.adoptShellPermissionIdentity(); - // Trigger a scan & wait for connection to one of the saved networks. - mWifiManager.startScan(); - waitForConnection(); - - // Turn screen on for wifi traffic polling. - turnScreenOn(); - synchronized (mLock) { - try { - mWifiManager.registerTrafficStateCallback( - Executors.newSingleThreadExecutor(), trafficStateCallback); - // Send some traffic to trigger the traffic state change callbacks. - sendTraffic(); - // now wait for callback - mLock.wait(TEST_WAIT_DURATION_MS); - } catch (InterruptedException e) { - } - } - // check if we got the state changed callback - assertTrue(trafficStateCallback.onStateChangedCalled); - assertEquals(DATA_ACTIVITY_INOUT, trafficStateCallback.state); - } finally { - turnScreenOff(); - mWifiManager.unregisterTrafficStateCallback(trafficStateCallback); - uiAutomation.dropShellPermissionIdentity(); - } - } - - /** - * Tests {@link WifiManager#setScanAlwaysAvailable(boolean)} & - * {@link WifiManager#isScanAlwaysAvailable()}. - */ - public void testScanAlwaysAvailable() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - Boolean currState = null; - try { - uiAutomation.adoptShellPermissionIdentity(); - currState = mWifiManager.isScanAlwaysAvailable(); - boolean newState = !currState; - mWifiManager.setScanAlwaysAvailable(newState); - PollingCheck.check( - "Wifi settings toggle failed!", - DURATION_SETTINGS_TOGGLE, - () -> mWifiManager.isScanAlwaysAvailable() == newState); - assertEquals(newState, mWifiManager.isScanAlwaysAvailable()); - } finally { - if (currState != null) mWifiManager.setScanAlwaysAvailable(currState); - uiAutomation.dropShellPermissionIdentity(); - } - } - - /** - * Tests {@link WifiManager#setScanThrottleEnabled(boolean)} & - * {@link WifiManager#isScanThrottleEnabled()}. - */ - public void testScanThrottleEnabled() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - Boolean currState = null; - try { - uiAutomation.adoptShellPermissionIdentity(); - currState = mWifiManager.isScanThrottleEnabled(); - boolean newState = !currState; - mWifiManager.setScanThrottleEnabled(newState); - PollingCheck.check( - "Wifi settings toggle failed!", - DURATION_SETTINGS_TOGGLE, - () -> mWifiManager.isScanThrottleEnabled() == newState); - assertEquals(newState, mWifiManager.isScanThrottleEnabled()); - } finally { - if (currState != null) mWifiManager.setScanThrottleEnabled(currState); - uiAutomation.dropShellPermissionIdentity(); - } - } - - /** - * Tests {@link WifiManager#setAutoWakeupEnabled(boolean)} & - * {@link WifiManager#isAutoWakeupEnabled()}. - */ - public void testAutoWakeUpEnabled() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - Boolean currState = null; - try { - uiAutomation.adoptShellPermissionIdentity(); - currState = mWifiManager.isAutoWakeupEnabled(); - boolean newState = !currState; - mWifiManager.setAutoWakeupEnabled(newState); - PollingCheck.check( - "Wifi settings toggle failed!", - DURATION_SETTINGS_TOGGLE, - () -> mWifiManager.isAutoWakeupEnabled() == newState); - assertEquals(newState, mWifiManager.isAutoWakeupEnabled()); - } finally { - if (currState != null) mWifiManager.setAutoWakeupEnabled(currState); - uiAutomation.dropShellPermissionIdentity(); - } - } - - /** - * Tests {@link WifiManager#setVerboseLoggingEnabled(boolean)} & - * {@link WifiManager#isVerboseLoggingEnabled()}. - */ - public void testVerboseLoggingEnabled() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - Boolean currState = null; - try { - uiAutomation.adoptShellPermissionIdentity(); - currState = mWifiManager.isVerboseLoggingEnabled(); - boolean newState = !currState; - mWifiManager.setVerboseLoggingEnabled(newState); - PollingCheck.check( - "Wifi settings toggle failed!", - DURATION_SETTINGS_TOGGLE, - () -> mWifiManager.isVerboseLoggingEnabled() == newState); - assertEquals(newState, mWifiManager.isVerboseLoggingEnabled()); - } finally { - if (currState != null) mWifiManager.setVerboseLoggingEnabled(currState); - uiAutomation.dropShellPermissionIdentity(); - } - } - - /** - * Tests {@link WifiManager#factoryReset()}. - * - * Note: This test assumes that the device only has 1 or more saved networks before the test. - * The test will restore those when the test exits. But, it does not restore the softap - * configuration, suggestions, etc which will also have been lost on factory reset. - */ - public void testFactoryReset() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - List savedNetworks = null; - try { - uiAutomation.adoptShellPermissionIdentity(); - // These below API's only work with privileged permissions (obtained via shell identity - // for test) - savedNetworks = mWifiManager.getPrivilegedConfiguredNetworks(); - - mWifiManager.factoryReset(); - // Ensure all the saved networks are removed. - assertEquals(0, mWifiManager.getConfiguredNetworks().size()); - } finally { - // Restore the original saved networks. - if (savedNetworks != null) { - for (WifiConfiguration network : savedNetworks) { - network.networkId = WifiConfiguration.INVALID_NETWORK_ID; - int networkId = mWifiManager.addNetwork(network); - mWifiManager.enableNetwork(networkId, false); - } - } - uiAutomation.dropShellPermissionIdentity(); - } - } - - /** - * Test {@link WifiNetworkConnectionStatistics} does not crash. - * TODO(b/150891569): deprecate it in Android S, this API is not used anywhere. - */ - public void testWifiNetworkConnectionStatistics() { - new WifiNetworkConnectionStatistics(); - WifiNetworkConnectionStatistics stats = new WifiNetworkConnectionStatistics(0, 0); - new WifiNetworkConnectionStatistics(stats); - } - - /** - * Test that the wifi country code is either null, or a length-2 string. - */ - public void testGetCountryCode() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - - String wifiCountryCode = ShellIdentityUtils.invokeWithShellPermissions( - mWifiManager::getCountryCode); - - if (wifiCountryCode == null) { - return; - } - assertEquals(2, wifiCountryCode.length()); - - // assert that the country code is all uppercase - assertEquals(wifiCountryCode.toUpperCase(Locale.US), wifiCountryCode); - - String telephonyCountryCode = getContext().getSystemService(TelephonyManager.class) - .getNetworkCountryIso(); - assertEquals(telephonyCountryCode, wifiCountryCode.toLowerCase(Locale.US)); - } - - /** - * Test that {@link WifiManager#getCurrentNetwork()} returns a Network obeject consistent - * with {@link ConnectivityManager#registerNetworkCallback} when connected to a Wifi network, - * and returns null when not connected. - */ - public void testGetCurrentNetwork() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - - // wait for Wifi to be connected - PollingCheck.check( - "Wifi not connected - Please ensure there is a saved network in range of this " - + "device", - 20000, - () -> mWifiManager.getConnectionInfo().getNetworkId() != -1); - - Network wifiCurrentNetwork = ShellIdentityUtils.invokeWithShellPermissions( - mWifiManager::getCurrentNetwork); - assertNotNull(wifiCurrentNetwork); - - TestNetworkCallback networkCallbackListener = new TestNetworkCallback(mLock); - synchronized (mLock) { - try { - // File a request for wifi network. - mConnectivityManager.registerNetworkCallback( - new NetworkRequest.Builder() - .addTransportType(TRANSPORT_WIFI) - .build(), - networkCallbackListener); - // now wait for callback - mLock.wait(TEST_WAIT_DURATION_MS); - } catch (InterruptedException e) { - } - } - assertTrue(networkCallbackListener.onAvailableCalled); - Network connectivityCurrentNetwork = networkCallbackListener.network; - assertEquals(connectivityCurrentNetwork, wifiCurrentNetwork); - - setWifiEnabled(false); - PollingCheck.check( - "Wifi not disconnected!", - 20000, - () -> mWifiManager.getConnectionInfo().getNetworkId() == -1); - - assertNull(ShellIdentityUtils.invokeWithShellPermissions(mWifiManager::getCurrentNetwork)); - } - - /** - * Tests {@link WifiManager#isWpa3SaeSupported()} does not crash. - */ - public void testIsWpa3SaeSupported() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - mWifiManager.isWpa3SaeSupported(); - } - - /** - * Tests {@link WifiManager#isWpa3SuiteBSupported()} does not crash. - */ - public void testIsWpa3SuiteBSupported() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - mWifiManager.isWpa3SuiteBSupported(); - } - - /** - * Tests {@link WifiManager#isEnhancedOpenSupported()} does not crash. - */ - public void testIsEnhancedOpenSupported() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - mWifiManager.isEnhancedOpenSupported(); - } - - /** - * Test that {@link WifiManager#is5GHzBandSupported()} returns successfully in - * both WiFi enabled/disabled states. - * Note that the response depends on device support and hence both true/false - * are valid responses. - */ - public void testIs5GhzBandSupported() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - - // Check for 5GHz support with wifi enabled - setWifiEnabled(true); - PollingCheck.check( - "Wifi not enabled!", - 20000, - () -> mWifiManager.isWifiEnabled()); - boolean isSupportedEnabled = mWifiManager.is5GHzBandSupported(); - - // Check for 5GHz support with wifi disabled - setWifiEnabled(false); - PollingCheck.check( - "Wifi not disabled!", - 20000, - () -> !mWifiManager.isWifiEnabled()); - boolean isSupportedDisabled = mWifiManager.is5GHzBandSupported(); - - // If Support is true when WiFi is disable, then it has to be true when it is enabled. - // Note, the reverse is a valid case. - if (isSupportedDisabled) { - assertTrue(isSupportedEnabled); - } - } - - /** - * Test that {@link WifiManager#is6GHzBandSupported()} returns successfully in - * both Wifi enabled/disabled states. - * Note that the response depends on device support and hence both true/false - * are valid responses. - */ - public void testIs6GhzBandSupported() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - - // Check for 6GHz support with wifi enabled - setWifiEnabled(true); - PollingCheck.check( - "Wifi not enabled!", - 20000, - () -> mWifiManager.isWifiEnabled()); - boolean isSupportedEnabled = mWifiManager.is6GHzBandSupported(); - - // Check for 6GHz support with wifi disabled - setWifiEnabled(false); - PollingCheck.check( - "Wifi not disabled!", - 20000, - () -> !mWifiManager.isWifiEnabled()); - boolean isSupportedDisabled = mWifiManager.is6GHzBandSupported(); - - // If Support is true when WiFi is disable, then it has to be true when it is enabled. - // Note, the reverse is a valid case. - if (isSupportedDisabled) { - assertTrue(isSupportedEnabled); - } - } - - /** - * Test that {@link WifiManager#isWifiStandardSupported()} returns successfully in - * both Wifi enabled/disabled states. The test is to be performed on - * {@link WifiAnnotations}'s {@code WIFI_STANDARD_} - * Note that the response depends on device support and hence both true/false - * are valid responses. - */ - public void testIsWifiStandardsSupported() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - - // Check for WiFi standards support with wifi enabled - setWifiEnabled(true); - PollingCheck.check( - "Wifi not enabled!", - 20000, - () -> mWifiManager.isWifiEnabled()); - boolean isLegacySupportedEnabled = - mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_LEGACY); - boolean is11nSupporedEnabled = - mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11N); - boolean is11acSupportedEnabled = - mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AC); - boolean is11axSupportedEnabled = - mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AX); - - // Check for WiFi standards support with wifi disabled - setWifiEnabled(false); - PollingCheck.check( - "Wifi not disabled!", - 20000, - () -> !mWifiManager.isWifiEnabled()); - - boolean isLegacySupportedDisabled = - mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_LEGACY); - boolean is11nSupportedDisabled = - mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11N); - boolean is11acSupportedDisabled = - mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AC); - boolean is11axSupportedDisabled = - mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AX); - - if (isLegacySupportedDisabled) { - assertTrue(isLegacySupportedEnabled); - } - - if (is11nSupportedDisabled) { - assertTrue(is11nSupporedEnabled); - } - - if (is11acSupportedDisabled) { - assertTrue(is11acSupportedEnabled); - } - - if (is11axSupportedDisabled) { - assertTrue(is11axSupportedEnabled); - } - } - - private static PasspointConfiguration createPasspointConfiguration() { - PasspointConfiguration config = new PasspointConfiguration(); - HomeSp homeSp = new HomeSp(); - homeSp.setFqdn("test.com"); - homeSp.setFriendlyName("friendly name"); - homeSp.setRoamingConsortiumOis(new long[]{0x55, 0x66}); - config.setHomeSp(homeSp); - Credential.SimCredential simCred = new Credential.SimCredential(); - simCred.setImsi("123456*"); - simCred.setEapType(23 /* EAP_AKA */); - Credential cred = new Credential(); - cred.setRealm("realm"); - cred.setSimCredential(simCred); - config.setCredential(cred); - - return config; - } - - /** - * Tests {@link WifiManager#addOrUpdatePasspointConfiguration(PasspointConfiguration)} - * adds a Passpoint configuration correctly by getting it once it is added, and comparing it - * to the local copy of the configuration. - */ - public void testAddOrUpdatePasspointConfiguration() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - - // Create and install a Passpoint configuration - PasspointConfiguration passpointConfiguration = createPasspointConfiguration(); - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - try { - uiAutomation.adoptShellPermissionIdentity(); - mWifiManager.addOrUpdatePasspointConfiguration(passpointConfiguration); - - // Compare configurations - List configurations = mWifiManager.getPasspointConfigurations(); - assertNotNull(configurations); - assertEquals(passpointConfiguration, configurations.get(0)); - - // Clean up - mWifiManager.removePasspointConfiguration(passpointConfiguration.getHomeSp().getFqdn()); - } finally { - uiAutomation.dropShellPermissionIdentity(); - } - } - - /** - * Tests that - * {@link WifiManager#startSubscriptionProvisioning(OsuProvider, Executor, ProvisioningCallback)} - * starts a subscription provisioning, and confirm a status callback invoked once. - */ - public void testStartSubscriptionProvisioning() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - - // Using Java reflection to construct an OsuProvider instance because its constructor is - // hidden and not available to apps. - Class osuProviderClass = Class.forName("android.net.wifi.hotspot2.OsuProvider"); - Constructor osuProviderClassConstructor = osuProviderClass.getConstructor(String.class, - Map.class, String.class, Uri.class, String.class, List.class); - - OsuProvider osuProvider = (OsuProvider) osuProviderClassConstructor.newInstance(TEST_SSID, - TEST_FRIENDLY_NAMES, TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, - TEST_METHOD_LIST); - - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - try { - uiAutomation.adoptShellPermissionIdentity(); - synchronized (mLock) { - // Start a subscription provisioning for a non-existent Passpoint R2 AP - mWifiManager.startSubscriptionProvisioning(osuProvider, mExecutor, - mProvisioningCallback); - mLock.wait(TEST_WAIT_DURATION_MS); - } - } finally { - uiAutomation.dropShellPermissionIdentity(); - } - - // Expect only a single callback event, connecting. Since AP doesn't exist, it ends here - assertEquals(ProvisioningCallback.OSU_STATUS_AP_CONNECTING, mProvisioningStatus); - // No failure callbacks expected - assertEquals(0, mProvisioningFailureStatus); - // No completion callback expected - assertFalse(mProvisioningComplete); - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiMigrationTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiMigrationTest.java deleted file mode 100644 index c74c177039..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/WifiMigrationTest.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * 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.wifi.cts; - -import android.app.ActivityManager; -import android.net.wifi.WifiMigration; -import android.os.UserHandle; -import android.os.UserManager; -import android.test.AndroidTestCase; - -public class WifiMigrationTest extends AndroidTestCase { - private static final String TEST_SSID_UNQUOTED = "testSsid1"; - - @Override - protected void setUp() throws Exception { - super.setUp(); - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - } - - @Override - protected void tearDown() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - super.tearDown(); - return; - } - super.tearDown(); - } - - /** - * Tests {@link android.net.wifi.WifiMigration.SettingsMigrationData.Builder} class. - */ - public void testWifiMigrationSettingsDataBuilder() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - WifiMigration.SettingsMigrationData migrationData = - new WifiMigration.SettingsMigrationData.Builder() - .setScanAlwaysAvailable(true) - .setP2pFactoryResetPending(true) - .setScanThrottleEnabled(true) - .setSoftApTimeoutEnabled(true) - .setWakeUpEnabled(true) - .setVerboseLoggingEnabled(true) - .setP2pDeviceName(TEST_SSID_UNQUOTED) - .build(); - - assertNotNull(migrationData); - assertTrue(migrationData.isScanAlwaysAvailable()); - assertTrue(migrationData.isP2pFactoryResetPending()); - assertTrue(migrationData.isScanThrottleEnabled()); - assertTrue(migrationData.isSoftApTimeoutEnabled()); - assertTrue(migrationData.isWakeUpEnabled()); - assertTrue(migrationData.isVerboseLoggingEnabled()); - assertEquals(TEST_SSID_UNQUOTED, migrationData.getP2pDeviceName()); - } - - /** - * Tests {@link android.net.wifi.WifiMigration.SettingsMigrationData} class. - */ - public void testWifiMigrationSettings() throws Exception { - try { - WifiMigration.loadFromSettings(getContext()); - } catch (Exception ignore) { - } - } - - /** - * Tests {@link WifiMigration#convertAndRetrieveSharedConfigStoreFile(int)}, - * {@link WifiMigration#convertAndRetrieveUserConfigStoreFile(int, UserHandle)}, - * {@link WifiMigration#removeSharedConfigStoreFile(int)} and - * {@link WifiMigration#removeUserConfigStoreFile(int, UserHandle)}. - */ - public void testWifiMigrationConfigStore() throws Exception { - try { - WifiMigration.convertAndRetrieveSharedConfigStoreFile( - WifiMigration.STORE_FILE_SHARED_GENERAL); - } catch (Exception ignore) { - } - try { - WifiMigration.convertAndRetrieveSharedConfigStoreFile( - WifiMigration.STORE_FILE_SHARED_SOFTAP); - } catch (Exception ignore) { - } - try { - WifiMigration.convertAndRetrieveUserConfigStoreFile( - WifiMigration.STORE_FILE_USER_GENERAL, - UserHandle.of(ActivityManager.getCurrentUser())); - } catch (Exception ignore) { - } - try { - WifiMigration.convertAndRetrieveUserConfigStoreFile( - WifiMigration.STORE_FILE_USER_NETWORK_SUGGESTIONS, - UserHandle.of(ActivityManager.getCurrentUser())); - } catch (Exception ignore) { - } - try { - WifiMigration.removeSharedConfigStoreFile( - WifiMigration.STORE_FILE_SHARED_GENERAL); - } catch (Exception ignore) { - } - try { - WifiMigration.removeSharedConfigStoreFile( - WifiMigration.STORE_FILE_SHARED_SOFTAP); - } catch (Exception ignore) { - } - try { - WifiMigration.removeUserConfigStoreFile( - WifiMigration.STORE_FILE_USER_GENERAL, - UserHandle.of(ActivityManager.getCurrentUser())); - } catch (Exception ignore) { - } - try { - WifiMigration.removeUserConfigStoreFile( - WifiMigration.STORE_FILE_USER_NETWORK_SUGGESTIONS, - UserHandle.of(ActivityManager.getCurrentUser())); - } catch (Exception ignore) { - } - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java deleted file mode 100644 index eb6d6843eb..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java +++ /dev/null @@ -1,562 +0,0 @@ -/* - * 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.wifi.cts; - -import static android.net.NetworkCapabilitiesProto.TRANSPORT_WIFI; -import static android.os.Process.myUid; - -import static com.google.common.truth.Truth.assertThat; - -import android.app.UiAutomation; -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.LinkProperties; -import android.net.MacAddress; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.NetworkRequest; -import android.net.wifi.ScanResult; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiEnterpriseConfig; -import android.net.wifi.WifiInfo; -import android.net.wifi.WifiManager; -import android.net.wifi.WifiManager.NetworkRequestMatchCallback; -import android.net.wifi.WifiNetworkSpecifier; -import android.os.PatternMatcher; -import android.os.WorkSource; -import android.platform.test.annotations.AppModeFull; -import android.support.test.uiautomator.UiDevice; -import android.test.AndroidTestCase; -import android.text.TextUtils; - -import androidx.test.platform.app.InstrumentationRegistry; - -import com.android.compatibility.common.util.PollingCheck; -import com.android.compatibility.common.util.ShellIdentityUtils; -import com.android.compatibility.common.util.SystemUtil; - -import java.util.List; -import java.util.concurrent.Executors; - -/** - * Tests the entire connection flow using {@link WifiNetworkSpecifier} embedded in a - * {@link NetworkRequest} & passed into {@link ConnectivityManager#requestNetwork(NetworkRequest, - * ConnectivityManager.NetworkCallback)}. - * - * Assumes that all the saved networks is either open/WPA1/WPA2/WPA3 authenticated network. - * TODO(b/150716005): Use assumeTrue for wifi support check. - */ -@AppModeFull(reason = "Cannot get WifiManager in instant app mode") -public class WifiNetworkSpecifierTest extends AndroidTestCase { - private static final String TAG = "WifiNetworkSpecifierTest"; - - private WifiManager mWifiManager; - private ConnectivityManager mConnectivityManager; - private UiDevice mUiDevice; - private final Object mLock = new Object(); - private final Object mUiLock = new Object(); - private WifiConfiguration mTestNetwork; - private boolean mWasVerboseLoggingEnabled; - private boolean mWasScanThrottleEnabled; - - private static final int DURATION = 10_000; - private static final int DURATION_UI_INTERACTION = 15_000; - private static final int DURATION_NETWORK_CONNECTION = 30_000; - private static final int DURATION_SCREEN_TOGGLE = 2000; - - @Override - protected void setUp() throws Exception { - super.setUp(); - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); - mConnectivityManager = getContext().getSystemService(ConnectivityManager.class); - assertNotNull(mWifiManager); - - // turn on verbose logging for tests - mWasVerboseLoggingEnabled = ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.isVerboseLoggingEnabled()); - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.setVerboseLoggingEnabled(true)); - // Disable scan throttling for tests. - mWasScanThrottleEnabled = ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.isScanThrottleEnabled()); - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.setScanThrottleEnabled(false)); - - if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true); - mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); - turnScreenOn(); - PollingCheck.check("Wifi not enabled", DURATION, () -> mWifiManager.isWifiEnabled()); - - List savedNetworks = ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.getPrivilegedConfiguredNetworks()); - assertFalse("Need at least one saved network", savedNetworks.isEmpty()); - // Pick any one of the saved networks on the device (assumes that it is in range) - mTestNetwork = savedNetworks.get(0); - // Disconnect & disable auto-join on the saved network to prevent auto-connect from - // interfering with the test. - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.disableNetwork(mTestNetwork.networkId)); - // wait for Wifi to be disconnected - PollingCheck.check( - "Wifi not disconnected", - 20000, - () -> mWifiManager.getConnectionInfo().getNetworkId() == -1); - } - - @Override - protected void tearDown() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - super.tearDown(); - return; - } - if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true); - turnScreenOff(); - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.enableNetwork(mTestNetwork.networkId, false)); - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.setScanThrottleEnabled(mWasScanThrottleEnabled)); - ShellIdentityUtils.invokeWithShellPermissions( - () -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled)); - super.tearDown(); - } - - private void setWifiEnabled(boolean enable) throws Exception { - // now trigger the change using shell commands. - SystemUtil.runShellCommand("svc wifi " + (enable ? "enable" : "disable")); - } - - private void turnScreenOn() throws Exception { - mUiDevice.executeShellCommand("input keyevent KEYCODE_WAKEUP"); - mUiDevice.executeShellCommand("wm dismiss-keyguard"); - // Since the screen on/off intent is ordered, they will not be sent right now. - Thread.sleep(DURATION_SCREEN_TOGGLE); - } - - private void turnScreenOff() throws Exception { - mUiDevice.executeShellCommand("input keyevent KEYCODE_SLEEP"); - // Since the screen on/off intent is ordered, they will not be sent right now. - Thread.sleep(DURATION_SCREEN_TOGGLE); - } - - private static class TestNetworkCallback extends ConnectivityManager.NetworkCallback { - private final Object mLock; - public boolean onAvailableCalled = false; - public boolean onUnavailableCalled = false; - public NetworkCapabilities networkCapabilities; - - TestNetworkCallback(Object lock) { - mLock = lock; - } - - @Override - public void onAvailable(Network network, NetworkCapabilities networkCapabilities, - LinkProperties linkProperties, boolean blocked) { - synchronized (mLock) { - onAvailableCalled = true; - this.networkCapabilities = networkCapabilities; - mLock.notify(); - } - } - - @Override - public void onUnavailable() { - synchronized (mLock) { - onUnavailableCalled = true; - mLock.notify(); - } - } - } - - private static class TestNetworkRequestMatchCallback implements NetworkRequestMatchCallback { - private final Object mLock; - - public boolean onRegistrationCalled = false; - public boolean onAbortCalled = false; - public boolean onMatchCalled = false; - public boolean onConnectSuccessCalled = false; - public boolean onConnectFailureCalled = false; - public WifiManager.NetworkRequestUserSelectionCallback userSelectionCallback = null; - public List matchedScanResults = null; - - TestNetworkRequestMatchCallback(Object lock) { - mLock = lock; - } - - @Override - public void onUserSelectionCallbackRegistration( - WifiManager.NetworkRequestUserSelectionCallback userSelectionCallback) { - synchronized (mLock) { - onRegistrationCalled = true; - this.userSelectionCallback = userSelectionCallback; - mLock.notify(); - } - } - - @Override - public void onAbort() { - synchronized (mLock) { - onAbortCalled = true; - mLock.notify(); - } - } - - @Override - public void onMatch(List scanResults) { - synchronized (mLock) { - // This can be invoked multiple times. So, ignore after the first one to avoid - // disturbing the rest of the test sequence. - if (onMatchCalled) return; - onMatchCalled = true; - matchedScanResults = scanResults; - mLock.notify(); - } - } - - @Override - public void onUserSelectionConnectSuccess(WifiConfiguration config) { - synchronized (mLock) { - onConnectSuccessCalled = true; - mLock.notify(); - } - } - - @Override - public void onUserSelectionConnectFailure(WifiConfiguration config) { - synchronized (mLock) { - onConnectFailureCalled = true; - mLock.notify(); - } - } - } - - private void handleUiInteractions(boolean shouldUserReject) { - UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(); - TestNetworkRequestMatchCallback networkRequestMatchCallback = - new TestNetworkRequestMatchCallback(mUiLock); - try { - uiAutomation.adoptShellPermissionIdentity(); - - // 1. Wait for registration callback. - synchronized (mUiLock) { - try { - mWifiManager.registerNetworkRequestMatchCallback( - Executors.newSingleThreadExecutor(), networkRequestMatchCallback); - // now wait for the registration callback first. - mUiLock.wait(DURATION_UI_INTERACTION); - } catch (InterruptedException e) { - } - } - assertTrue(networkRequestMatchCallback.onRegistrationCalled); - assertNotNull(networkRequestMatchCallback.userSelectionCallback); - - // 2. Wait for matching scan results - synchronized (mUiLock) { - try { - // now wait for the registration callback first. - mUiLock.wait(DURATION_UI_INTERACTION); - } catch (InterruptedException e) { - } - } - assertTrue(networkRequestMatchCallback.onMatchCalled); - assertNotNull(networkRequestMatchCallback.matchedScanResults); - assertThat(networkRequestMatchCallback.matchedScanResults.size()).isAtLeast(1); - - // 3. Trigger connection to one of the matched networks or reject the request. - if (shouldUserReject) { - networkRequestMatchCallback.userSelectionCallback.reject(); - } else { - networkRequestMatchCallback.userSelectionCallback.select(mTestNetwork); - } - - // 4. Wait for connection success or abort. - synchronized (mUiLock) { - try { - // now wait for the registration callback first. - mUiLock.wait(DURATION_UI_INTERACTION); - } catch (InterruptedException e) { - } - } - if (shouldUserReject) { - assertTrue(networkRequestMatchCallback.onAbortCalled); - } else { - assertTrue(networkRequestMatchCallback.onConnectSuccessCalled); - } - } finally { - mWifiManager.unregisterNetworkRequestMatchCallback(networkRequestMatchCallback); - uiAutomation.dropShellPermissionIdentity(); - } - } - - /** - * Tests the entire connection flow using the provided specifier. - * - * @param specifier Specifier to use for network request. - * @param shouldUserReject Whether to simulate user rejection or not. - */ - private void testConnectionFlowWithSpecifier( - WifiNetworkSpecifier specifier, boolean shouldUserReject) { - // Fork a thread to handle the UI interactions. - Thread uiThread = new Thread(() -> handleUiInteractions(shouldUserReject)); - - // File the network request & wait for the callback. - TestNetworkCallback networkCallbackListener = new TestNetworkCallback(mLock); - synchronized (mLock) { - try { - // File a request for wifi network. - mConnectivityManager.requestNetwork( - new NetworkRequest.Builder() - .addTransportType(TRANSPORT_WIFI) - .setNetworkSpecifier(specifier) - .build(), - networkCallbackListener); - // Wait for the request to reach the wifi stack before kick-starting the UI - // interactions. - Thread.sleep(100); - // Start the UI interactions. - uiThread.run(); - // now wait for callback - mLock.wait(DURATION_NETWORK_CONNECTION); - } catch (InterruptedException e) { - } - } - if (shouldUserReject) { - assertTrue(networkCallbackListener.onUnavailableCalled); - } else { - assertTrue(networkCallbackListener.onAvailableCalled); - } - - try { - // Ensure that the UI interaction thread has completed. - uiThread.join(DURATION_UI_INTERACTION); - } catch (InterruptedException e) { - fail("UI interaction interrupted"); - } - - // Release the request after the test. - mConnectivityManager.unregisterNetworkCallback(networkCallbackListener); - } - - private void testSuccessfulConnectionWithSpecifier(WifiNetworkSpecifier specifier) { - testConnectionFlowWithSpecifier(specifier, false); - } - - private void testUserRejectionWithSpecifier(WifiNetworkSpecifier specifier) { - testConnectionFlowWithSpecifier(specifier, true); - } - - private static String removeDoubleQuotes(String string) { - return WifiInfo.sanitizeSsid(string); - } - - private WifiNetworkSpecifier.Builder createSpecifierBuilderWithCredentialFromSavedNetwork() { - WifiNetworkSpecifier.Builder specifierBuilder = new WifiNetworkSpecifier.Builder(); - if (mTestNetwork.preSharedKey != null) { - if (mTestNetwork.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK)) { - specifierBuilder.setWpa2Passphrase(removeDoubleQuotes(mTestNetwork.preSharedKey)); - } else if (mTestNetwork.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE)) { - specifierBuilder.setWpa3Passphrase(removeDoubleQuotes(mTestNetwork.preSharedKey)); - } else { - fail("Unsupported security type found in saved networks"); - } - } else if (!mTestNetwork.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.OWE)) { - specifierBuilder.setIsEnhancedOpen(false); - } else if (!mTestNetwork.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)) { - fail("Unsupported security type found in saved networks"); - } - specifierBuilder.setIsHiddenSsid(mTestNetwork.hiddenSSID); - return specifierBuilder; - } - - /** - * Tests the entire connection flow using a specific SSID in the specifier. - */ - public void testConnectionWithSpecificSsid() { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - WifiNetworkSpecifier specifier = createSpecifierBuilderWithCredentialFromSavedNetwork() - .setSsid(removeDoubleQuotes(mTestNetwork.SSID)) - .build(); - testSuccessfulConnectionWithSpecifier(specifier); - } - - /** - * Tests the entire connection flow using a SSID pattern in the specifier. - */ - public void testConnectionWithSsidPattern() { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - // Creates a ssid pattern by dropping the last char in the saved network & pass that - // as a prefix match pattern in the request. - String ssidUnquoted = removeDoubleQuotes(mTestNetwork.SSID); - assertThat(ssidUnquoted.length()).isAtLeast(2); - String ssidPrefix = ssidUnquoted.substring(0, ssidUnquoted.length() - 1); - // Note: The match may return more than 1 network in this case since we use a prefix match, - // But, we will still ensure that the UI interactions in the test still selects the - // saved network for connection. - WifiNetworkSpecifier specifier = createSpecifierBuilderWithCredentialFromSavedNetwork() - .setSsidPattern(new PatternMatcher(ssidPrefix, PatternMatcher.PATTERN_PREFIX)) - .build(); - testSuccessfulConnectionWithSpecifier(specifier); - } - - private static class TestScanResultsCallback extends WifiManager.ScanResultsCallback { - private final Object mLock; - public boolean onAvailableCalled = false; - - TestScanResultsCallback(Object lock) { - mLock = lock; - } - - @Override - public void onScanResultsAvailable() { - synchronized (mLock) { - onAvailableCalled = true; - mLock.notify(); - } - } - } - - /** - * Loops through all available scan results and finds the first match for the saved network. - * - * Note: - * a) If there are more than 2 networks with the same SSID, but different credential type, then - * this matching may pick the wrong one. - */ - private ScanResult findScanResultMatchingSavedNetwork() { - // Trigger a scan to get fresh scan results. - TestScanResultsCallback scanResultsCallback = new TestScanResultsCallback(mLock); - synchronized (mLock) { - try { - mWifiManager.registerScanResultsCallback( - Executors.newSingleThreadExecutor(), scanResultsCallback); - mWifiManager.startScan(new WorkSource(myUid())); - // now wait for callback - mLock.wait(DURATION_NETWORK_CONNECTION); - } catch (InterruptedException e) { - } finally { - mWifiManager.unregisterScanResultsCallback(scanResultsCallback); - } - } - List scanResults = mWifiManager.getScanResults(); - if (scanResults == null || scanResults.isEmpty()) fail("No scan results available"); - for (ScanResult scanResult : scanResults) { - if (TextUtils.equals(scanResult.SSID, removeDoubleQuotes(mTestNetwork.SSID))) { - return scanResult; - } - } - fail("No matching scan results found"); - return null; - } - - /** - * Tests the entire connection flow using a specific BSSID in the specifier. - */ - public void testConnectionWithSpecificBssid() { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - ScanResult scanResult = findScanResultMatchingSavedNetwork(); - WifiNetworkSpecifier specifier = createSpecifierBuilderWithCredentialFromSavedNetwork() - .setBssid(MacAddress.fromString(scanResult.BSSID)) - .build(); - testSuccessfulConnectionWithSpecifier(specifier); - } - - /** - * Tests the entire connection flow using a BSSID pattern in the specifier. - */ - public void testConnectionWithBssidPattern() { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - ScanResult scanResult = findScanResultMatchingSavedNetwork(); - // Note: The match may return more than 1 network in this case since we use a prefix match, - // But, we will still ensure that the UI interactions in the test still selects the - // saved network for connection. - WifiNetworkSpecifier specifier = createSpecifierBuilderWithCredentialFromSavedNetwork() - .setBssidPattern(MacAddress.fromString(scanResult.BSSID), - MacAddress.fromString("ff:ff:ff:00:00:00")) - .build(); - testSuccessfulConnectionWithSpecifier(specifier); - } - - /** - * Tests the entire connection flow using a BSSID pattern in the specifier. - */ - public void testUserRejectionWithSpecificSsid() { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - WifiNetworkSpecifier specifier = createSpecifierBuilderWithCredentialFromSavedNetwork() - .setSsid(removeDoubleQuotes(mTestNetwork.SSID)) - .build(); - testUserRejectionWithSpecifier(specifier); - } - - /** - * Tests the builder for WPA2 enterprise networks. - * Note: Can't do end to end tests for such networks in CTS environment. - */ - public void testBuilderForWpa2Enterprise() { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - WifiNetworkSpecifier specifier1 = new WifiNetworkSpecifier.Builder() - .setSsid(removeDoubleQuotes(mTestNetwork.SSID)) - .setWpa2EnterpriseConfig(new WifiEnterpriseConfig()) - .build(); - WifiNetworkSpecifier specifier2 = new WifiNetworkSpecifier.Builder() - .setSsid(removeDoubleQuotes(mTestNetwork.SSID)) - .setWpa2EnterpriseConfig(new WifiEnterpriseConfig()) - .build(); - assertThat(specifier1.satisfiedBy(specifier2)).isTrue(); - } - - /** - * Tests the builder for WPA3 enterprise networks. - * Note: Can't do end to end tests for such networks in CTS environment. - */ - public void testBuilderForWpa3Enterprise() { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - WifiNetworkSpecifier specifier1 = new WifiNetworkSpecifier.Builder() - .setSsid(removeDoubleQuotes(mTestNetwork.SSID)) - .setWpa3EnterpriseConfig(new WifiEnterpriseConfig()) - .build(); - WifiNetworkSpecifier specifier2 = new WifiNetworkSpecifier.Builder() - .setSsid(removeDoubleQuotes(mTestNetwork.SSID)) - .setWpa3EnterpriseConfig(new WifiEnterpriseConfig()) - .build(); - assertThat(specifier1.satisfiedBy(specifier2)).isTrue(); - } -} diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java deleted file mode 100644 index e73abb8b54..0000000000 --- a/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java +++ /dev/null @@ -1,268 +0,0 @@ -/* - * 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.wifi.cts; - -import static android.net.wifi.WifiEnterpriseConfig.Eap.AKA; -import static android.net.wifi.WifiEnterpriseConfig.Eap.WAPI_CERT; - -import android.net.MacAddress; -import android.net.wifi.WifiEnterpriseConfig; -import android.net.wifi.WifiNetworkSuggestion; -import android.net.wifi.hotspot2.PasspointConfiguration; -import android.net.wifi.hotspot2.pps.Credential; -import android.net.wifi.hotspot2.pps.HomeSp; -import android.telephony.TelephonyManager; -import android.test.AndroidTestCase; - -public class WifiNetworkSuggestionTest extends AndroidTestCase { - private static final String TEST_SSID = "testSsid"; - private static final String TEST_BSSID = "00:df:aa:bc:12:23"; - private static final String TEST_PASSPHRASE = "testPassword"; - - @Override - protected void setUp() throws Exception { - super.setUp(); - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - } - - @Override - protected void tearDown() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - super.tearDown(); - return; - } - super.tearDown(); - } - - private WifiNetworkSuggestion.Builder createBuilderWithCommonParams() { - return createBuilderWithCommonParams(false); - } - - private WifiNetworkSuggestion.Builder createBuilderWithCommonParams(boolean isPasspoint) { - WifiNetworkSuggestion.Builder builder = new WifiNetworkSuggestion.Builder(); - if (!isPasspoint) { - builder.setSsid(TEST_SSID); - builder.setBssid(MacAddress.fromString(TEST_BSSID)); - builder.setIsEnhancedOpen(false); - builder.setIsHiddenSsid(true); - } - builder.setPriority(0); - builder.setIsAppInteractionRequired(true); - builder.setIsUserInteractionRequired(true); - builder.setIsMetered(true); - builder.setCarrierId(TelephonyManager.UNKNOWN_CARRIER_ID); - builder.setCredentialSharedWithUser(true); - builder.setIsInitialAutojoinEnabled(true); - builder.setUntrusted(false); - return builder; - } - - private void validateCommonParams(WifiNetworkSuggestion suggestion) { - validateCommonParams(suggestion, false); - } - - private void validateCommonParams(WifiNetworkSuggestion suggestion, boolean isPasspoint) { - assertNotNull(suggestion); - assertNotNull(suggestion.getWifiConfiguration()); - if (!isPasspoint) { - assertEquals(TEST_SSID, suggestion.getSsid()); - assertEquals(TEST_BSSID, suggestion.getBssid().toString()); - assertFalse(suggestion.isEnhancedOpen()); - assertTrue(suggestion.isHiddenSsid()); - } - assertEquals(0, suggestion.getPriority()); - assertTrue(suggestion.isAppInteractionRequired()); - assertTrue(suggestion.isUserInteractionRequired()); - assertTrue(suggestion.isMetered()); - assertTrue(suggestion.isCredentialSharedWithUser()); - assertTrue(suggestion.isInitialAutojoinEnabled()); - assertFalse(suggestion.isUntrusted()); - } - - /** - * Tests {@link android.net.wifi.WifiNetworkSuggestion.Builder} class. - */ - public void testBuilderWithWpa2Passphrase() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - WifiNetworkSuggestion suggestion = - createBuilderWithCommonParams() - .setWpa2Passphrase(TEST_PASSPHRASE) - .build(); - validateCommonParams(suggestion); - assertEquals(TEST_PASSPHRASE, suggestion.getPassphrase()); - assertNotNull(suggestion.getEnterpriseConfig()); - assertNull(suggestion.getPasspointConfig()); - } - - /** - * Tests {@link android.net.wifi.WifiNetworkSuggestion.Builder} class. - */ - public void testBuilderWithWpa3Passphrase() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - WifiNetworkSuggestion suggestion = - createBuilderWithCommonParams() - .setWpa3Passphrase(TEST_PASSPHRASE) - .build(); - validateCommonParams(suggestion); - assertEquals(TEST_PASSPHRASE, suggestion.getPassphrase()); - assertNotNull(suggestion.getEnterpriseConfig()); - assertNull(suggestion.getPasspointConfig()); - } - - /** - * Tests {@link android.net.wifi.WifiNetworkSuggestion.Builder} class. - */ - public void testBuilderWithWapiPassphrase() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - WifiNetworkSuggestion suggestion = - createBuilderWithCommonParams() - .setWapiPassphrase(TEST_PASSPHRASE) - .build(); - validateCommonParams(suggestion); - assertEquals(TEST_PASSPHRASE, suggestion.getPassphrase()); - assertNotNull(suggestion.getEnterpriseConfig()); - assertNull(suggestion.getPasspointConfig()); - } - - private static WifiEnterpriseConfig createEnterpriseConfig() { - WifiEnterpriseConfig config = new WifiEnterpriseConfig(); - config.setEapMethod(AKA); - return config; - } - - /** - * Tests {@link android.net.wifi.WifiNetworkSuggestion.Builder} class. - */ - public void testBuilderWithWpa2Enterprise() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - WifiEnterpriseConfig enterpriseConfig = createEnterpriseConfig(); - WifiNetworkSuggestion suggestion = - createBuilderWithCommonParams() - .setWpa2EnterpriseConfig(enterpriseConfig) - .build(); - validateCommonParams(suggestion); - assertNull(suggestion.getPassphrase()); - assertNotNull(suggestion.getEnterpriseConfig()); - assertEquals(enterpriseConfig.getEapMethod(), - suggestion.getEnterpriseConfig().getEapMethod()); - assertNull(suggestion.getPasspointConfig()); - } - - /** - * Tests {@link android.net.wifi.WifiNetworkSuggestion.Builder} class. - */ - public void testBuilderWithWpa3Enterprise() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - WifiEnterpriseConfig enterpriseConfig = createEnterpriseConfig(); - WifiNetworkSuggestion suggestion = - createBuilderWithCommonParams() - .setWpa3EnterpriseConfig(enterpriseConfig) - .build(); - validateCommonParams(suggestion); - assertNull(suggestion.getPassphrase()); - assertNotNull(suggestion.getEnterpriseConfig()); - assertEquals(enterpriseConfig.getEapMethod(), - suggestion.getEnterpriseConfig().getEapMethod()); - assertNull(suggestion.getPasspointConfig()); - } - - /** - * Tests {@link android.net.wifi.WifiNetworkSuggestion.Builder} class. - */ - public void testBuilderWithWapiEnterprise() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); - enterpriseConfig.setEapMethod(WAPI_CERT); - WifiNetworkSuggestion suggestion = - createBuilderWithCommonParams() - .setWapiEnterpriseConfig(enterpriseConfig) - .build(); - validateCommonParams(suggestion); - assertNull(suggestion.getPassphrase()); - assertNotNull(suggestion.getEnterpriseConfig()); - assertEquals(enterpriseConfig.getEapMethod(), - suggestion.getEnterpriseConfig().getEapMethod()); - assertNull(suggestion.getPasspointConfig()); - } - - /** - * Helper function for creating a {@link PasspointConfiguration} for testing. - * - * @return {@link PasspointConfiguration} - */ - private static PasspointConfiguration createPasspointConfig() { - HomeSp homeSp = new HomeSp(); - homeSp.setFqdn("fqdn"); - homeSp.setFriendlyName("friendly name"); - homeSp.setRoamingConsortiumOis(new long[] {0x55, 0x66}); - Credential cred = new Credential(); - cred.setRealm("realm"); - cred.setUserCredential(null); - cred.setCertCredential(null); - cred.setSimCredential(new Credential.SimCredential()); - cred.getSimCredential().setImsi("1234*"); - cred.getSimCredential().setEapType(23); // EAP-AKA - cred.setCaCertificate(null); - cred.setClientCertificateChain(null); - cred.setClientPrivateKey(null); - PasspointConfiguration config = new PasspointConfiguration(); - config.setHomeSp(homeSp); - config.setCredential(cred); - return config; - } - - /** - * Tests {@link android.net.wifi.WifiNetworkSuggestion.Builder} class. - */ - public void testBuilderWithPasspointConfig() throws Exception { - if (!WifiFeature.isWifiSupported(getContext())) { - // skip the test if WiFi is not supported - return; - } - PasspointConfiguration passpointConfig = createPasspointConfig(); - WifiNetworkSuggestion suggestion = - createBuilderWithCommonParams(true) - .setPasspointConfig(passpointConfig) - .build(); - validateCommonParams(suggestion, true); - assertNull(suggestion.getPassphrase()); - assertNotNull(suggestion.getEnterpriseConfig()); - assertEquals(passpointConfig, suggestion.getPasspointConfig()); - } -} diff --git a/tests/cts/net/src/android/net/wifi/nl80211/cts/DeviceWiphyCapabilitiesTest.java b/tests/cts/net/src/android/net/wifi/nl80211/cts/DeviceWiphyCapabilitiesTest.java deleted file mode 100644 index d8f5e579da..0000000000 --- a/tests/cts/net/src/android/net/wifi/nl80211/cts/DeviceWiphyCapabilitiesTest.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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.wifi.nl80211.cts; - -import static com.google.common.truth.Truth.assertThat; - -import static org.junit.Assume.assumeTrue; - -import android.content.Context; -import android.net.wifi.ScanResult; -import android.net.wifi.cts.WifiFeature; -import android.net.wifi.nl80211.DeviceWiphyCapabilities; -import android.os.Parcel; - -import androidx.test.filters.SmallTest; -import androidx.test.platform.app.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** CTS tests for {@link DeviceWiphyCapabilities}. */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class DeviceWiphyCapabilitiesTest { - - @Before - public void setUp() { - Context context = InstrumentationRegistry.getInstrumentation().getContext(); - // skip tests if Wifi is not supported - assumeTrue(WifiFeature.isWifiSupported(context)); - } - - /** - * Test that a {@link DeviceWiphyCapabilities} object can be serialized and deserialized, - * while keeping its values unchanged. - */ - @Test - public void canSerializeAndDeserialize() { - DeviceWiphyCapabilities capa = new DeviceWiphyCapabilities(); - - capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true); - capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true); - capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false); - - Parcel parcel = Parcel.obtain(); - capa.writeToParcel(parcel, 0); - // Rewind the pointer to the head of the parcel. - parcel.setDataPosition(0); - DeviceWiphyCapabilities capaDeserialized = - DeviceWiphyCapabilities.CREATOR.createFromParcel(parcel); - - assertThat(capaDeserialized.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11N)).isTrue(); - assertThat(capaDeserialized.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AC)) - .isTrue(); - assertThat(capaDeserialized.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AX)) - .isFalse(); - assertThat(capaDeserialized).isEqualTo(capa); - assertThat(capaDeserialized.hashCode()).isEqualTo(capa.hashCode()); - } - - /** Test mapping wifi standard support into channel width support */ - @Test - public void testMappingWifiStandardIntoChannelWidthSupport() { - DeviceWiphyCapabilities capa = new DeviceWiphyCapabilities(); - - capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, false); - capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, false); - capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false); - assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)).isTrue(); - assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)).isFalse(); - assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)).isFalse(); - - capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true); - assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)).isTrue(); - assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)).isTrue(); - assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)).isFalse(); - - capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true); - assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)).isTrue(); - assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)).isTrue(); - assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)).isTrue(); - } -} diff --git a/tests/cts/net/src/android/net/wifi/nl80211/cts/NativeWifiClientTest.java b/tests/cts/net/src/android/net/wifi/nl80211/cts/NativeWifiClientTest.java deleted file mode 100644 index 3149b54abd..0000000000 --- a/tests/cts/net/src/android/net/wifi/nl80211/cts/NativeWifiClientTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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.wifi.nl80211.cts; - -import static com.google.common.truth.Truth.assertThat; - -import static org.junit.Assume.assumeTrue; - -import android.content.Context; -import android.net.MacAddress; -import android.net.wifi.cts.WifiFeature; -import android.net.wifi.nl80211.NativeWifiClient; -import android.os.Parcel; - -import androidx.test.filters.SmallTest; -import androidx.test.platform.app.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** CTS tests for {@link NativeWifiClient}. */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class NativeWifiClientTest { - - private static final byte[] TEST_MAC = { 1, 2, 3, 4, 5, 6 }; - - @Before - public void setUp() { - Context context = InstrumentationRegistry.getInstrumentation().getContext(); - // skip tests if Wifi is not supported - assumeTrue(WifiFeature.isWifiSupported(context)); - } - - @Test - public void testGetters() { - NativeWifiClient client = new NativeWifiClient(MacAddress.fromBytes(TEST_MAC)); - - assertThat(client.getMacAddress().toByteArray()).isEqualTo(TEST_MAC); - } - - @Test - public void canSerializeAndDeserialize() { - NativeWifiClient client = new NativeWifiClient(MacAddress.fromBytes(TEST_MAC)); - - Parcel parcel = Parcel.obtain(); - client.writeToParcel(parcel, 0); - // Rewind the pointer to the head of the parcel. - parcel.setDataPosition(0); - NativeWifiClient clientDeserialized = NativeWifiClient.CREATOR.createFromParcel(parcel); - - assertThat(clientDeserialized.getMacAddress().toByteArray()).isEqualTo(TEST_MAC); - assertThat(clientDeserialized).isEqualTo(client); - assertThat(clientDeserialized.hashCode()).isEqualTo(client.hashCode()); - } - - @Test - public void testEquals() { - NativeWifiClient client = new NativeWifiClient(MacAddress.fromBytes(TEST_MAC)); - NativeWifiClient client2 = - new NativeWifiClient(MacAddress.fromBytes(new byte[] { 7, 8, 9, 10, 11, 12 })); - - assertThat(client2).isNotEqualTo(client); - } -} diff --git a/tests/cts/net/src/android/net/wifi/nl80211/cts/PnoNetworkTest.java b/tests/cts/net/src/android/net/wifi/nl80211/cts/PnoNetworkTest.java deleted file mode 100644 index f3a8f05927..0000000000 --- a/tests/cts/net/src/android/net/wifi/nl80211/cts/PnoNetworkTest.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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.wifi.nl80211.cts; - -import static com.google.common.truth.Truth.assertThat; - -import static org.junit.Assume.assumeTrue; - -import android.content.Context; -import android.net.wifi.cts.WifiFeature; -import android.net.wifi.nl80211.PnoNetwork; -import android.os.Parcel; - -import androidx.test.filters.SmallTest; -import androidx.test.platform.app.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** CTS tests for {@link PnoNetwork}. */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class PnoNetworkTest { - - private static final byte[] TEST_SSID = { 's', 's', 'i', 'd' }; - private static final int[] TEST_FREQUENCIES = { 2412, 2417, 5035 }; - - @Before - public void setUp() { - Context context = InstrumentationRegistry.getInstrumentation().getContext(); - // skip tests if Wifi is not supported - assumeTrue(WifiFeature.isWifiSupported(context)); - } - - @Test - public void testGetters() { - PnoNetwork network = new PnoNetwork(); - network.setSsid(TEST_SSID); - network.setFrequenciesMhz(TEST_FREQUENCIES); - network.setHidden(true); - - assertThat(network.getSsid()).isEqualTo(TEST_SSID); - assertThat(network.getFrequenciesMhz()).isEqualTo(TEST_FREQUENCIES); - assertThat(network.isHidden()).isTrue(); - } - - @Test - public void canSerializeAndDeserialize() { - PnoNetwork network = new PnoNetwork(); - network.setSsid(TEST_SSID); - network.setFrequenciesMhz(TEST_FREQUENCIES); - network.setHidden(true); - - Parcel parcel = Parcel.obtain(); - network.writeToParcel(parcel, 0); - // Rewind the pointer to the head of the parcel. - parcel.setDataPosition(0); - PnoNetwork networkDeserialized = PnoNetwork.CREATOR.createFromParcel(parcel); - - assertThat(networkDeserialized.getSsid()).isEqualTo(TEST_SSID); - assertThat(networkDeserialized.getFrequenciesMhz()).isEqualTo(TEST_FREQUENCIES); - assertThat(networkDeserialized.isHidden()).isTrue(); - assertThat(networkDeserialized).isEqualTo(network); - assertThat(networkDeserialized.hashCode()).isEqualTo(network.hashCode()); - } - - @Test - public void testEquals() { - PnoNetwork network = new PnoNetwork(); - network.setSsid(TEST_SSID); - network.setFrequenciesMhz(TEST_FREQUENCIES); - network.setHidden(true); - - PnoNetwork network2 = new PnoNetwork(); - network.setSsid(new byte[] { 'a', 's', 'd', 'f'}); - network.setFrequenciesMhz(new int[] { 1, 2, 3 }); - network.setHidden(false); - - assertThat(network2).isNotEqualTo(network); - } -} diff --git a/tests/cts/net/src/android/net/wifi/nl80211/cts/PnoSettingsTest.java b/tests/cts/net/src/android/net/wifi/nl80211/cts/PnoSettingsTest.java deleted file mode 100644 index 59f5d993a3..0000000000 --- a/tests/cts/net/src/android/net/wifi/nl80211/cts/PnoSettingsTest.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * 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.wifi.nl80211.cts; - -import static com.google.common.truth.Truth.assertThat; - -import static org.junit.Assume.assumeTrue; - -import android.content.Context; -import android.net.wifi.cts.WifiFeature; -import android.net.wifi.nl80211.PnoNetwork; -import android.net.wifi.nl80211.PnoSettings; -import android.os.Parcel; - -import androidx.test.filters.SmallTest; -import androidx.test.platform.app.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.Arrays; -import java.util.List; - -/** CTS tests for {@link PnoSettings}. */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class PnoSettingsTest { - - private static List createTestNetworks() { - PnoNetwork network1 = new PnoNetwork(); - network1.setSsid(new byte[] { 's', 's', 'i', 'd' }); - network1.setFrequenciesMhz(new int[] { 2412, 2417, 5035 }); - network1.setHidden(true); - - PnoNetwork network2 = new PnoNetwork(); - network2.setSsid(new byte[] { 'a', 's', 'd', 'f' }); - network2.setFrequenciesMhz(new int[] { 2422, 2427, 5040 }); - network2.setHidden(false); - - return Arrays.asList(network1, network2); - } - - @Before - public void setUp() { - Context context = InstrumentationRegistry.getInstrumentation().getContext(); - // skip tests if Wifi is not supported - assumeTrue(WifiFeature.isWifiSupported(context)); - } - - @Test - public void testGetters() { - PnoSettings settings = new PnoSettings(); - settings.setIntervalMillis(1000); - settings.setMin2gRssiDbm(-70); - settings.setMin5gRssiDbm(-60); - settings.setMin6gRssiDbm(-50); - settings.setPnoNetworks(createTestNetworks()); - - assertThat(settings.getIntervalMillis()).isEqualTo(1000); - assertThat(settings.getMin2gRssiDbm()).isEqualTo(-70); - assertThat(settings.getMin5gRssiDbm()).isEqualTo(-60); - assertThat(settings.getMin6gRssiDbm()).isEqualTo(-50); - assertThat(settings.getPnoNetworks()).isEqualTo(createTestNetworks()); - } - - @Test - public void canSerializeAndDeserialize() { - PnoSettings settings = new PnoSettings(); - settings.setIntervalMillis(1000); - settings.setMin2gRssiDbm(-70); - settings.setMin5gRssiDbm(-60); - settings.setMin6gRssiDbm(-50); - settings.setPnoNetworks(createTestNetworks()); - - Parcel parcel = Parcel.obtain(); - settings.writeToParcel(parcel, 0); - // Rewind the pointer to the head of the parcel. - parcel.setDataPosition(0); - PnoSettings settingsDeserialized = PnoSettings.CREATOR.createFromParcel(parcel); - - assertThat(settingsDeserialized.getIntervalMillis()).isEqualTo(1000); - assertThat(settingsDeserialized.getMin2gRssiDbm()).isEqualTo(-70); - assertThat(settingsDeserialized.getMin5gRssiDbm()).isEqualTo(-60); - assertThat(settingsDeserialized.getMin6gRssiDbm()).isEqualTo(-50); - assertThat(settingsDeserialized.getPnoNetworks()).isEqualTo(createTestNetworks()); - assertThat(settingsDeserialized).isEqualTo(settings); - assertThat(settingsDeserialized.hashCode()).isEqualTo(settings.hashCode()); - } - - @Test - public void testEquals() { - PnoSettings settings = new PnoSettings(); - settings.setIntervalMillis(1000); - settings.setMin2gRssiDbm(-70); - settings.setMin5gRssiDbm(-60); - settings.setMin6gRssiDbm(-50); - settings.setPnoNetworks(createTestNetworks()); - - PnoSettings settings2 = new PnoSettings(); - settings.setIntervalMillis(2000); - settings.setMin2gRssiDbm(-70); - settings.setMin5gRssiDbm(-60); - settings.setMin6gRssiDbm(-50); - settings.setPnoNetworks(createTestNetworks()); - - assertThat(settings2).isNotEqualTo(settings); - } -} diff --git a/tests/cts/net/src/android/net/wifi/nl80211/cts/RadioChainInfoTest.java b/tests/cts/net/src/android/net/wifi/nl80211/cts/RadioChainInfoTest.java deleted file mode 100644 index 0a76bdbe32..0000000000 --- a/tests/cts/net/src/android/net/wifi/nl80211/cts/RadioChainInfoTest.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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.wifi.nl80211.cts; - -import static com.google.common.truth.Truth.assertThat; - -import static org.junit.Assume.assumeTrue; - -import android.content.Context; -import android.net.wifi.cts.WifiFeature; -import android.net.wifi.nl80211.RadioChainInfo; -import android.os.Parcel; - -import androidx.test.filters.SmallTest; -import androidx.test.platform.app.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** CTS tests for {@link RadioChainInfo}. */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class RadioChainInfoTest { - - private static final int TEST_CHAIN_ID = 1; - private static final int TEST_CHAIN_ID2 = 2; - private static final int TEST_LEVEL_DBM = -50; - private static final int TEST_LEVEL_DBM2 = -80; - - @Before - public void setUp() { - Context context = InstrumentationRegistry.getInstrumentation().getContext(); - // skip tests if Wifi is not supported - assumeTrue(WifiFeature.isWifiSupported(context)); - } - - @Test - public void testGetters() { - RadioChainInfo info = new RadioChainInfo(TEST_CHAIN_ID, TEST_LEVEL_DBM); - assertThat(info.getChainId()).isEqualTo(TEST_CHAIN_ID); - assertThat(info.getLevelDbm()).isEqualTo(TEST_LEVEL_DBM); - } - - @Test - public void canSerializeAndDeserialize() { - RadioChainInfo info = new RadioChainInfo(TEST_CHAIN_ID, TEST_LEVEL_DBM); - - Parcel parcel = Parcel.obtain(); - info.writeToParcel(parcel, 0); - // Rewind the pointer to the head of the parcel. - parcel.setDataPosition(0); - RadioChainInfo infoDeserialized = RadioChainInfo.CREATOR.createFromParcel(parcel); - - assertThat(infoDeserialized.getChainId()).isEqualTo(TEST_CHAIN_ID); - assertThat(infoDeserialized.getLevelDbm()).isEqualTo(TEST_LEVEL_DBM); - assertThat(infoDeserialized).isEqualTo(info); - assertThat(infoDeserialized.hashCode()).isEqualTo(info.hashCode()); - } - - @Test - public void testEquals() { - RadioChainInfo info = new RadioChainInfo(TEST_CHAIN_ID, TEST_LEVEL_DBM); - RadioChainInfo info2 = new RadioChainInfo(TEST_CHAIN_ID2, TEST_LEVEL_DBM2); - - assertThat(info2).isNotEqualTo(info); - } -} diff --git a/tests/cts/net/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java b/tests/cts/net/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java deleted file mode 100644 index f1f3010ddf..0000000000 --- a/tests/cts/net/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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.wifi.nl80211.cts; - -import static android.net.wifi.nl80211.WifiNl80211Manager.OemSecurityType; - -import static com.google.common.truth.Truth.assertThat; - -import static org.junit.Assume.assumeTrue; - -import android.content.Context; -import android.net.wifi.ScanResult; -import android.net.wifi.cts.WifiFeature; -import android.net.wifi.nl80211.WifiNl80211Manager; - -import androidx.test.filters.SmallTest; -import androidx.test.platform.app.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.Arrays; - -/** CTS tests for {@link WifiNl80211Manager}. */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class WifiNl80211ManagerTest { - - private Context mContext; - - @Before - public void setUp() { - mContext = InstrumentationRegistry.getInstrumentation().getContext(); - // skip tests if Wifi is not supported - assumeTrue(WifiFeature.isWifiSupported(mContext)); - } - - @Test - public void testOemSecurityTypeConstructor() { - OemSecurityType securityType = new OemSecurityType( - ScanResult.PROTOCOL_WPA, - Arrays.asList(ScanResult.KEY_MGMT_PSK, ScanResult.KEY_MGMT_SAE), - Arrays.asList(ScanResult.CIPHER_NONE, ScanResult.CIPHER_TKIP), - ScanResult.CIPHER_CCMP); - - assertThat(securityType.protocol).isEqualTo(ScanResult.PROTOCOL_WPA); - assertThat(securityType.keyManagement) - .isEqualTo(Arrays.asList(ScanResult.KEY_MGMT_PSK, ScanResult.KEY_MGMT_SAE)); - assertThat(securityType.pairwiseCipher) - .isEqualTo(Arrays.asList(ScanResult.CIPHER_NONE, ScanResult.CIPHER_TKIP)); - assertThat(securityType.groupCipher).isEqualTo(ScanResult.CIPHER_CCMP); - } - - @Test - public void testSendMgmtFrame() { - try { - WifiNl80211Manager manager = mContext.getSystemService(WifiNl80211Manager.class); - manager.sendMgmtFrame("wlan0", new byte[]{}, -1, Runnable::run, - new WifiNl80211Manager.SendMgmtFrameCallback() { - @Override - public void onAck(int elapsedTimeMs) {} - - @Override - public void onFailure(int reason) {} - }); - } catch (Exception ignore) {} - } -} diff --git a/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pConfigTest.java b/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pConfigTest.java deleted file mode 100644 index 0a2a2e6779..0000000000 --- a/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pConfigTest.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2019 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.wifi.p2p.cts; - -import android.net.MacAddress; -import android.net.wifi.p2p.WifiP2pConfig; -import android.net.wifi.p2p.WifiP2pGroup; -import android.test.AndroidTestCase; - -public class WifiP2pConfigTest extends AndroidTestCase { - private static final String TEST_NETWORK_NAME = "DIRECT-xy-Hello"; - private static final String TEST_PASSPHRASE = "8etterW0r1d"; - private static final int TEST_OWNER_BAND = WifiP2pConfig.GROUP_OWNER_BAND_5GHZ; - private static final int TEST_OWNER_FREQ = 2447; - private static final String TEST_DEVICE_ADDRESS = "aa:bb:cc:dd:ee:ff"; - - public void testWifiP2pConfigCopyConstructor() { - WifiP2pConfig config = new WifiP2pConfig.Builder() - .setNetworkName(TEST_NETWORK_NAME) - .setPassphrase(TEST_PASSPHRASE) - .setGroupOperatingBand(TEST_OWNER_BAND) - .setDeviceAddress(MacAddress.fromString(TEST_DEVICE_ADDRESS)) - .enablePersistentMode(true) - .build(); - - WifiP2pConfig copiedConfig = new WifiP2pConfig(config); - - assertEquals(copiedConfig.deviceAddress, TEST_DEVICE_ADDRESS); - assertEquals(copiedConfig.getNetworkName(), TEST_NETWORK_NAME); - assertEquals(copiedConfig.getPassphrase(), TEST_PASSPHRASE); - assertEquals(copiedConfig.getGroupOwnerBand(), TEST_OWNER_BAND); - assertEquals(copiedConfig.getNetworkId(), WifiP2pGroup.NETWORK_ID_PERSISTENT); - } - - public void testWifiP2pConfigBuilderForPersist() { - WifiP2pConfig config = new WifiP2pConfig.Builder() - .setNetworkName(TEST_NETWORK_NAME) - .setPassphrase(TEST_PASSPHRASE) - .setGroupOperatingBand(TEST_OWNER_BAND) - .setDeviceAddress(MacAddress.fromString(TEST_DEVICE_ADDRESS)) - .enablePersistentMode(true) - .build(); - - assertEquals(config.deviceAddress, TEST_DEVICE_ADDRESS); - assertEquals(config.getNetworkName(), TEST_NETWORK_NAME); - assertEquals(config.getPassphrase(), TEST_PASSPHRASE); - assertEquals(config.getGroupOwnerBand(), TEST_OWNER_BAND); - assertEquals(config.getNetworkId(), WifiP2pGroup.NETWORK_ID_PERSISTENT); - } - - public void testWifiP2pConfigBuilderForNonPersist() { - WifiP2pConfig config = new WifiP2pConfig.Builder() - .setNetworkName(TEST_NETWORK_NAME) - .setPassphrase(TEST_PASSPHRASE) - .setGroupOperatingFrequency(TEST_OWNER_FREQ) - .setDeviceAddress(MacAddress.fromString(TEST_DEVICE_ADDRESS)) - .enablePersistentMode(false) - .build(); - - assertEquals(config.deviceAddress, TEST_DEVICE_ADDRESS); - assertEquals(config.getNetworkName(), TEST_NETWORK_NAME); - assertEquals(config.getPassphrase(), TEST_PASSPHRASE); - assertEquals(config.getGroupOwnerBand(), TEST_OWNER_FREQ); - assertEquals(config.getNetworkId(), WifiP2pGroup.NETWORK_ID_TEMPORARY); - } -} diff --git a/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pDeviceTest.java b/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pDeviceTest.java deleted file mode 100644 index 1510d7cc1c..0000000000 --- a/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pDeviceTest.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.wifi.p2p.cts; - -import android.net.InetAddresses; -import android.net.wifi.p2p.WifiP2pDevice; -import android.test.AndroidTestCase; - -public class WifiP2pDeviceTest extends AndroidTestCase { - - public void testDefaultWpsMethodSupportCheck() { - WifiP2pDevice dev = new WifiP2pDevice(); - - assertFalse(dev.wpsPbcSupported()); - assertFalse(dev.wpsDisplaySupported()); - assertFalse(dev.wpsKeypadSupported()); - } - - public void testDefaultDeviceCapabilityCheck() { - WifiP2pDevice dev = new WifiP2pDevice(); - - assertFalse(dev.isServiceDiscoveryCapable()); - } -} diff --git a/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pInfoTest.java b/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pInfoTest.java deleted file mode 100644 index 8504f15e43..0000000000 --- a/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pInfoTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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.wifi.p2p.cts; - -import android.net.InetAddresses; -import android.net.wifi.p2p.WifiP2pInfo; -import android.test.AndroidTestCase; - -public class WifiP2pInfoTest extends AndroidTestCase { - - public String TEST_GROUP_OWNER_ADDRESS = "192.168.43.1"; - - public void testWifiP2pInfoNoGroup() { - WifiP2pInfo info = new WifiP2pInfo(); - info.groupFormed = false; - - WifiP2pInfo copiedInfo = new WifiP2pInfo(info); - assertEquals(info.groupFormed, copiedInfo.groupFormed); - assertEquals(info.isGroupOwner, copiedInfo.isGroupOwner); - assertEquals(info.groupOwnerAddress, copiedInfo.groupOwnerAddress); - } - - public void testWifiP2pInfoGroupOwner() { - WifiP2pInfo info = new WifiP2pInfo(); - info.groupFormed = true; - info.isGroupOwner = true; - info.groupOwnerAddress = InetAddresses.parseNumericAddress(TEST_GROUP_OWNER_ADDRESS); - - WifiP2pInfo copiedInfo = new WifiP2pInfo(info); - assertEquals(info.groupFormed, copiedInfo.groupFormed); - assertEquals(info.isGroupOwner, copiedInfo.isGroupOwner); - assertEquals(info.groupOwnerAddress, copiedInfo.groupOwnerAddress); - } - - public void testWifiP2pInfoGroupClient() { - WifiP2pInfo info = new WifiP2pInfo(); - info.groupFormed = true; - info.isGroupOwner = false; - info.groupOwnerAddress = InetAddresses.parseNumericAddress(TEST_GROUP_OWNER_ADDRESS); - - WifiP2pInfo copiedInfo = new WifiP2pInfo(info); - assertEquals(info.groupFormed, copiedInfo.groupFormed); - assertEquals(info.isGroupOwner, copiedInfo.isGroupOwner); - assertEquals(info.groupOwnerAddress, copiedInfo.groupOwnerAddress); - } -} diff --git a/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pServiceRequestTest.java b/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pServiceRequestTest.java deleted file mode 100644 index b363b1ed19..0000000000 --- a/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pServiceRequestTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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.wifi.p2p.cts; - -import android.net.wifi.p2p.nsd.WifiP2pServiceInfo; -import android.net.wifi.p2p.nsd.WifiP2pServiceRequest; -import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceRequest; -import android.test.AndroidTestCase; -import android.util.Log; - -import java.util.Arrays; -import java.util.List; -import java.util.Locale; -import java.util.stream.Collectors; - -public class WifiP2pServiceRequestTest extends AndroidTestCase { - - private final int TEST_UPNP_VERSION = 0x10; - private final String TEST_UPNP_QUERY = "ssdp:all"; - - private String bin2HexStr(byte[] data) { - StringBuffer sb = new StringBuffer(); - for (byte b: data) { - sb.append(String.format(Locale.US, "%02x", b & 0xff)); - } - return sb.toString(); - } - - public void testValidRawRequest() throws IllegalArgumentException { - StringBuffer sb = new StringBuffer(); - sb.append(String.format(Locale.US, "%02x", TEST_UPNP_VERSION)); - sb.append(bin2HexStr(TEST_UPNP_QUERY.getBytes())); - - WifiP2pServiceRequest rawRequest = - WifiP2pServiceRequest.newInstance( - WifiP2pServiceInfo.SERVICE_TYPE_UPNP, - sb.toString()); - - WifiP2pUpnpServiceRequest upnpRequest = - WifiP2pUpnpServiceRequest.newInstance( - TEST_UPNP_QUERY); - - assertEquals(rawRequest, upnpRequest); - } - - public void testInvalidRawRequest() { - StringBuffer sb = new StringBuffer(); - sb.append(String.format(Locale.US, "%02x", TEST_UPNP_VERSION)); - sb.append(bin2HexStr(TEST_UPNP_QUERY.getBytes())); - sb.append("x"); - - try { - WifiP2pServiceRequest request = - WifiP2pServiceRequest.newInstance( - WifiP2pServiceInfo.SERVICE_TYPE_UPNP, sb.toString()); - fail("Expected IllegalArgumentException"); - } catch (IllegalArgumentException ex) { - return; - } - } -} diff --git a/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pWfdInfoTest.java b/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pWfdInfoTest.java deleted file mode 100644 index 75df5bf928..0000000000 --- a/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pWfdInfoTest.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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.wifi.p2p.cts; - -import android.net.wifi.p2p.WifiP2pWfdInfo; -import android.test.AndroidTestCase; - -public class WifiP2pWfdInfoTest extends AndroidTestCase { - - private final int TEST_DEVICE_TYPE = WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE; - private final boolean TEST_DEVICE_ENABLE_STATUS = true; - private final boolean TEST_SESSION_STATUS = true; - private final int TEST_CONTROL_PORT = 9999; - private final int TEST_MAX_THROUGHPUT = 1024; - private final boolean TEST_CONTENT_PROTECTION_SUPPORTED_STATUS = true; - - public void testWifiP2pWfdInfo() { - WifiP2pWfdInfo info = new WifiP2pWfdInfo(); - - info.setDeviceType(TEST_DEVICE_TYPE); - info.setEnabled(TEST_DEVICE_ENABLE_STATUS); - info.setSessionAvailable(true); - info.setControlPort(TEST_CONTROL_PORT); - info.setMaxThroughput(TEST_MAX_THROUGHPUT); - info.setContentProtectionSupported(true); - - WifiP2pWfdInfo copiedInfo = new WifiP2pWfdInfo(info); - assertEquals(TEST_DEVICE_TYPE, copiedInfo.getDeviceType()); - assertEquals(TEST_DEVICE_ENABLE_STATUS, copiedInfo.isEnabled()); - assertEquals(TEST_SESSION_STATUS, copiedInfo.isSessionAvailable()); - assertEquals(TEST_CONTROL_PORT, copiedInfo.getControlPort()); - assertEquals(TEST_MAX_THROUGHPUT, copiedInfo.getMaxThroughput()); - assertEquals(TEST_CONTENT_PROTECTION_SUPPORTED_STATUS, - copiedInfo.isContentProtectionSupported()); - } -} diff --git a/tests/cts/net/src/android/net/wifi/rtt/cts/TestBase.java b/tests/cts/net/src/android/net/wifi/rtt/cts/TestBase.java deleted file mode 100644 index 07d5718044..0000000000 --- a/tests/cts/net/src/android/net/wifi/rtt/cts/TestBase.java +++ /dev/null @@ -1,237 +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.wifi.rtt.cts; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.location.LocationManager; -import android.net.wifi.ScanResult; -import android.net.wifi.WifiManager; -import android.net.wifi.rtt.RangingResult; -import android.net.wifi.rtt.RangingResultCallback; -import android.net.wifi.rtt.WifiRttManager; -import android.os.Handler; -import android.os.HandlerExecutor; -import android.os.HandlerThread; -import android.test.AndroidTestCase; - -import com.android.compatibility.common.util.SystemUtil; - -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executor; -import java.util.concurrent.TimeUnit; - -/** - * Base class for Wi-Fi RTT CTS test cases. Provides a uniform configuration and event management - * facility. - */ -public class TestBase extends AndroidTestCase { - protected static final String TAG = "WifiRttCtsTests"; - - // wait for Wi-Fi RTT to become available - private static final int WAIT_FOR_RTT_CHANGE_SECS = 10; - - // wait for Wi-Fi scan results to become available - private static final int WAIT_FOR_SCAN_RESULTS_SECS = 20; - - protected WifiRttManager mWifiRttManager; - protected WifiManager mWifiManager; - private LocationManager mLocationManager; - private WifiManager.WifiLock mWifiLock; - - private final HandlerThread mHandlerThread = new HandlerThread("SingleDeviceTest"); - protected final Executor mExecutor; - { - mHandlerThread.start(); - mExecutor = new HandlerExecutor(new Handler(mHandlerThread.getLooper())); - } - - /** - * Returns a flag indicating whether or not Wi-Fi RTT should be tested. Wi-Fi RTT - * should be tested if the feature is supported on the current device. - */ - static boolean shouldTestWifiRtt(Context context) { - final PackageManager pm = context.getPackageManager(); - return pm.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT); - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - if (!shouldTestWifiRtt(getContext())) { - return; - } - - mLocationManager = (LocationManager) getContext().getSystemService( - Context.LOCATION_SERVICE); - assertTrue("RTT testing requires Location to be enabled", - mLocationManager.isLocationEnabled()); - - mWifiRttManager = (WifiRttManager) getContext().getSystemService( - Context.WIFI_RTT_RANGING_SERVICE); - assertNotNull("Wi-Fi RTT Manager", mWifiRttManager); - - mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); - assertNotNull("Wi-Fi Manager", mWifiManager); - mWifiLock = mWifiManager.createWifiLock(TAG); - mWifiLock.acquire(); - if (!mWifiManager.isWifiEnabled()) { - SystemUtil.runShellCommand("svc wifi enable"); - } - - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(WifiRttManager.ACTION_WIFI_RTT_STATE_CHANGED); - WifiRttBroadcastReceiver receiver = new WifiRttBroadcastReceiver(); - mContext.registerReceiver(receiver, intentFilter); - if (!mWifiRttManager.isAvailable()) { - assertTrue("Timeout waiting for Wi-Fi RTT to change status", - receiver.waitForStateChange()); - assertTrue("Wi-Fi RTT is not available (should be)", mWifiRttManager.isAvailable()); - } - } - - @Override - protected void tearDown() throws Exception { - if (!shouldTestWifiRtt(getContext())) { - super.tearDown(); - return; - } - - super.tearDown(); - } - - class WifiRttBroadcastReceiver extends BroadcastReceiver { - private CountDownLatch mBlocker = new CountDownLatch(1); - - @Override - public void onReceive(Context context, Intent intent) { - if (WifiRttManager.ACTION_WIFI_RTT_STATE_CHANGED.equals(intent.getAction())) { - mBlocker.countDown(); - } - } - - boolean waitForStateChange() throws InterruptedException { - return mBlocker.await(WAIT_FOR_RTT_CHANGE_SECS, TimeUnit.SECONDS); - } - } - - class WifiScansBroadcastReceiver extends BroadcastReceiver { - private CountDownLatch mBlocker = new CountDownLatch(1); - - @Override - public void onReceive(Context context, Intent intent) { - if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(intent.getAction())) { - mBlocker.countDown(); - } - } - - boolean waitForStateChange() throws InterruptedException { - return mBlocker.await(WAIT_FOR_SCAN_RESULTS_SECS, TimeUnit.SECONDS); - } - } - - class ResultCallback extends RangingResultCallback { - private CountDownLatch mBlocker = new CountDownLatch(1); - private int mCode; // 0: success, otherwise RangingResultCallback STATUS_CODE_*. - private List mResults; - - @Override - public void onRangingFailure(int code) { - mCode = code; - mResults = null; // not necessary since intialized to null - but for completeness - mBlocker.countDown(); - } - - @Override - public void onRangingResults(List results) { - mCode = 0; // not necessary since initialized to 0 - but for completeness - mResults = results; - mBlocker.countDown(); - } - - /** - * Waits for the listener callback to be called - or an error (timeout, interruption). - * Returns true on callback called, false on error (timeout, interruption). - */ - boolean waitForCallback() throws InterruptedException { - return mBlocker.await(WAIT_FOR_RTT_CHANGE_SECS, TimeUnit.SECONDS); - } - - /** - * Returns the code of the callback operation. Will be 0 for success (onRangingResults - * called), else (if onRangingFailure called) will be one of the STATUS_CODE_* values. - */ - int getCode() { - return mCode; - } - - /** - * Returns the list of ranging results. In cases of error (getCode() != 0) will return null. - */ - List getResults() { - return mResults; - } - } - - /** - * Start a scan and return a list of observed ScanResults (APs). - */ - protected List scanAps() throws InterruptedException { - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); - WifiScansBroadcastReceiver receiver = new WifiScansBroadcastReceiver(); - mContext.registerReceiver(receiver, intentFilter); - - mWifiManager.startScan(); - receiver.waitForStateChange(); - mContext.unregisterReceiver(receiver); - return mWifiManager.getScanResults(); - } - - /** - * Start a scan and return a test AP which supports IEEE 802.11mc and which has the highest - * RSSI. Will perform N (parameterized) scans and get the best AP across both scans. - * - * Returns null if test AP is not found in the specified number of scans. - * - * @param numScanRetries Maximum number of scans retries (in addition to first scan). - */ - protected ScanResult scanForTestAp(int numScanRetries) - throws InterruptedException { - int scanCount = 0; - ScanResult bestTestAp = null; - while (scanCount <= numScanRetries) { - for (ScanResult scanResult : scanAps()) { - if (!scanResult.is80211mcResponder()) { - continue; - } - if (bestTestAp == null || scanResult.level > bestTestAp.level) { - bestTestAp = scanResult; - } - } - - scanCount++; - } - - return bestTestAp; - } -} diff --git a/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java b/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java deleted file mode 100644 index 9cbaf3953e..0000000000 --- a/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java +++ /dev/null @@ -1,404 +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.wifi.rtt.cts; - -import static org.mockito.Mockito.mock; - -import android.net.MacAddress; -import android.net.wifi.ScanResult; -import android.net.wifi.aware.PeerHandle; -import android.net.wifi.rtt.RangingRequest; -import android.net.wifi.rtt.RangingResult; -import android.net.wifi.rtt.ResponderLocation; -import android.platform.test.annotations.AppModeFull; - -import com.android.compatibility.common.util.DeviceReportLog; -import com.android.compatibility.common.util.ResultType; -import com.android.compatibility.common.util.ResultUnit; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * Wi-Fi RTT CTS test: range to all available Access Points which support IEEE 802.11mc. - */ -@AppModeFull(reason = "Cannot get WifiManager in instant app mode") -public class WifiRttTest extends TestBase { - // Number of scans to do while searching for APs supporting IEEE 802.11mc - private static final int NUM_SCANS_SEARCHING_FOR_IEEE80211MC_AP = 2; - - // Number of RTT measurements per AP - private static final int NUM_OF_RTT_ITERATIONS = 10; - - // Maximum failure rate of RTT measurements (percentage) - private static final int MAX_FAILURE_RATE_PERCENT = 10; - - // Maximum variation from the average measurement (measures consistency) - private static final int MAX_VARIATION_FROM_AVERAGE_DISTANCE_MM = 1000; - - // Minimum valid RSSI value - private static final int MIN_VALID_RSSI = -100; - - // Valid Mac Address - private static final MacAddress MAC = MacAddress.fromString("00:01:02:03:04:05"); - - /** - * Test Wi-Fi RTT ranging operation: - * - Scan for visible APs for the test AP (which is validated to support IEEE 802.11mc) - * - Perform N (constant) RTT operations - * - Validate: - * - Failure ratio < threshold (constant) - * - Result margin < threshold (constant) - */ - public void testRangingToTestAp() throws InterruptedException { - if (!shouldTestWifiRtt(getContext())) { - return; - } - - // Scan for IEEE 802.11mc supporting APs - ScanResult testAp = scanForTestAp(NUM_SCANS_SEARCHING_FOR_IEEE80211MC_AP); - assertNotNull( - "Cannot find any test APs which support RTT / IEEE 802.11mc - please verify that " - + "your test setup includes them!", testAp); - - // Perform RTT operations - RangingRequest request = new RangingRequest.Builder().addAccessPoint(testAp).build(); - List allResults = new ArrayList<>(); - int numFailures = 0; - int distanceSum = 0; - int distanceMin = 0; - int distanceMax = 0; - int[] statuses = new int[NUM_OF_RTT_ITERATIONS]; - int[] distanceMms = new int[NUM_OF_RTT_ITERATIONS]; - int[] distanceStdDevMms = new int[NUM_OF_RTT_ITERATIONS]; - int[] rssis = new int[NUM_OF_RTT_ITERATIONS]; - int[] numAttempted = new int[NUM_OF_RTT_ITERATIONS]; - int[] numSuccessful = new int[NUM_OF_RTT_ITERATIONS]; - long[] timestampsMs = new long[NUM_OF_RTT_ITERATIONS]; - byte[] lastLci = null; - byte[] lastLcr = null; - for (int i = 0; i < NUM_OF_RTT_ITERATIONS; ++i) { - ResultCallback callback = new ResultCallback(); - mWifiRttManager.startRanging(request, mExecutor, callback); - assertTrue("Wi-Fi RTT results: no callback on iteration " + i, - callback.waitForCallback()); - - List currentResults = callback.getResults(); - assertNotNull("Wi-Fi RTT results: null results (onRangingFailure) on iteration " + i, - currentResults); - assertEquals("Wi-Fi RTT results: unexpected # of results (expect 1) on iteration " + i, - 1, currentResults.size()); - RangingResult result = currentResults.get(0); - assertEquals("Wi-Fi RTT results: invalid result (wrong BSSID) entry on iteration " + i, - result.getMacAddress().toString(), testAp.BSSID); - assertNull("Wi-Fi RTT results: invalid result (non-null PeerHandle) entry on iteration " - + i, result.getPeerHandle()); - - allResults.add(result); - int status = result.getStatus(); - statuses[i] = status; - if (status == RangingResult.STATUS_SUCCESS) { - distanceSum += result.getDistanceMm(); - if (i == 0) { - distanceMin = result.getDistanceMm(); - distanceMax = result.getDistanceMm(); - } else { - distanceMin = Math.min(distanceMin, result.getDistanceMm()); - distanceMax = Math.max(distanceMax, result.getDistanceMm()); - } - - assertTrue("Wi-Fi RTT results: invalid RSSI on iteration " + i, - result.getRssi() >= MIN_VALID_RSSI); - - distanceMms[i - numFailures] = result.getDistanceMm(); - distanceStdDevMms[i - numFailures] = result.getDistanceStdDevMm(); - rssis[i - numFailures] = result.getRssi(); - numAttempted[i - numFailures] = result.getNumAttemptedMeasurements(); - numSuccessful[i - numFailures] = result.getNumSuccessfulMeasurements(); - timestampsMs[i - numFailures] = result.getRangingTimestampMillis(); - - byte[] currentLci = result.getLci(); - byte[] currentLcr = result.getLcr(); - if (i - numFailures > 0) { - assertTrue("Wi-Fi RTT results: invalid result (LCI mismatch) on iteration " + i, - Arrays.equals(currentLci, lastLci)); - assertTrue("Wi-Fi RTT results: invalid result (LCR mismatch) on iteration " + i, - Arrays.equals(currentLcr, lastLcr)); - } - lastLci = currentLci; - lastLcr = currentLcr; - } else { - numFailures++; - } - } - - // Save results to log - int numGoodResults = NUM_OF_RTT_ITERATIONS - numFailures; - DeviceReportLog reportLog = new DeviceReportLog(TAG, "testRangingToTestAp"); - reportLog.addValues("status_codes", statuses, ResultType.NEUTRAL, ResultUnit.NONE); - reportLog.addValues("distance_mm", Arrays.copyOf(distanceMms, numGoodResults), - ResultType.NEUTRAL, ResultUnit.NONE); - reportLog.addValues("distance_stddev_mm", Arrays.copyOf(distanceStdDevMms, numGoodResults), - ResultType.NEUTRAL, ResultUnit.NONE); - reportLog.addValues("rssi_dbm", Arrays.copyOf(rssis, numGoodResults), ResultType.NEUTRAL, - ResultUnit.NONE); - reportLog.addValues("num_attempted", Arrays.copyOf(numAttempted, numGoodResults), - ResultType.NEUTRAL, ResultUnit.NONE); - reportLog.addValues("num_successful", Arrays.copyOf(numSuccessful, numGoodResults), - ResultType.NEUTRAL, ResultUnit.NONE); - reportLog.addValues("timestamps", Arrays.copyOf(timestampsMs, numGoodResults), - ResultType.NEUTRAL, ResultUnit.NONE); - reportLog.submit(); - - // Analyze results - assertTrue("Wi-Fi RTT failure rate exceeds threshold: FAIL=" + numFailures + ", ITERATIONS=" - + NUM_OF_RTT_ITERATIONS + ", AP RSSI=" + testAp.level - + ", AP SSID=" + testAp.SSID, - numFailures <= NUM_OF_RTT_ITERATIONS * MAX_FAILURE_RATE_PERCENT / 100); - if (numFailures != NUM_OF_RTT_ITERATIONS) { - double distanceAvg = distanceSum / (NUM_OF_RTT_ITERATIONS - numFailures); - assertTrue("Wi-Fi RTT: Variation (max direction) exceeds threshold", - (distanceMax - distanceAvg) <= MAX_VARIATION_FROM_AVERAGE_DISTANCE_MM); - assertTrue("Wi-Fi RTT: Variation (min direction) exceeds threshold", - (distanceAvg - distanceMin) <= MAX_VARIATION_FROM_AVERAGE_DISTANCE_MM); - for (int i = 0; i < numGoodResults; ++i) { - assertNotSame("Number of attempted measurements is 0", 0, numAttempted[i]); - assertNotSame("Number of successful measurements is 0", 0, numSuccessful[i]); - } - } - } - - /** - * Validate that when a request contains more range operations than allowed (by API) that we - * get an exception. - */ - public void testRequestTooLarge() throws InterruptedException { - if (!shouldTestWifiRtt(getContext())) { - return; - } - ScanResult testAp = scanForTestAp(NUM_SCANS_SEARCHING_FOR_IEEE80211MC_AP); - assertNotNull( - "Cannot find any test APs which support RTT / IEEE 802.11mc - please verify that " - + "your test setup includes them!", testAp); - - RangingRequest.Builder builder = new RangingRequest.Builder(); - for (int i = 0; i < RangingRequest.getMaxPeers() - 2; ++i) { - builder.addAccessPoint(testAp); - } - - List scanResults = new ArrayList<>(); - scanResults.add(testAp); - scanResults.add(testAp); - scanResults.add(testAp); - - builder.addAccessPoints(scanResults); - - try { - mWifiRttManager.startRanging(builder.build(), mExecutor, new ResultCallback()); - } catch (IllegalArgumentException e) { - return; - } - - fail("Did not receive expected IllegalArgumentException when tried to range to too " - + "many peers"); - } - - /** - * Verify ResponderLocation API - */ - public void testRangingToTestApWithResponderLocation() throws InterruptedException { - if (!shouldTestWifiRtt(getContext())) { - return; - } - // Scan for IEEE 802.11mc supporting APs - ScanResult testAp = scanForTestAp(NUM_SCANS_SEARCHING_FOR_IEEE80211MC_AP); - assertNotNull( - "Cannot find any test APs which support RTT / IEEE 802.11mc - please verify that " - + "your test setup includes them!", testAp); - - // Perform RTT operations - RangingRequest request = new RangingRequest.Builder().addAccessPoint(testAp).build(); - ResultCallback callback = new ResultCallback(); - mWifiRttManager.startRanging(request, mExecutor, callback); - assertTrue("Wi-Fi RTT results: no callback! ", - callback.waitForCallback()); - - RangingResult result = callback.getResults().get(0); - assertEquals("Ranging request not success", - result.getStatus(), RangingResult.STATUS_SUCCESS); - ResponderLocation responderLocation = result.getUnverifiedResponderLocation(); - assertNotNull("ResponderLocation should not be null", responderLocation); - assertTrue("ResponderLocation is not valid", responderLocation.isLciSubelementValid()); - - // Check LCI related APIs - int exceptionCount = 0; - int apiCount = 0; - try { - apiCount++; - responderLocation.getLatitudeUncertainty(); - } catch (IllegalStateException e) { - exceptionCount++; - } - try { - apiCount++; - responderLocation.getLatitude(); - } catch (IllegalStateException e) { - exceptionCount++; - } - try { - apiCount++; - responderLocation.getLongitudeUncertainty(); - } catch (IllegalStateException e) { - exceptionCount++; - } - try { - apiCount++; - responderLocation.getLongitude(); - } catch (IllegalStateException e) { - exceptionCount++; - } - try { - apiCount++; - responderLocation.getAltitudeType(); - } catch (IllegalStateException e) { - exceptionCount++; - } - try { - apiCount++; - responderLocation.getAltitudeUncertainty(); - } catch (IllegalStateException e) { - exceptionCount++; - } - try { - apiCount++; - responderLocation.getAltitude(); - } catch (IllegalStateException e) { - exceptionCount++; - } - try { - apiCount++; - responderLocation.getDatum(); - } catch (IllegalStateException e) { - exceptionCount++; - } - try { - apiCount++; - responderLocation.getRegisteredLocationAgreementIndication(); - } catch (IllegalStateException e) { - exceptionCount++; - } - try { - apiCount++; - responderLocation.getLciVersion(); - } catch (IllegalStateException e) { - exceptionCount++; - } - try { - apiCount++; - assertNotNull(responderLocation.toLocation()); - } catch (IllegalStateException e) { - exceptionCount++; - } - // If LCI is not valid, all APIs should throw exception, otherwise no exception. - assertEquals("Exception number should equal to API number", - responderLocation.isLciSubelementValid()? 0 : apiCount, exceptionCount); - - // Verify ZaxisSubelement APIs - apiCount = 0; - exceptionCount = 0; - - try { - apiCount++; - responderLocation.getExpectedToMove(); - } catch (IllegalStateException e) { - exceptionCount++; - } - - try { - apiCount++; - responderLocation.getFloorNumber(); - } catch (IllegalStateException e) { - exceptionCount++; - } - - try { - apiCount++; - responderLocation.getHeightAboveFloorMeters(); - } catch (IllegalStateException e) { - exceptionCount++; - } - - try { - apiCount++; - responderLocation.getHeightAboveFloorUncertaintyMeters(); - } catch (IllegalStateException e) { - exceptionCount++; - } - // If Zaxis is not valid, all APIs should throw exception, otherwise no exception. - assertEquals("Exception number should equal to API number", - responderLocation.isZaxisSubelementValid() ? 0 : apiCount, exceptionCount); - // Verify civic location - if (responderLocation.toCivicLocationAddress() == null) { - assertNull(responderLocation.toCivicLocationSparseArray()); - } else { - assertNotNull(responderLocation.toCivicLocationSparseArray()); - } - // Verify map image - if (responderLocation.getMapImageUri() == null) { - assertNull(responderLocation.getMapImageMimeType()); - } else { - assertNotNull(responderLocation.getMapImageMimeType()); - } - boolean extraInfoOnAssociationIndication = - responderLocation.getExtraInfoOnAssociationIndication(); - assertNotNull("ColocatedBSSID list should be nonNull", - responderLocation.getColocatedBssids()); - } - - /** - * Verify ranging request with aware peer Mac address and peer handle. - */ - public void testAwareRttWithMacAddress() throws InterruptedException { - RangingRequest request = new RangingRequest.Builder() - .addWifiAwarePeer(MAC).build(); - ResultCallback callback = new ResultCallback(); - mWifiRttManager.startRanging(request, mExecutor, callback); - assertTrue("Wi-Fi RTT results: no callback", - callback.waitForCallback()); - List rangingResults = callback.getResults(); - assertNotNull("Wi-Fi RTT results: null results", rangingResults); - assertEquals(1, rangingResults.size()); - assertEquals(RangingResult.STATUS_FAIL, rangingResults.get(0).getStatus()); - } - - /** - * Verify ranging request with aware peer handle. - */ - public void testAwareRttWithPeerHandle() throws InterruptedException { - PeerHandle peerHandle = mock(PeerHandle.class); - RangingRequest request = new RangingRequest.Builder() - .addWifiAwarePeer(peerHandle).build(); - ResultCallback callback = new ResultCallback(); - mWifiRttManager.startRanging(request, mExecutor, callback); - assertTrue("Wi-Fi RTT results: no callback", - callback.waitForCallback()); - List rangingResults = callback.getResults(); - assertNotNull("Wi-Fi RTT results: null results", rangingResults); - assertEquals("Invalid peerHandle should return 0 result", 0, rangingResults.size()); - } -} From 146e767b32b4f73ac5af289d376ef438f655d282 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Mon, 30 Mar 2020 08:16:52 -0700 Subject: [PATCH 0826/1109] CtsWifiTests: Move wifi assets over to wifi test suite Bug: 152733292 Test: atest android.net.wifi.cts.ConfigParserTest Test: atest android.net.wifi.cts.PpsMoParserTest Test: atest android.net.wifi.cts.WifiManagerTest Change-Id: I47179210a4074bc9600ee07eaeb12c56f2f7bfc0 --- .../net/assets/HSR1ProfileWithCACert.base64 | 85 ------------------- tests/cts/net/assets/OWNERS | 4 - .../net/assets/PerProviderSubscription.xml | 80 ----------------- .../net/assets/ValidPasspointProfile.base64 | 1 - 4 files changed, 170 deletions(-) delete mode 100644 tests/cts/net/assets/HSR1ProfileWithCACert.base64 delete mode 100644 tests/cts/net/assets/OWNERS delete mode 100644 tests/cts/net/assets/PerProviderSubscription.xml delete mode 100644 tests/cts/net/assets/ValidPasspointProfile.base64 diff --git a/tests/cts/net/assets/HSR1ProfileWithCACert.base64 b/tests/cts/net/assets/HSR1ProfileWithCACert.base64 deleted file mode 100644 index 995963d2b4..0000000000 --- a/tests/cts/net/assets/HSR1ProfileWithCACert.base64 +++ /dev/null @@ -1,85 +0,0 @@ -Q29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5PXtib3VuZGFyeX0KQ29udGVu -dC1UcmFuc2Zlci1FbmNvZGluZzogYmFzZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBh -cHBsaWNhdGlvbi94LXBhc3Nwb2ludC1wcm9maWxlCkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6 -IGJhc2U2NAoKUEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29n -SUR4V1pYSkVWRVErTVM0eVBDOVdaWEpFVkVRKwpDaUFnUEU1dlpHVStDaUFnSUNBOFRtOWtaVTVo -YldVK1VHVnlVSEp2ZG1sa1pYSlRkV0p6WTNKcGNIUnBiMjQ4TDA1dlpHVk9ZVzFsClBnb2dJQ0Fn -UEZKVVVISnZjR1Z5ZEdsbGN6NEtJQ0FnSUNBZ1BGUjVjR1UrQ2lBZ0lDQWdJQ0FnUEVSRVJrNWhi -V1UrZFhKdU9uZG0KWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZ -M0pwY0hScGIyNDZNUzR3UEM5RVJFWk9ZVzFsUGdvZwpJQ0FnSUNBOEwxUjVjR1UrQ2lBZ0lDQThM -MUpVVUhKdmNHVnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVSth -VEF3TVR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFRt -RnRaVDVJYjIxbFUxQTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lD -QWdJQ0FnUEU1dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdApaVHd2VG05a1pVNWhiV1UrQ2lBZ0lD -QWdJQ0FnSUNBOFZtRnNkV1UrUTJWdWRIVnllU0JJYjNWelpUd3ZWbUZzZFdVK0NpQWdJQ0FnCklD -QWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcx -bFBrWlJSRTQ4TDA1dlpHVk8KWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBtMXBOaTVqYnk1 -MWF6d3ZWbUZzZFdVK0NpQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZwpJQ0FnSUNBZ0lEeE9iMlJsUGdv -Z0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsSnZZVzFwYm1kRGIyNXpiM0owYVhWdFQwazhMMDV2 -ClpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUGpFeE1qSXpNeXcwTkRVMU5qWThMMVpo -YkhWbFBnb2dJQ0FnSUNBZ0lEd3YKVG05a1pUNEtJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0E4 -VG05a1pUNEtJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStRM0psWkdWdQpkR2xoYkR3dlRtOWtaVTVo -YldVK0NpQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1VtVmhi -RzA4CkwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBuTm9ZV3RsYmk1emRHbHlj -bVZrTG1OdmJUd3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9i -MlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsVnpaWEp1WVcxbApVR0Z6YzNkdmNtUThM -MDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2Iy -UmxUbUZ0ClpUNVZjMlZ5Ym1GdFpUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lX -eDFaVDVxWVcxbGN6d3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lD -QWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxCaApjM04zYjNKa1BD -OU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbGx0T1hWYVJFRjNUbmM5UFR3 -dlZtRnNkV1UrCkNpQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0 -S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWwKUGtWQlVFMWxkR2h2WkR3dlRtOWtaVTVoYldV -K0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0FnSUR4TwpiMlJsVG1G -dFpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBOFZtRnNkV1Ur -TWpFOEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lDQWdJQ0Fn -SUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeE8KYjJSbFRtRnRaVDVKYm01bGNrMWxkR2h2 -WkR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQazFUTFVOSQpRVkF0 -VmpJOEwxWmhiSFZsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThM -MDV2WkdVK0NpQWdJQ0FnCklDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJ -Q0FnSUNBZ1BFNXZaR1ZPWVcxbFBrUnBaMmwwWVd4RFpYSjAKYVdacFkyRjBaVHd2VG05a1pVNWhi -V1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbApQ -a05sY25ScFptbGpZWFJsVkhsd1pUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lX -eDFaVDU0TlRBNWRqTThMMVpoCmJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lD -QWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNURaWEowVTBoQk1q -VTJSbWx1WjJWeWNISnBiblE4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdV -KwpNV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpG -bU1XWXhaakZtTVdZeFpqRm1NV1l4ClpqRm1NV1l4Wmp3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0FnSUNB -OEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWcKSUR4T2IyUmxQZ29nSUNB -Z0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxOSlRUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4 -VG05awpaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBrbE5VMGs4TDA1dlpHVk9ZVzFs -UGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzCmRXVSthVzF6YVR3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0Fn -SUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWcKSUNBZ0lDQWdQRTV2 -WkdWT1lXMWxQa1ZCVUZSNWNHVThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBOFZtRnNk -V1UrTWpROApMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEd3ZU -bTlrWlQ0S0lDQWdJQ0FnUEM5T2IyUmxQZ29nCklDQWdQQzlPYjJSbFBnb2dJRHd2VG05a1pUNEtQ -QzlOWjIxMFZISmxaVDRLCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94 -LXg1MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRMUzFD -UlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlowbEtR -VWxNYkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQwSm5U -bFlLUWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYyaGpU -azFxV1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZrRm5V -VEJGZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtOblMw -TkJVVVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIxV1ZY -TldkVzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJOQ01T -dHZSMWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpVClJV -RkRaV1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwyUzJo -U1FqZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dyVUdK -ck1IVjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIzUWtz -M2FFUTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNLMGxh -CmFYQllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFVRzVX -TTJreGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNXVVZH -U1hkWU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJOMDFF -YlVGR1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RWSkJk -MFJuCldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldVUldV -akJVUWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNXaDJZ -MDVCVVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQwaEZD -amxIUlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5VVNY -ZEpWV00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5KT1Ew -OTBhWE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhsT2JX -MVdUQW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhnMmVF -MXVWR3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxXYUhw -aFNFb3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5WnpG -S1VDdHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQTDNS -a1RrNTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJKUmts -RFFWUkZMUzB0TFMwSwotLXtib3VuZGFyeX0tLQo= diff --git a/tests/cts/net/assets/OWNERS b/tests/cts/net/assets/OWNERS deleted file mode 100644 index 14edd1d505..0000000000 --- a/tests/cts/net/assets/OWNERS +++ /dev/null @@ -1,4 +0,0 @@ -# Bug component: 31808 -etancohen@google.com -lorenzo@google.com -satk@google.com diff --git a/tests/cts/net/assets/PerProviderSubscription.xml b/tests/cts/net/assets/PerProviderSubscription.xml deleted file mode 100644 index de6c0c6dd2..0000000000 --- a/tests/cts/net/assets/PerProviderSubscription.xml +++ /dev/null @@ -1,80 +0,0 @@ - - 1.2 - - PerProviderSubscription - - - urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0 - - - - i001 - - HomeSP - - FriendlyName - Century House - - - FQDN - mi6.co.uk - - - RoamingConsortiumOI - 112233,445566 - - - - Credential - - Realm - shaken.stirred.com - - - UsernamePassword - - Username - james - - - Password - Ym9uZDAwNw== - - - EAPMethod - - EAPType - 21 - - - InnerMethod - MS-CHAP-V2 - - - - - DigitalCertificate - - CertificateType - x509v3 - - - CertSHA256Fingerprint - 1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f - - - - SIM - - IMSI - imsi - - - EAPType - 24 - - - - - - diff --git a/tests/cts/net/assets/ValidPasspointProfile.base64 b/tests/cts/net/assets/ValidPasspointProfile.base64 deleted file mode 100644 index 3f60eb85cc..0000000000 --- a/tests/cts/net/assets/ValidPasspointProfile.base64 +++ /dev/null @@ -1 +0,0 @@ -Q29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5PXtib3VuZGFyeX0KQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFzZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXBhc3Nwb2ludC1wcm9maWxlCkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoKUEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29nSUR4V1pYSkVWRVErTVM0eVBDOVdaWEpFVkVRK0NpQWdQRTV2WkdVK0NpQWdJQ0E4VG05a1pVNWhiV1UrVUdWeVVISnZkbWxrWlhKVGRXSnpZM0pwY0hScGIyNDhMMDV2WkdWT1lXMWxQZ29nSUNBZ1BGSlVVSEp2Y0dWeWRHbGxjejRLSUNBZ0lDQWdQRlI1Y0dVK0NpQWdJQ0FnSUNBZ1BFUkVSazVoYldVK2RYSnVPbmRtWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZM0pwY0hScGIyNDZNUzR3UEM5RVJFWk9ZVzFsUGdvZ0lDQWdJQ0E4TDFSNWNHVStDaUFnSUNBOEwxSlVVSEp2Y0dWeWRHbGxjejRLSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0E4VG05a1pVNWhiV1UrYVRBd01Ud3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0WlQ1SWIyMWxVMUE4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdFpUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4Vm1Gc2RXVStRVlJVSUZCaGMzTndiMmx1ZER3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQa1pSUkU0OEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBtRjBkSGRwWm1rdVkyOXRQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUR3dlRtOWtaVDRLSUNBZ0lDQWdQRTV2WkdVK0NpQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBrTnlaV1JsYm5ScFlXdzhMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWxQbEpsWVd4dFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJRHhXWVd4MVpUNTNiR0Z1TG0xdVl6UXhNQzV0WTJNek1UQXVNMmR3Y0c1bGRIZHZjbXN1YjNKblBDOVdZV3gxWlQ0S0lDQWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrVTBsTlBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0E4VG05a1pVNWhiV1UrU1UxVFNUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lXeDFaVDR6TVRBME1UQXFQQzlXWVd4MVpUNEtJQ0FnSUNBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBrVkJVRlI1Y0dVOEwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdJQ0FnSUR4V1lXeDFaVDR5TXp3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lDQWdJQ0FnSUNBOEwwNXZaR1UrQ2lBZ0lDQWdJRHd2VG05a1pUNEtJQ0FnSUR3dlRtOWtaVDRLSUNBOEwwNXZaR1UrQ2p3dlRXZHRkRlJ5WldVKwotLXtib3VuZGFyeX0tLQo= From ff1b6ec2dc8c2b8313f5f9a4e6fa8d5c5d20cec9 Mon Sep 17 00:00:00 2001 From: paulhu Date: Tue, 3 Mar 2020 10:35:16 +0800 Subject: [PATCH 0827/1109] Add a cts test for PermissionMonitor security problem Add a cts test to check whether app can have netd sytem permission even the app didn't grant the CONNECTIVITY_USE_RESTRICTED_NETWORKS permission. Bug: 144679405 Test: atest android.net.cts.ConnectivityManagerTest Change-Id: I2c717a11bda43db166a55d343eb752ab45947fe8 Merged-In: I2c717a11bda43db166a55d343eb752ab45947fe8 (cherry picked from commit ag/10285567) --- tests/cts/net/AndroidManifest.xml | 1 + .../net/cts/ConnectivityManagerTest.java | 45 ++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index c2b3bf77ad..267b05f7af 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -26,6 +26,7 @@ + diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index fa7e1381b3..ae3def6633 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -16,13 +16,17 @@ package android.net.cts; +import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS; import static android.content.pm.PackageManager.FEATURE_ETHERNET; import static android.content.pm.PackageManager.FEATURE_TELEPHONY; -import static android.content.pm.PackageManager.FEATURE_WIFI; import static android.content.pm.PackageManager.FEATURE_USB_HOST; +import static android.content.pm.PackageManager.FEATURE_WIFI; +import static android.content.pm.PackageManager.GET_PERMISSIONS; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.net.cts.util.CtsNetUtils.ConnectivityActionReceiver; import static android.net.cts.util.CtsNetUtils.HTTP_PORT; @@ -45,6 +49,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.res.Resources; import android.net.ConnectivityManager; @@ -59,10 +64,12 @@ import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; import android.net.NetworkRequest; +import android.net.NetworkUtils; import android.net.SocketKeepalive; import android.net.cts.util.CtsNetUtils; import android.net.util.KeepaliveUtils; import android.net.wifi.WifiManager; +import android.os.Binder; import android.os.Build; import android.os.Looper; import android.os.MessageQueue; @@ -78,6 +85,8 @@ import android.util.Pair; import androidx.test.InstrumentationRegistry; +import com.android.internal.util.ArrayUtils; + import libcore.io.Streams; import java.io.FileDescriptor; @@ -1272,4 +1281,38 @@ public class ConnectivityManagerTest extends AndroidTestCase { assertTrue("" + greater + " expected to be greater than or equal to " + lesser, greater >= lesser); } + + /** + * Verifies that apps are not allowed to access restricted networks even if they declare the + * CONNECTIVITY_USE_RESTRICTED_NETWORKS permission in their manifests. + * See. b/144679405. + */ + @AppModeFull(reason = "Cannot get WifiManager in instant app mode") + public void testRestrictedNetworkPermission() throws Exception { + // Ensure that CONNECTIVITY_USE_RESTRICTED_NETWORKS isn't granted to this package. + final PackageInfo app = mPackageManager.getPackageInfo(mContext.getPackageName(), + GET_PERMISSIONS); + final int index = ArrayUtils.indexOf( + app.requestedPermissions, CONNECTIVITY_USE_RESTRICTED_NETWORKS); + assertTrue(index >= 0); + assertTrue(app.requestedPermissionsFlags[index] != PERMISSION_GRANTED); + + // Ensure that NetworkUtils.queryUserAccess always returns false since this package should + // not have netd system permission to call this function. + final Network wifiNetwork = ensureWifiConnected(); + assertFalse(NetworkUtils.queryUserAccess(Binder.getCallingUid(), wifiNetwork.netId)); + + // Ensure that this package cannot bind to any restricted network that's currently + // connected. + Network[] networks = mCm.getAllNetworks(); + for (Network network : networks) { + NetworkCapabilities nc = mCm.getNetworkCapabilities(network); + if (nc != null && !nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) { + try { + network.bindSocket(new Socket()); + fail("Bind to restricted network " + network + " unexpectedly succeeded"); + } catch (IOException expected) {} + } + } + } } From ae7a0709b3370e6033c37a048752a854d40ebea0 Mon Sep 17 00:00:00 2001 From: paulhu Date: Thu, 26 Mar 2020 23:44:34 +0800 Subject: [PATCH 0828/1109] Add TetheringRequest CTS tests Test APIs below: TetheringRequest.getClientStaticIpv4Address() TetheringRequest.getLocalIpv4Address() TetheringRequest.getShouldShowEntitlementUi() TetheringRequest.getTetheringType() TetheringRequest.isExemptFromEntitlementCheck() TetheringRequest.Builder(int) TetheringRequest.Builder.build() TetheringRequest.Builder.setExemptFromEntitlementCheck(boolean) TetheringRequest.Builder.setShouldShowEntitlementUi(boolean) TetheringRequest.Builder.setStaticIpv4Addresses( \ android.net.LinkAddress, android.net.LinkAddress) Bug: 150632842 Test: atest CtsTetheringTest Change-Id: Ice5aefa1bacc1a635a7a79ce91d5d30ec5dcf335 --- .../tethering/cts/TetheringManagerTest.java | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java index 4d72eae3e4..86fe54ce54 100644 --- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java +++ b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java @@ -15,17 +15,22 @@ */ package android.tethering.test; +import static android.net.TetheringManager.TETHERING_USB; import static android.net.TetheringManager.TETHERING_WIFI; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.net.LinkAddress; import android.net.TetheringManager; import android.net.TetheringManager.TetheringRequest; -import android.os.ConditionVariable; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; @@ -37,8 +42,6 @@ import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.Arrays; -import java.util.Iterator; -import java.util.concurrent.Executor; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; @@ -225,4 +228,27 @@ public class TetheringManagerTest { mTM.stopTethering(TETHERING_WIFI); mTetherChangeReceiver.expectNoActiveTethering(DEFAULT_TIMEOUT_MS); } + + @Test + public void testTetheringRequest() { + final TetheringRequest tr = new TetheringRequest.Builder(TETHERING_WIFI).build(); + assertEquals(TETHERING_WIFI, tr.getTetheringType()); + assertNull(tr.getLocalIpv4Address()); + assertNull(tr.getClientStaticIpv4Address()); + assertFalse(tr.isExemptFromEntitlementCheck()); + assertTrue(tr.getShouldShowEntitlementUi()); + + final LinkAddress localAddr = new LinkAddress("192.168.24.5/24"); + final LinkAddress clientAddr = new LinkAddress("192.168.24.100/24"); + final TetheringRequest tr2 = new TetheringRequest.Builder(TETHERING_USB) + .setStaticIpv4Addresses(localAddr, clientAddr) + .setExemptFromEntitlementCheck(true) + .setShouldShowEntitlementUi(false).build(); + + assertEquals(localAddr, tr2.getLocalIpv4Address()); + assertEquals(clientAddr, tr2.getClientStaticIpv4Address()); + assertEquals(TETHERING_USB, tr2.getTetheringType()); + assertTrue(tr2.isExemptFromEntitlementCheck()); + assertFalse(tr2.getShouldShowEntitlementUi()); + } } From d4bff6cd28f96f5ab399643b52c45ebc7513dd54 Mon Sep 17 00:00:00 2001 From: Dan Shi Date: Tue, 31 Mar 2020 12:53:18 -0700 Subject: [PATCH 0829/1109] Remove tests from vts suite After vts-core is renamed to vts, the CTS tests won't be needed in vts suite. Bug: 151896491 Test: local build Exempt-From-Owner-Approval: This CL removes all CTS tests in vts suite, as vts is renamed to vts10. This CL won't change test logic or behavior. Change-Id: Idc9e9cc1d1080ff689823671a736bbb78bd7a740 --- tests/cts/hostside/Android.bp | 1 - tests/cts/hostside/app/Android.bp | 1 - tests/cts/hostside/app2/Android.bp | 1 - tests/cts/net/Android.bp | 1 - tests/cts/net/api23Test/Android.bp | 1 - tests/cts/net/appForApi23/Android.bp | 1 - tests/cts/net/native/qtaguid/Android.bp | 1 - 7 files changed, 7 deletions(-) diff --git a/tests/cts/hostside/Android.bp b/tests/cts/hostside/Android.bp index a8cc95ba5f..741c961e5f 100644 --- a/tests/cts/hostside/Android.bp +++ b/tests/cts/hostside/Android.bp @@ -24,7 +24,6 @@ java_test_host { // Tag this module as a cts test artifact test_suites: [ "cts", - "vts", "vts10", "general-tests", ], diff --git a/tests/cts/hostside/app/Android.bp b/tests/cts/hostside/app/Android.bp index 8b6d38b821..7a1145609f 100644 --- a/tests/cts/hostside/app/Android.bp +++ b/tests/cts/hostside/app/Android.bp @@ -35,7 +35,6 @@ android_test_helper_app { // Tag this module as a cts test artifact test_suites: [ "cts", - "vts", "vts10", "general-tests", ], diff --git a/tests/cts/hostside/app2/Android.bp b/tests/cts/hostside/app2/Android.bp index 0bb0d2f631..a6e9b118ff 100644 --- a/tests/cts/hostside/app2/Android.bp +++ b/tests/cts/hostside/app2/Android.bp @@ -23,7 +23,6 @@ android_test_helper_app { // Tag this module as a cts test artifact test_suites: [ "cts", - "vts", "vts10", "general-tests", ], diff --git a/tests/cts/net/Android.bp b/tests/cts/net/Android.bp index d77f416557..76bb27e448 100644 --- a/tests/cts/net/Android.bp +++ b/tests/cts/net/Android.bp @@ -64,7 +64,6 @@ android_test { defaults: ["CtsNetTestCasesDefaults"], test_suites: [ "cts", - "vts", "vts10", "general-tests", ], diff --git a/tests/cts/net/api23Test/Android.bp b/tests/cts/net/api23Test/Android.bp index 614a5a2a76..ffeef48a88 100644 --- a/tests/cts/net/api23Test/Android.bp +++ b/tests/cts/net/api23Test/Android.bp @@ -45,7 +45,6 @@ android_test { // Tag this module as a cts test artifact test_suites: [ "cts", - "vts", "vts10", "general-tests", ], diff --git a/tests/cts/net/appForApi23/Android.bp b/tests/cts/net/appForApi23/Android.bp index 17cfe3821b..399c199508 100644 --- a/tests/cts/net/appForApi23/Android.bp +++ b/tests/cts/net/appForApi23/Android.bp @@ -26,7 +26,6 @@ android_test { // Tag this module as a cts test artifact test_suites: [ "cts", - "vts", "vts10", "general-tests", ], diff --git a/tests/cts/net/native/qtaguid/Android.bp b/tests/cts/net/native/qtaguid/Android.bp index 054937b4fa..23a0cf764d 100644 --- a/tests/cts/net/native/qtaguid/Android.bp +++ b/tests/cts/net/native/qtaguid/Android.bp @@ -42,7 +42,6 @@ cc_test { // Tag this module as a cts test artifact test_suites: [ "cts", - "vts", "vts10", ], From 21793bad185f1d2054c0fee90a82d40b7287a11f Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Mon, 9 Mar 2020 21:22:04 +0900 Subject: [PATCH 0830/1109] Add a first NetworkAgent CTS test This is a basic test that only tests register(), markConnected(), unregister and onNetworkUnwanted. It provides the backbone for the tests, a harness to test callbacks on NetworkAgent, and demonstrates how the instrumentation in ConnectivityService can be used to test this API. Test: this Bug: 139268426 Change-Id: I022c9e237fdaec27338047c171c04e5a96cf89e3 --- tests/cts/net/AndroidManifest.xml | 5 + .../net/cts/IpSecManagerTunnelTest.java | 3 +- .../src/android/net/cts/NetworkAgentTest.kt | 142 ++++++++++++++++++ 3 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 tests/cts/net/src/android/net/cts/NetworkAgentTest.kt diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index c2b3bf77ad..baf914f1ac 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -35,6 +35,11 @@ + + diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java index 999d2f187b..1d83dda33c 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java @@ -192,9 +192,8 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { // Build a network request NetworkRequest nr = new NetworkRequest.Builder() + .clearCapabilities() .addTransportType(TRANSPORT_TEST) - .removeCapability(NET_CAPABILITY_TRUSTED) - .removeCapability(NET_CAPABILITY_NOT_VPN) .setNetworkSpecifier(ifname) .build(); diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt new file mode 100644 index 0000000000..85c94e7db2 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -0,0 +1,142 @@ +/* + * 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.cts + +import android.app.Instrumentation +import android.content.Context +import android.net.ConnectivityManager +import android.net.LinkProperties +import android.net.NetworkAgent +import android.net.NetworkAgentConfig +import android.net.NetworkCapabilities +import android.net.NetworkProvider +import android.net.NetworkRequest +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnNetworkUnwanted +import android.os.Build +import android.os.HandlerThread +import android.os.Looper +import androidx.test.InstrumentationRegistry +import androidx.test.runner.AndroidJUnit4 +import com.android.testutils.ArrayTrackRecord +import com.android.testutils.DevSdkIgnoreRule +import com.android.testutils.RecorderCallback.CallbackEntry.Lost +import com.android.testutils.TestableNetworkCallback +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import kotlin.test.assertFailsWith +import kotlin.test.assertTrue + +// This test doesn't really have a constraint on how fast the methods should return. If it's +// going to fail, it will simply wait forever, so setting a high timeout lowers the flake ratio +// without affecting the run time of successful runs. Thus, set a very high timeout. +private const val DEFAULT_TIMEOUT_MS = 5000L +// Any legal score (0~99) for the test network would do, as it is going to be kept up by the +// requests filed by the test and should never match normal internet requests. 70 is the default +// score of Ethernet networks, it's as good a value as any other. +private const val TEST_NETWORK_SCORE = 70 +private val instrumentation: Instrumentation + get() = InstrumentationRegistry.getInstrumentation() +private val context: Context + get() = InstrumentationRegistry.getContext() + +@RunWith(AndroidJUnit4::class) +class NetworkAgentTest { + @Rule @JvmField + val ignoreRule = DevSdkIgnoreRule(ignoreClassUpTo = Build.VERSION_CODES.Q) + + private val mCM = context.getSystemService(ConnectivityManager::class.java) + private val mHandlerThread = HandlerThread("${javaClass.simpleName} handler thread") + + private class Provider(context: Context, looper: Looper) : + NetworkProvider(context, looper, "NetworkAgentTest NetworkProvider") + + @Before + fun setUp() { + instrumentation.getUiAutomation().adoptShellPermissionIdentity() + mHandlerThread.start() + } + + @After + fun tearDown() { + mHandlerThread.quitSafely() + instrumentation.getUiAutomation().dropShellPermissionIdentity() + } + + internal class TestableNetworkAgent( + looper: Looper, + nc: NetworkCapabilities, + lp: LinkProperties, + conf: NetworkAgentConfig + ) : NetworkAgent(context, looper, TestableNetworkAgent::class.java.simpleName /* tag */, + nc, lp, TEST_NETWORK_SCORE, conf, Provider(context, looper)) { + private val history = ArrayTrackRecord().newReadHead() + + sealed class CallbackEntry { + object OnNetworkUnwanted : CallbackEntry() + } + + override fun onNetworkUnwanted() { + super.onNetworkUnwanted() + history.add(OnNetworkUnwanted) + } + + inline fun expectCallback() { + val foundCallback = history.poll(DEFAULT_TIMEOUT_MS) + assertTrue(foundCallback is T, "Expected ${T::class} but found $foundCallback") + } + } + + private fun createNetworkAgent(): TestableNetworkAgent { + val nc = NetworkCapabilities().apply { + addTransportType(NetworkCapabilities.TRANSPORT_TEST) + removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED) + removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED) + addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING) + addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) + } + val lp = LinkProperties() + val config = NetworkAgentConfig.Builder().build() + return TestableNetworkAgent(mHandlerThread.looper, nc, lp, config) + } + + private fun createConnectedNetworkAgent(): Pair { + val request: NetworkRequest = NetworkRequest.Builder() + .clearCapabilities() + .addTransportType(NetworkCapabilities.TRANSPORT_TEST) + .build() + val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS) + mCM.requestNetwork(request, callback) + val agent = createNetworkAgent().also { it.register() } + agent.markConnected() + return agent to callback + } + + @Test + fun testConnectAndUnregister() { + val (agent, callback) = createConnectedNetworkAgent() + callback.expectAvailableThenValidatedCallbacks(agent.network) + agent.unregister() + callback.expectCallback(agent.network) + agent.expectCallback() + assertFailsWith("Must not be able to register an agent twice") { + agent.register() + } + } +} From a2686116292edaa8e25a0997251721778ad7d845 Mon Sep 17 00:00:00 2001 From: Paul Hu Date: Thu, 2 Apr 2020 19:14:44 +0000 Subject: [PATCH 0831/1109] Add TetheringRequest CTS tests Test APIs below: TetheringRequest.getClientStaticIpv4Address() TetheringRequest.getLocalIpv4Address() TetheringRequest.getShouldShowEntitlementUi() TetheringRequest.getTetheringType() TetheringRequest.isExemptFromEntitlementCheck() TetheringRequest.Builder(int) TetheringRequest.Builder.build() TetheringRequest.Builder.setExemptFromEntitlementCheck(boolean) TetheringRequest.Builder.setShouldShowEntitlementUi(boolean) TetheringRequest.Builder.setStaticIpv4Addresses( \ android.net.LinkAddress, android.net.LinkAddress) Bug: 150632842 Test: atest CtsTetheringTest Change-Id: Ice5aefa1bacc1a635a7a79ce91d5d30ec5dcf335 Merged-In: Ice5aefa1bacc1a635a7a79ce91d5d30ec5dcf335 (cherry picked from commit 3780b3720ca19063e0d4c0372422f3105dc5bb86) --- .../tethering/cts/TetheringManagerTest.java | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java index 4d72eae3e4..86fe54ce54 100644 --- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java +++ b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java @@ -15,17 +15,22 @@ */ package android.tethering.test; +import static android.net.TetheringManager.TETHERING_USB; import static android.net.TetheringManager.TETHERING_WIFI; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.net.LinkAddress; import android.net.TetheringManager; import android.net.TetheringManager.TetheringRequest; -import android.os.ConditionVariable; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; @@ -37,8 +42,6 @@ import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.Arrays; -import java.util.Iterator; -import java.util.concurrent.Executor; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; @@ -225,4 +228,27 @@ public class TetheringManagerTest { mTM.stopTethering(TETHERING_WIFI); mTetherChangeReceiver.expectNoActiveTethering(DEFAULT_TIMEOUT_MS); } + + @Test + public void testTetheringRequest() { + final TetheringRequest tr = new TetheringRequest.Builder(TETHERING_WIFI).build(); + assertEquals(TETHERING_WIFI, tr.getTetheringType()); + assertNull(tr.getLocalIpv4Address()); + assertNull(tr.getClientStaticIpv4Address()); + assertFalse(tr.isExemptFromEntitlementCheck()); + assertTrue(tr.getShouldShowEntitlementUi()); + + final LinkAddress localAddr = new LinkAddress("192.168.24.5/24"); + final LinkAddress clientAddr = new LinkAddress("192.168.24.100/24"); + final TetheringRequest tr2 = new TetheringRequest.Builder(TETHERING_USB) + .setStaticIpv4Addresses(localAddr, clientAddr) + .setExemptFromEntitlementCheck(true) + .setShouldShowEntitlementUi(false).build(); + + assertEquals(localAddr, tr2.getLocalIpv4Address()); + assertEquals(clientAddr, tr2.getClientStaticIpv4Address()); + assertEquals(TETHERING_USB, tr2.getTetheringType()); + assertTrue(tr2.isExemptFromEntitlementCheck()); + assertFalse(tr2.getShouldShowEntitlementUi()); + } } From 5c22928658f73e720dbebd31f9c8ad9d728bb12f Mon Sep 17 00:00:00 2001 From: evitayan Date: Sun, 8 Mar 2020 18:26:51 -0700 Subject: [PATCH 0832/1109] Create build files for CtsIkeTestCases Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: I2f49fc12314ac648e8df816058d599033c822dca --- tests/cts/net/ipsec/Android.bp | 46 +++++++++++++++++++ tests/cts/net/ipsec/AndroidManifest.xml | 39 ++++++++++++++++ tests/cts/net/ipsec/AndroidTest.xml | 30 ++++++++++++ .../net/ipsec/ike/cts/SaProposalTest.java | 30 ++++++++++++ 4 files changed, 145 insertions(+) create mode 100644 tests/cts/net/ipsec/Android.bp create mode 100644 tests/cts/net/ipsec/AndroidManifest.xml create mode 100644 tests/cts/net/ipsec/AndroidTest.xml create mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java diff --git a/tests/cts/net/ipsec/Android.bp b/tests/cts/net/ipsec/Android.bp new file mode 100644 index 0000000000..86969c31ae --- /dev/null +++ b/tests/cts/net/ipsec/Android.bp @@ -0,0 +1,46 @@ +// 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. + +android_test { + name: "CtsIkeTestCases", + defaults: ["cts_defaults"], + + // Include both the 32 and 64 bit versions + compile_multilib: "both", + + libs: [ + "android.net.ipsec.ike.stubs.system", + "android.test.base.stubs", + ], + + srcs: [ + "src/**/*.java", + ], + + static_libs: [ + "androidx.test.ext.junit", + "compatibility-device-util-axt", + "ctstestrunner-axt", + ], + + platform_apis: true, + + // Tag this module as a cts test artifact + test_suites: [ + "cts", + "mts", + "vts", + "general-tests", + ], +} diff --git a/tests/cts/net/ipsec/AndroidManifest.xml b/tests/cts/net/ipsec/AndroidManifest.xml new file mode 100644 index 0000000000..de7d23cbd5 --- /dev/null +++ b/tests/cts/net/ipsec/AndroidManifest.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/tests/cts/net/ipsec/AndroidTest.xml b/tests/cts/net/ipsec/AndroidTest.xml new file mode 100644 index 0000000000..09e5c93cf8 --- /dev/null +++ b/tests/cts/net/ipsec/AndroidTest.xml @@ -0,0 +1,30 @@ + + + diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java new file mode 100644 index 0000000000..47e8f0174d --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java @@ -0,0 +1,30 @@ +/* + * 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.ipsec.ike.cts; + +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class SaProposalTest { + @Test + public void testBuildIkeSaProposal() { + // TODO(b/148689509): Add real tests here + } +} From 03dfb41f8cd8bd0a5bde2a884d355fdb82d0be9f Mon Sep 17 00:00:00 2001 From: Yan Yan Date: Fri, 3 Apr 2020 23:08:47 +0000 Subject: [PATCH 0833/1109] Create build files for CtsIkeTestCases Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: I2f49fc12314ac648e8df816058d599033c822dca Merged-In: I2f49fc12314ac648e8df816058d599033c822dca (cherry picked from commit aead83c98a09c70a20e034474c4b4a4995cc3bac) --- tests/cts/net/ipsec/Android.bp | 46 +++++++++++++++++++ tests/cts/net/ipsec/AndroidManifest.xml | 39 ++++++++++++++++ tests/cts/net/ipsec/AndroidTest.xml | 30 ++++++++++++ .../net/ipsec/ike/cts/SaProposalTest.java | 30 ++++++++++++ 4 files changed, 145 insertions(+) create mode 100644 tests/cts/net/ipsec/Android.bp create mode 100644 tests/cts/net/ipsec/AndroidManifest.xml create mode 100644 tests/cts/net/ipsec/AndroidTest.xml create mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java diff --git a/tests/cts/net/ipsec/Android.bp b/tests/cts/net/ipsec/Android.bp new file mode 100644 index 0000000000..86969c31ae --- /dev/null +++ b/tests/cts/net/ipsec/Android.bp @@ -0,0 +1,46 @@ +// 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. + +android_test { + name: "CtsIkeTestCases", + defaults: ["cts_defaults"], + + // Include both the 32 and 64 bit versions + compile_multilib: "both", + + libs: [ + "android.net.ipsec.ike.stubs.system", + "android.test.base.stubs", + ], + + srcs: [ + "src/**/*.java", + ], + + static_libs: [ + "androidx.test.ext.junit", + "compatibility-device-util-axt", + "ctstestrunner-axt", + ], + + platform_apis: true, + + // Tag this module as a cts test artifact + test_suites: [ + "cts", + "mts", + "vts", + "general-tests", + ], +} diff --git a/tests/cts/net/ipsec/AndroidManifest.xml b/tests/cts/net/ipsec/AndroidManifest.xml new file mode 100644 index 0000000000..de7d23cbd5 --- /dev/null +++ b/tests/cts/net/ipsec/AndroidManifest.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/tests/cts/net/ipsec/AndroidTest.xml b/tests/cts/net/ipsec/AndroidTest.xml new file mode 100644 index 0000000000..09e5c93cf8 --- /dev/null +++ b/tests/cts/net/ipsec/AndroidTest.xml @@ -0,0 +1,30 @@ + + + diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java new file mode 100644 index 0000000000..47e8f0174d --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java @@ -0,0 +1,30 @@ +/* + * 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.ipsec.ike.cts; + +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class SaProposalTest { + @Test + public void testBuildIkeSaProposal() { + // TODO(b/148689509): Add real tests here + } +} From 1f4e465b5af26a105c59930af337b6a99d1a9e70 Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Sun, 5 Apr 2020 01:51:10 -0700 Subject: [PATCH 0834/1109] Dump debug logs after a test failure before running tearDown()s. Bug: 145420790 Test: atest hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java Change-Id: I19516046f05bd4564c57542ae82a82a1cc362f48 --- ...ractRestrictBackgroundNetworkTestCase.java | 8 +--- .../net/hostside/NetworkPolicyTestRunner.java | 44 +++++++++++++++++++ 2 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestRunner.java diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 69dd2adb48..21212af824 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -62,13 +62,10 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import androidx.test.platform.app.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; - /** * Superclass for tests related to background network restrictions. */ -@RunWith(AndroidJUnit4.class) +@RunWith(NetworkPolicyTestRunner.class) public abstract class AbstractRestrictBackgroundNetworkTestCase { public static final String TAG = "RestrictBackgroundNetworkTests"; @@ -137,8 +134,7 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase { private boolean mIsLocationOn; @Rule - public final RuleChain mRuleChain = RuleChain.outerRule(new DumpOnFailureRule()) - .around(new RequiredPropertiesRule()) + public final RuleChain mRuleChain = RuleChain.outerRule(new RequiredPropertiesRule()) .around(new MeterednessConfigurationRule()); protected void setUp() throws Exception { diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestRunner.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestRunner.java new file mode 100644 index 0000000000..f340907ae5 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestRunner.java @@ -0,0 +1,44 @@ +/* + * 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 com.android.cts.net.hostside; + +import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner; + +import org.junit.rules.RunRules; +import org.junit.rules.TestRule; +import org.junit.runners.model.FrameworkMethod; +import org.junit.runners.model.InitializationError; +import org.junit.runners.model.Statement; + +import java.util.List; + +/** + * Custom runner to allow dumping logs after a test failure before the @After methods get to run. + */ +public class NetworkPolicyTestRunner extends AndroidJUnit4ClassRunner { + private TestRule mDumpOnFailureRule = new DumpOnFailureRule(); + + public NetworkPolicyTestRunner(Class klass) throws InitializationError { + super(klass); + } + + @Override + public Statement methodInvoker(FrameworkMethod method, Object test) { + return new RunRules(super.methodInvoker(method, test), List.of(mDumpOnFailureRule), + describeChild(method)); + } +} From b03df59c70d09bb8f4e41994e944ad49be9be626 Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Thu, 21 Nov 2019 21:37:22 +0800 Subject: [PATCH 0835/1109] Add ProxyInfoTest to test public APIs Add cts to test current public APIs and new public APIs. Bug: 151110319 Bug: 152617305 Test: atest CtsNetTestCasesLatestSdk:ProxyInfoTest Change-Id: I451989f7312fb98ec2fa0b7b9ddc856ecf2087be --- .../src/android/net/cts/ProxyInfoTest.java | 135 ++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 tests/cts/net/src/android/net/cts/ProxyInfoTest.java diff --git a/tests/cts/net/src/android/net/cts/ProxyInfoTest.java b/tests/cts/net/src/android/net/cts/ProxyInfoTest.java new file mode 100644 index 0000000000..1c5624ce38 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/ProxyInfoTest.java @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2019 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 static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import android.net.ProxyInfo; +import android.net.Uri; +import android.os.Build; + +import androidx.test.runner.AndroidJUnit4; + +import com.android.testutils.DevSdkIgnoreRule; +import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +@RunWith(AndroidJUnit4.class) +public final class ProxyInfoTest { + private static final String TEST_HOST = "test.example.com"; + private static final int TEST_PORT = 5566; + private static final Uri TEST_URI = Uri.parse("https://test.example.com"); + // This matches android.net.ProxyInfo#LOCAL_EXCL_LIST + private static final String LOCAL_EXCL_LIST = ""; + // This matches android.net.ProxyInfo#LOCAL_HOST + private static final String LOCAL_HOST = "localhost"; + // This matches android.net.ProxyInfo#LOCAL_PORT + private static final int LOCAL_PORT = -1; + + @Rule + public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule(); + + @Test + public void testConstructor() { + final ProxyInfo proxy = new ProxyInfo((ProxyInfo) null); + checkEmpty(proxy); + + assertEquals(proxy, new ProxyInfo(proxy)); + } + + @Test + public void testBuildDirectProxy() { + final ProxyInfo proxy1 = ProxyInfo.buildDirectProxy(TEST_HOST, TEST_PORT); + + assertEquals(TEST_HOST, proxy1.getHost()); + assertEquals(TEST_PORT, proxy1.getPort()); + assertArrayEquals(new String[0], proxy1.getExclusionList()); + assertEquals(Uri.EMPTY, proxy1.getPacFileUrl()); + + final List exclList = new ArrayList<>(); + exclList.add("localhost"); + exclList.add("*.exclusion.com"); + final ProxyInfo proxy2 = ProxyInfo.buildDirectProxy(TEST_HOST, TEST_PORT, exclList); + + assertEquals(TEST_HOST, proxy2.getHost()); + assertEquals(TEST_PORT, proxy2.getPort()); + assertArrayEquals(exclList.toArray(new String[0]), proxy2.getExclusionList()); + assertEquals(Uri.EMPTY, proxy2.getPacFileUrl()); + } + + @Test @IgnoreUpTo(Build.VERSION_CODES.Q) + public void testBuildPacProxy() { + final ProxyInfo proxy1 = ProxyInfo.buildPacProxy(TEST_URI); + + assertEquals(LOCAL_HOST, proxy1.getHost()); + assertEquals(LOCAL_PORT, proxy1.getPort()); + assertArrayEquals(LOCAL_EXCL_LIST.toLowerCase(Locale.ROOT).split(","), + proxy1.getExclusionList()); + assertEquals(TEST_URI, proxy1.getPacFileUrl()); + + final ProxyInfo proxy2 = ProxyInfo.buildPacProxy(TEST_URI, TEST_PORT); + + assertEquals(LOCAL_HOST, proxy2.getHost()); + assertEquals(TEST_PORT, proxy2.getPort()); + assertArrayEquals(LOCAL_EXCL_LIST.toLowerCase(Locale.ROOT).split(","), + proxy2.getExclusionList()); + assertEquals(TEST_URI, proxy2.getPacFileUrl()); + } + + @Test + public void testIsValid() { + final ProxyInfo proxy1 = ProxyInfo.buildDirectProxy(TEST_HOST, TEST_PORT); + assertTrue(proxy1.isValid()); + + // Given empty host + final ProxyInfo proxy2 = ProxyInfo.buildDirectProxy("", TEST_PORT); + assertFalse(proxy2.isValid()); + // Given invalid host + final ProxyInfo proxy3 = ProxyInfo.buildDirectProxy(".invalid.com", TEST_PORT); + assertFalse(proxy3.isValid()); + // Given invalid port. + final ProxyInfo proxy4 = ProxyInfo.buildDirectProxy(TEST_HOST, 0); + assertFalse(proxy4.isValid()); + // Given another invalid port + final ProxyInfo proxy5 = ProxyInfo.buildDirectProxy(TEST_HOST, 65536); + assertFalse(proxy5.isValid()); + // Given invalid exclusion list + final List exclList = new ArrayList<>(); + exclList.add(".invalid.com"); + exclList.add("%.test.net"); + final ProxyInfo proxy6 = ProxyInfo.buildDirectProxy(TEST_HOST, TEST_PORT, exclList); + assertFalse(proxy6.isValid()); + } + + private void checkEmpty(ProxyInfo proxy) { + assertNull(proxy.getHost()); + assertEquals(0, proxy.getPort()); + assertNull(proxy.getExclusionList()); + assertEquals(Uri.EMPTY, proxy.getPacFileUrl()); + } +} From 64522ba4eae63b8daf37197a2aec357732b9a75d Mon Sep 17 00:00:00 2001 From: markchien Date: Fri, 6 Mar 2020 10:37:21 +0800 Subject: [PATCH 0836/1109] Add testRegisterTetheringEventCallback for CtsTetheringTest Bug: 150632712 Bug: 150631563 Test: atest CtsTetheringTest Change-Id: I55895c8b26acb7ec905d75d1f4b2a8964b13187a --- .../tethering/cts/TetheringManagerTest.java | 181 +++++++++++++++++- 1 file changed, 179 insertions(+), 2 deletions(-) diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java index 86fe54ce54..b132982e1a 100644 --- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java +++ b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java @@ -29,9 +29,14 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.LinkAddress; +import android.net.Network; +import android.net.TetheredClient; import android.net.TetheringManager; +import android.net.TetheringManager.TetheringEventCallback; +import android.net.TetheringManager.TetheringInterfaceRegexps; import android.net.TetheringManager.TetheringRequest; +import androidx.annotation.NonNull; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; @@ -42,6 +47,8 @@ import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.List; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; @@ -195,8 +202,12 @@ public class TetheringManagerTest { } } - private static boolean isIfaceMatch(final String[] ifaceRegexs, - final ArrayList ifaces) { + private static boolean isIfaceMatch(final List ifaceRegexs, + final List ifaces) { + return isIfaceMatch(ifaceRegexs.toArray(new String[0]), ifaces); + } + + private static boolean isIfaceMatch(final String[] ifaceRegexs, final List ifaces) { if (ifaceRegexs == null) fail("ifaceRegexs should not be null"); if (ifaces == null) return false; @@ -251,4 +262,170 @@ public class TetheringManagerTest { assertTrue(tr2.isExemptFromEntitlementCheck()); assertFalse(tr2.getShouldShowEntitlementUi()); } + + // Must poll the callback before looking at the member. + private static class TestTetheringEventCallback implements TetheringEventCallback { + public enum CallbackType { + ON_SUPPORTED, + ON_UPSTREAM, + ON_TETHERABLE_REGEX, + ON_TETHERABLE_IFACES, + ON_TETHERED_IFACES, + ON_ERROR, + ON_CLIENTS, + }; + + public static class CallbackValue { + public final CallbackType callbackType; + public final Object callbackParam; + public final int callbackParam2; + + private CallbackValue(final CallbackType type, final Object param, final int param2) { + this.callbackType = type; + this.callbackParam = param; + this.callbackParam2 = param2; + } + } + private final LinkedBlockingQueue mCallbacks = new LinkedBlockingQueue<>(); + + private TetheringInterfaceRegexps mTetherableRegex; + private List mTetherableIfaces; + private List mTetheredIfaces; + + @Override + public void onTetheringSupported(boolean supported) { + mCallbacks.add(new CallbackValue(CallbackType.ON_SUPPORTED, null, 0)); + } + + @Override + public void onUpstreamChanged(Network network) { + mCallbacks.add(new CallbackValue(CallbackType.ON_UPSTREAM, network, 0)); + } + + @Override + public void onTetherableInterfaceRegexpsChanged(TetheringInterfaceRegexps reg) { + mTetherableRegex = reg; + mCallbacks.add(new CallbackValue(CallbackType.ON_TETHERABLE_REGEX, reg, 0)); + } + + @Override + public void onTetherableInterfacesChanged(List interfaces) { + mTetherableIfaces = interfaces; + mCallbacks.add(new CallbackValue(CallbackType.ON_TETHERABLE_IFACES, interfaces, 0)); + } + + @Override + public void onTetheredInterfacesChanged(List interfaces) { + mTetheredIfaces = interfaces; + mCallbacks.add(new CallbackValue(CallbackType.ON_TETHERED_IFACES, interfaces, 0)); + } + + @Override + public void onError(String ifName, int error) { + mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, ifName, error)); + } + + @Override + public void onClientsChanged(Collection clients) { + mCallbacks.add(new CallbackValue(CallbackType.ON_CLIENTS, clients, 0)); + } + + public CallbackValue pollCallback() { + try { + return mCallbacks.poll(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + fail("Callback not seen"); + } + return null; + } + + public void expectTetherableInterfacesChanged(@NonNull List regexs) { + while (true) { + final CallbackValue cv = pollCallback(); + if (cv == null) fail("No expected tetherable ifaces callback"); + if (cv.callbackType != CallbackType.ON_TETHERABLE_IFACES) continue; + + final List interfaces = (List) cv.callbackParam; + if (isIfaceMatch(regexs, interfaces)) break; + } + } + + public void expectTetheredInterfacesChanged(@NonNull List regexs) { + while (true) { + final CallbackValue cv = pollCallback(); + if (cv == null) fail("No expected tethered ifaces callback"); + if (cv.callbackType != CallbackType.ON_TETHERED_IFACES) continue; + + final List interfaces = (List) cv.callbackParam; + + // Null regexs means no active tethering. + if (regexs == null) { + if (interfaces.size() == 0) break; + } else if (isIfaceMatch(regexs, interfaces)) { + break; + } + } + } + + public void expectCallbackStarted() { + // The each bit represent a type from CallbackType.ON_*. + // Expect all of callbacks except for ON_ERROR. + final int expectedBitMap = 0x7f ^ (1 << CallbackType.ON_ERROR.ordinal()); + int receivedBitMap = 0; + while (receivedBitMap != expectedBitMap) { + final CallbackValue cv = pollCallback(); + if (cv == null) { + fail("No expected callbacks, " + "expected bitmap: " + + expectedBitMap + ", actual: " + receivedBitMap); + } + receivedBitMap = receivedBitMap | (1 << cv.callbackType.ordinal()); + } + } + + public TetheringInterfaceRegexps getTetheringInterfaceRegexps() { + return mTetherableRegex; + } + + public List getTetherableInterfaces() { + return mTetherableIfaces; + } + + public List getTetheredInterfaces() { + return mTetheredIfaces; + } + } + + @Test + public void testRegisterTetheringEventCallback() throws Exception { + if (!mTM.isTetheringSupported()) return; + + final TestTetheringEventCallback tetherEventCallback = new TestTetheringEventCallback(); + + mTM.registerTetheringEventCallback(c -> c.run(), tetherEventCallback); + tetherEventCallback.expectCallbackStarted(); + + final TetheringInterfaceRegexps tetherableRegexs = + tetherEventCallback.getTetheringInterfaceRegexps(); + final List wifiRegexs = tetherableRegexs.getTetherableWifiRegexs(); + if (wifiRegexs.size() == 0) return; + + final boolean isIfaceAvailWhenNoTethering = + isIfaceMatch(wifiRegexs, tetherEventCallback.getTetherableInterfaces()); + + mTM.startTethering(new TetheringRequest.Builder(TETHERING_WIFI).build(), c -> c.run(), + new StartTetheringCallback()); + + // If interface is already available before starting tethering, the available callback may + // not be sent after tethering enabled. + if (!isIfaceAvailWhenNoTethering) { + tetherEventCallback.expectTetherableInterfacesChanged(wifiRegexs); + } + + tetherEventCallback.expectTetheredInterfacesChanged(wifiRegexs); + + mTM.stopTethering(TETHERING_WIFI); + + tetherEventCallback.expectTetheredInterfacesChanged(null); + mTM.unregisterTetheringEventCallback(tetherEventCallback); + } } From a18f6094e1bbe992bb7659fe34a56e7a6e90dfa2 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Fri, 13 Dec 2019 22:23:01 +0900 Subject: [PATCH 0837/1109] CTS test for NetworkRequest#getSpecifier Bug: 135998869 Test: this Change-Id: I339c62f0ce68cc3c19abbaef7f99d216362db4cb --- .../android/net/cts/NetworkRequestTest.java | 52 ++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java index c862c77bc7..8b97c8cb92 100644 --- a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java @@ -18,11 +18,42 @@ package android.net.cts; import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS; import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH; +import static android.net.NetworkCapabilities.TRANSPORT_WIFI; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import android.net.MacAddress; import android.net.NetworkRequest; -import android.test.AndroidTestCase; +import android.net.NetworkSpecifier; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiNetworkSpecifier; +import android.os.Build; +import android.os.PatternMatcher; +import android.util.Pair; -public class NetworkRequestTest extends AndroidTestCase { +import androidx.test.runner.AndroidJUnit4; + +import com.android.testutils.DevSdkIgnoreRule; +import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class NetworkRequestTest { + @Rule + public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule(); + + private static final String TEST_SSID = "TestSSID"; + private static final int TEST_UID = 2097; + private static final String TEST_PACKAGE_NAME = "test.package.name"; + private static final MacAddress ARBITRARY_ADDRESS = MacAddress.fromString("3:5:8:12:9:2"); + + @Test public void testCapabilities() { assertTrue(new NetworkRequest.Builder().addCapability(NET_CAPABILITY_MMS).build() .hasCapability(NET_CAPABILITY_MMS)); @@ -30,10 +61,27 @@ public class NetworkRequestTest extends AndroidTestCase { .hasCapability(NET_CAPABILITY_MMS)); } + @Test public void testTransports() { assertTrue(new NetworkRequest.Builder().addTransportType(TRANSPORT_BLUETOOTH).build() .hasTransport(TRANSPORT_BLUETOOTH)); assertFalse(new NetworkRequest.Builder().removeTransportType(TRANSPORT_BLUETOOTH).build() .hasTransport(TRANSPORT_BLUETOOTH)); } + + @Test + @IgnoreUpTo(Build.VERSION_CODES.Q) + public void testSpecifier() { + assertNull(new NetworkRequest.Builder().build().getNetworkSpecifier()); + final WifiNetworkSpecifier specifier = new WifiNetworkSpecifier.Builder() + .setSsidPattern(new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL)) + .setBssidPattern(ARBITRARY_ADDRESS, ARBITRARY_ADDRESS) + .build(); + final NetworkSpecifier obtainedSpecifier = new NetworkRequest.Builder() + .addTransportType(TRANSPORT_WIFI) + .setNetworkSpecifier(specifier) + .build() + .getNetworkSpecifier(); + assertEquals(obtainedSpecifier, specifier); + } } From 2648ad46fe74d402f980f0fb315728c827f15d01 Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Fri, 8 Nov 2019 21:19:51 +0800 Subject: [PATCH 0838/1109] CTS test for DhcpInfo parcel/unparcel Bug: 139268426 Bug: 135998869 Test: atest CtsNetTestCasesLatestSdk:android.net.cts.DhcpInfoTest Change-Id: I076241072688fca37b8451873183f9597bc5fe79 --- .../net/src/android/net/cts/DhcpInfoTest.java | 105 +++++++++++++----- 1 file changed, 78 insertions(+), 27 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/DhcpInfoTest.java b/tests/cts/net/src/android/net/cts/DhcpInfoTest.java index 085fdd9132..b8d239272a 100644 --- a/tests/cts/net/src/android/net/cts/DhcpInfoTest.java +++ b/tests/cts/net/src/android/net/cts/DhcpInfoTest.java @@ -16,48 +16,99 @@ package android.net.cts; +import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTL; + +import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals; +import static com.android.testutils.ParcelUtilsKt.parcelingRoundTrip; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.annotation.Nullable; import android.net.DhcpInfo; -import android.test.AndroidTestCase; -public class DhcpInfoTest extends AndroidTestCase { +import androidx.test.runner.AndroidJUnit4; - public void testConstructor() { - new DhcpInfo(); +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.net.Inet4Address; +import java.net.InetAddress; + +@RunWith(AndroidJUnit4.class) +public class DhcpInfoTest { + private static final String STR_ADDR1 = "255.255.255.255"; + private static final String STR_ADDR2 = "127.0.0.1"; + private static final String STR_ADDR3 = "192.168.1.1"; + private static final String STR_ADDR4 = "192.168.1.0"; + private static final int LEASE_TIME = 9999; + + private int ipToInteger(String ipString) throws Exception { + return inet4AddressToIntHTL((Inet4Address) InetAddress.getByName(ipString)); } - public void testToString() { - String expectedDefault = "ipaddr 0.0.0.0 gateway 0.0.0.0 netmask 0.0.0.0 dns1 0.0.0.0 " - + "dns2 0.0.0.0 DHCP server 0.0.0.0 lease 0 seconds"; - String STR_ADDR1 = "255.255.255.255"; - String STR_ADDR2 = "127.0.0.1"; - String STR_ADDR3 = "192.168.1.1"; - String STR_ADDR4 = "192.168.1.0"; - int leaseTime = 9999; - String expected = "ipaddr " + STR_ADDR1 + " gateway " + STR_ADDR2 + " netmask " - + STR_ADDR3 + " dns1 " + STR_ADDR4 + " dns2 " + STR_ADDR4 + " DHCP server " - + STR_ADDR2 + " lease " + leaseTime + " seconds"; - - DhcpInfo dhcpInfo = new DhcpInfo(); - - // Test default string. - assertEquals(expectedDefault, dhcpInfo.toString()); - + private DhcpInfo createDhcpInfoObject() throws Exception { + final DhcpInfo dhcpInfo = new DhcpInfo(); dhcpInfo.ipAddress = ipToInteger(STR_ADDR1); dhcpInfo.gateway = ipToInteger(STR_ADDR2); dhcpInfo.netmask = ipToInteger(STR_ADDR3); dhcpInfo.dns1 = ipToInteger(STR_ADDR4); dhcpInfo.dns2 = ipToInteger(STR_ADDR4); dhcpInfo.serverAddress = ipToInteger(STR_ADDR2); - dhcpInfo.leaseDuration = leaseTime; + dhcpInfo.leaseDuration = LEASE_TIME; + return dhcpInfo; + } + @Test + public void testConstructor() { + new DhcpInfo(); + } + + @Test + public void testToString() throws Exception { + final String expectedDefault = "ipaddr 0.0.0.0 gateway 0.0.0.0 netmask 0.0.0.0 " + + "dns1 0.0.0.0 dns2 0.0.0.0 DHCP server 0.0.0.0 lease 0 seconds"; + + DhcpInfo dhcpInfo = new DhcpInfo(); + + // Test default string. + assertEquals(expectedDefault, dhcpInfo.toString()); + + dhcpInfo = createDhcpInfoObject(); + + final String expected = "ipaddr " + STR_ADDR1 + " gateway " + STR_ADDR2 + " netmask " + + STR_ADDR3 + " dns1 " + STR_ADDR4 + " dns2 " + STR_ADDR4 + " DHCP server " + + STR_ADDR2 + " lease " + LEASE_TIME + " seconds"; // Test with new values assertEquals(expected, dhcpInfo.toString()); } - private int ipToInteger(String ipString) { - String ipSegs[] = ipString.split("[.]"); - int tmp = Integer.parseInt(ipSegs[3]) << 24 | Integer.parseInt(ipSegs[2]) << 16 | - Integer.parseInt(ipSegs[1]) << 8 | Integer.parseInt(ipSegs[0]); - return tmp; + private boolean dhcpInfoEquals(@Nullable DhcpInfo left, @Nullable DhcpInfo right) { + if (left == null && right == null) return true; + + if (left == null || right == null) return false; + + return left.ipAddress == right.ipAddress + && left.gateway == right.gateway + && left.netmask == right.netmask + && left.dns1 == right.dns1 + && left.dns2 == right.dns2 + && left.serverAddress == right.serverAddress + && left.leaseDuration == right.leaseDuration; + } + + @Test + public void testParcelDhcpInfo() throws Exception { + // Cannot use assertParcelSane() here because this requires .equals() to work as + // defined, but DhcpInfo has a different legacy behavior that we cannot change. + final DhcpInfo dhcpInfo = createDhcpInfoObject(); + assertFieldCountEquals(7, DhcpInfo.class); + + final DhcpInfo dhcpInfoRoundTrip = parcelingRoundTrip(dhcpInfo); + assertTrue(dhcpInfoEquals(null, null)); + assertFalse(dhcpInfoEquals(null, dhcpInfoRoundTrip)); + assertFalse(dhcpInfoEquals(dhcpInfo, null)); + assertTrue(dhcpInfoEquals(dhcpInfo, dhcpInfoRoundTrip)); } } From 31a7f20c49a7297fbf506710db65b1d6476bb1d0 Mon Sep 17 00:00:00 2001 From: Treehugger Robot Date: Tue, 7 Apr 2020 06:59:29 +0000 Subject: [PATCH 0839/1109] CTS test for NetworkRequest#getSpecifier Bug: 135998869 Test: this Change-Id: I1ca9ecff8ed93164855686e4c76a070e6fa757c7 Merged-In: I339c62f0ce68cc3c19abbaef7f99d216362db4cb (cherry picked from commit 8fba41c86d92460a80cd58beb131528ce6e147d8, aosp/1188840) --- .../android/net/cts/NetworkRequestTest.java | 52 ++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java index c862c77bc7..8b97c8cb92 100644 --- a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java @@ -18,11 +18,42 @@ package android.net.cts; import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS; import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH; +import static android.net.NetworkCapabilities.TRANSPORT_WIFI; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import android.net.MacAddress; import android.net.NetworkRequest; -import android.test.AndroidTestCase; +import android.net.NetworkSpecifier; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiNetworkSpecifier; +import android.os.Build; +import android.os.PatternMatcher; +import android.util.Pair; -public class NetworkRequestTest extends AndroidTestCase { +import androidx.test.runner.AndroidJUnit4; + +import com.android.testutils.DevSdkIgnoreRule; +import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class NetworkRequestTest { + @Rule + public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule(); + + private static final String TEST_SSID = "TestSSID"; + private static final int TEST_UID = 2097; + private static final String TEST_PACKAGE_NAME = "test.package.name"; + private static final MacAddress ARBITRARY_ADDRESS = MacAddress.fromString("3:5:8:12:9:2"); + + @Test public void testCapabilities() { assertTrue(new NetworkRequest.Builder().addCapability(NET_CAPABILITY_MMS).build() .hasCapability(NET_CAPABILITY_MMS)); @@ -30,10 +61,27 @@ public class NetworkRequestTest extends AndroidTestCase { .hasCapability(NET_CAPABILITY_MMS)); } + @Test public void testTransports() { assertTrue(new NetworkRequest.Builder().addTransportType(TRANSPORT_BLUETOOTH).build() .hasTransport(TRANSPORT_BLUETOOTH)); assertFalse(new NetworkRequest.Builder().removeTransportType(TRANSPORT_BLUETOOTH).build() .hasTransport(TRANSPORT_BLUETOOTH)); } + + @Test + @IgnoreUpTo(Build.VERSION_CODES.Q) + public void testSpecifier() { + assertNull(new NetworkRequest.Builder().build().getNetworkSpecifier()); + final WifiNetworkSpecifier specifier = new WifiNetworkSpecifier.Builder() + .setSsidPattern(new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL)) + .setBssidPattern(ARBITRARY_ADDRESS, ARBITRARY_ADDRESS) + .build(); + final NetworkSpecifier obtainedSpecifier = new NetworkRequest.Builder() + .addTransportType(TRANSPORT_WIFI) + .setNetworkSpecifier(specifier) + .build() + .getNetworkSpecifier(); + assertEquals(obtainedSpecifier, specifier); + } } From d24f495dc4d86e305c4837205064baa9df2e3570 Mon Sep 17 00:00:00 2001 From: Dan Shi Date: Tue, 7 Apr 2020 14:04:44 -0700 Subject: [PATCH 0840/1109] Remove tests from vts suite After vts-core is renamed to vts, the CTS tests won't be needed in vts suite. Bug: 151896491 Test: local build Exempt-From-Owner-Approval: This CL removes all CTS tests in vts suite, as vts is renamed to vts10. This CL won't change test logic or behavior. Change-Id: Idc9e9cc1d1080ff689823671a736bbb78bd7a740 Merged-In: Idc9e9cc1d1080ff689823671a736bbb78bd7a740 --- tests/cts/hostside/Android.bp | 1 - tests/cts/hostside/app/Android.bp | 1 - tests/cts/hostside/app2/Android.bp | 1 - tests/cts/net/Android.bp | 1 - tests/cts/net/api23Test/Android.bp | 1 - tests/cts/net/appForApi23/Android.bp | 1 - tests/cts/net/ipsec/Android.bp | 1 - tests/cts/net/native/qtaguid/Android.bp | 1 - 8 files changed, 8 deletions(-) diff --git a/tests/cts/hostside/Android.bp b/tests/cts/hostside/Android.bp index a8cc95ba5f..741c961e5f 100644 --- a/tests/cts/hostside/Android.bp +++ b/tests/cts/hostside/Android.bp @@ -24,7 +24,6 @@ java_test_host { // Tag this module as a cts test artifact test_suites: [ "cts", - "vts", "vts10", "general-tests", ], diff --git a/tests/cts/hostside/app/Android.bp b/tests/cts/hostside/app/Android.bp index 49aacd91a9..2362389578 100644 --- a/tests/cts/hostside/app/Android.bp +++ b/tests/cts/hostside/app/Android.bp @@ -33,7 +33,6 @@ android_test_helper_app { // Tag this module as a cts test artifact test_suites: [ "cts", - "vts", "vts10", "general-tests", ], diff --git a/tests/cts/hostside/app2/Android.bp b/tests/cts/hostside/app2/Android.bp index 0bb0d2f631..a6e9b118ff 100644 --- a/tests/cts/hostside/app2/Android.bp +++ b/tests/cts/hostside/app2/Android.bp @@ -23,7 +23,6 @@ android_test_helper_app { // Tag this module as a cts test artifact test_suites: [ "cts", - "vts", "vts10", "general-tests", ], diff --git a/tests/cts/net/Android.bp b/tests/cts/net/Android.bp index d77f416557..76bb27e448 100644 --- a/tests/cts/net/Android.bp +++ b/tests/cts/net/Android.bp @@ -64,7 +64,6 @@ android_test { defaults: ["CtsNetTestCasesDefaults"], test_suites: [ "cts", - "vts", "vts10", "general-tests", ], diff --git a/tests/cts/net/api23Test/Android.bp b/tests/cts/net/api23Test/Android.bp index 614a5a2a76..ffeef48a88 100644 --- a/tests/cts/net/api23Test/Android.bp +++ b/tests/cts/net/api23Test/Android.bp @@ -45,7 +45,6 @@ android_test { // Tag this module as a cts test artifact test_suites: [ "cts", - "vts", "vts10", "general-tests", ], diff --git a/tests/cts/net/appForApi23/Android.bp b/tests/cts/net/appForApi23/Android.bp index 17cfe3821b..399c199508 100644 --- a/tests/cts/net/appForApi23/Android.bp +++ b/tests/cts/net/appForApi23/Android.bp @@ -26,7 +26,6 @@ android_test { // Tag this module as a cts test artifact test_suites: [ "cts", - "vts", "vts10", "general-tests", ], diff --git a/tests/cts/net/ipsec/Android.bp b/tests/cts/net/ipsec/Android.bp index 86969c31ae..8c073c9602 100644 --- a/tests/cts/net/ipsec/Android.bp +++ b/tests/cts/net/ipsec/Android.bp @@ -40,7 +40,6 @@ android_test { test_suites: [ "cts", "mts", - "vts", "general-tests", ], } diff --git a/tests/cts/net/native/qtaguid/Android.bp b/tests/cts/net/native/qtaguid/Android.bp index 054937b4fa..23a0cf764d 100644 --- a/tests/cts/net/native/qtaguid/Android.bp +++ b/tests/cts/net/native/qtaguid/Android.bp @@ -42,7 +42,6 @@ cc_test { // Tag this module as a cts test artifact test_suites: [ "cts", - "vts", "vts10", ], From f483cc96799dce6410e004733fcbd0117c50fb6f Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Mon, 23 Dec 2019 16:14:20 +0800 Subject: [PATCH 0841/1109] Add cts test for traffic stats APIs This change adds test for new public APIs. Bug: 135998869 Test: atest CtsNetTestCasesLatestSdk:TrafficStatsTest Change-Id: I6b4a6773e22a204b6267d28638b9f57a0d0eb65a --- .../src/android/net/cts/TrafficStatsTest.java | 58 ++++++++++++------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java index 12ab3702d4..577e24ac29 100755 --- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java +++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java @@ -61,6 +61,11 @@ public class TrafficStatsTest extends AndroidTestCase { assertTrue(TrafficStats.getTotalRxBytes() >= 0); } + public void testValidPacketStats() { + assertTrue(TrafficStats.getTxPackets("lo") >= 0); + assertTrue(TrafficStats.getRxPackets("lo") >= 0); + } + public void testThreadStatsTag() throws Exception { TrafficStats.setThreadStatsTag(0xf00d); assertTrue("Tag didn't stick", TrafficStats.getThreadStatsTag() == 0xf00d); @@ -104,6 +109,8 @@ public class TrafficStatsTest extends AndroidTestCase { final long uidRxBytesBefore = TrafficStats.getUidRxBytes(Process.myUid()); final long uidTxPacketsBefore = TrafficStats.getUidTxPackets(Process.myUid()); final long uidRxPacketsBefore = TrafficStats.getUidRxPackets(Process.myUid()); + final long ifaceTxPacketsBefore = TrafficStats.getTxPackets("lo"); + final long ifaceRxPacketsBefore = TrafficStats.getRxPackets("lo"); // Transfer 1MB of data across an explicitly localhost socket. final int byteCount = 1024; @@ -182,6 +189,10 @@ public class TrafficStatsTest extends AndroidTestCase { final long uidTxDeltaPackets = uidTxPacketsAfter - uidTxPacketsBefore; final long uidRxDeltaBytes = uidRxBytesAfter - uidRxBytesBefore; final long uidRxDeltaPackets = uidRxPacketsAfter - uidRxPacketsBefore; + final long ifaceTxPacketsAfter = TrafficStats.getTxPackets("lo"); + final long ifaceRxPacketsAfter = TrafficStats.getRxPackets("lo"); + final long ifaceTxDeltaPackets = ifaceTxPacketsAfter - ifaceTxPacketsBefore; + final long ifaceRxDeltaPackets = ifaceRxPacketsAfter - ifaceRxPacketsBefore; // Localhost traffic *does* count against per-UID stats. /* @@ -209,34 +220,37 @@ public class TrafficStatsTest extends AndroidTestCase { + deltaRxOtherPackets); } - // Check the per uid stats read from data profiling have the stats expected. The data - // profiling snapshot is generated from readNetworkStatsDetail() method in - // networkStatsService and in this way we can verify the detail networkStats of a given uid - // is correct. - NetworkStats.Entry entry = testStats.getTotal(null, Process.myUid()); + // Check that the per-uid stats obtained from data profiling contain the expected values. + // The data profiling snapshot is generated from the readNetworkStatsDetail() method in + // networkStatsService, so it's possible to verify that the detailed stats for a given + // uid are correct. + final NetworkStats.Entry entry = testStats.getTotal(null, Process.myUid()); + final long pktBytes = tcpPacketToIpBytes(packetCount, byteCount); + final long pktWithNoDataBytes = tcpPacketToIpBytes(packetCount, 0); + final long minExpExtraPktBytes = tcpPacketToIpBytes(minExpectedExtraPackets, 0); + final long maxExpExtraPktBytes = tcpPacketToIpBytes(maxExpectedExtraPackets, 0); + final long deltaTxOtherPktBytes = tcpPacketToIpBytes(deltaTxOtherPackets, 0); + final long deltaRxOtherPktBytes = tcpPacketToIpBytes(deltaRxOtherPackets, 0); assertInRange("txPackets detail", entry.txPackets, packetCount + minExpectedExtraPackets, uidTxDeltaPackets); assertInRange("rxPackets detail", entry.rxPackets, packetCount + minExpectedExtraPackets, uidRxDeltaPackets); - assertInRange("txBytes detail", entry.txBytes, tcpPacketToIpBytes(packetCount, byteCount) - + tcpPacketToIpBytes(minExpectedExtraPackets, 0), uidTxDeltaBytes); - assertInRange("rxBytes detail", entry.rxBytes, tcpPacketToIpBytes(packetCount, byteCount) - + tcpPacketToIpBytes(minExpectedExtraPackets, 0), uidRxDeltaBytes); - + assertInRange("txBytes detail", entry.txBytes, pktBytes + minExpExtraPktBytes, + uidTxDeltaBytes); + assertInRange("rxBytes detail", entry.rxBytes, pktBytes + minExpExtraPktBytes, + uidRxDeltaBytes); assertInRange("uidtxp", uidTxDeltaPackets, packetCount + minExpectedExtraPackets, packetCount + packetCount + maxExpectedExtraPackets + deltaTxOtherPackets); assertInRange("uidrxp", uidRxDeltaPackets, packetCount + minExpectedExtraPackets, packetCount + packetCount + maxExpectedExtraPackets + deltaRxOtherPackets); - assertInRange("uidtxb", uidTxDeltaBytes, tcpPacketToIpBytes(packetCount, byteCount) - + tcpPacketToIpBytes(minExpectedExtraPackets, 0), - tcpPacketToIpBytes(packetCount, byteCount) - + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets - + deltaTxOtherPackets, 0)); - assertInRange("uidrxb", uidRxDeltaBytes, tcpPacketToIpBytes(packetCount, byteCount) - + tcpPacketToIpBytes(minExpectedExtraPackets, 0), - tcpPacketToIpBytes(packetCount, byteCount) - + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets - + deltaRxOtherPackets, 0)); + assertInRange("uidtxb", uidTxDeltaBytes, pktBytes + minExpExtraPktBytes, + pktBytes + pktWithNoDataBytes + maxExpExtraPktBytes + deltaTxOtherPktBytes); + assertInRange("uidrxb", uidRxDeltaBytes, pktBytes + minExpExtraPktBytes, + pktBytes + pktWithNoDataBytes + maxExpExtraPktBytes + deltaRxOtherPktBytes); + assertInRange("iftxp", ifaceTxDeltaPackets, packetCount + minExpectedExtraPackets, + packetCount + packetCount + maxExpectedExtraPackets + deltaTxOtherPackets); + assertInRange("ifrxp", ifaceRxDeltaPackets, packetCount + minExpectedExtraPackets, + packetCount + packetCount + maxExpectedExtraPackets + deltaRxOtherPackets); // Localhost traffic *does* count against total stats. // Check the total stats increased after test data transfer over localhost has been made. @@ -248,6 +262,10 @@ public class TrafficStatsTest extends AndroidTestCase { totalTxBytesAfter >= totalTxBytesBefore + uidTxDeltaBytes); assertTrue("trxb: " + totalRxBytesBefore + " -> " + totalRxBytesAfter, totalRxBytesAfter >= totalRxBytesBefore + uidRxDeltaBytes); + assertTrue("iftxp: " + ifaceTxPacketsBefore + " -> " + ifaceTxPacketsAfter, + totalTxPacketsAfter >= totalTxPacketsBefore + ifaceTxDeltaPackets); + assertTrue("ifrxp: " + ifaceRxPacketsBefore + " -> " + ifaceRxPacketsAfter, + totalRxPacketsAfter >= totalRxPacketsBefore + ifaceRxDeltaPackets); // If the adb TCP port is opened, this test may be run by adb over network. // Huge amount of data traffic might go through the network and accounted into total packets From 0e7d08e2b2f8a7e18e63d470d7c709879d0690b0 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Tue, 7 Apr 2020 05:57:56 +0000 Subject: [PATCH 0842/1109] Add a first NetworkAgent CTS test This is a basic test that only tests register(), markConnected(), unregister and onNetworkUnwanted. It provides the backbone for the tests, a harness to test callbacks on NetworkAgent, and demonstrates how the instrumentation in ConnectivityService can be used to test this API. Test: this Bug: 139268426 Change-Id: I859208f381ccc22a85d6bccb44c0d5d84c3380c6 Merged-In: I022c9e237fdaec27338047c171c04e5a96cf89e3 (cherry picked from commit 723b519dc2de077c37db510850a590188591a80b, aosp/1253423) --- tests/cts/net/AndroidManifest.xml | 5 + .../net/cts/IpSecManagerTunnelTest.java | 3 +- .../src/android/net/cts/NetworkAgentTest.kt | 142 ++++++++++++++++++ 3 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 tests/cts/net/src/android/net/cts/NetworkAgentTest.kt diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml index c2b3bf77ad..baf914f1ac 100644 --- a/tests/cts/net/AndroidManifest.xml +++ b/tests/cts/net/AndroidManifest.xml @@ -35,6 +35,11 @@ + + diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java index 999d2f187b..1d83dda33c 100644 --- a/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java +++ b/tests/cts/net/src/android/net/cts/IpSecManagerTunnelTest.java @@ -192,9 +192,8 @@ public class IpSecManagerTunnelTest extends IpSecBaseTest { // Build a network request NetworkRequest nr = new NetworkRequest.Builder() + .clearCapabilities() .addTransportType(TRANSPORT_TEST) - .removeCapability(NET_CAPABILITY_TRUSTED) - .removeCapability(NET_CAPABILITY_NOT_VPN) .setNetworkSpecifier(ifname) .build(); diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt new file mode 100644 index 0000000000..85c94e7db2 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -0,0 +1,142 @@ +/* + * 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.cts + +import android.app.Instrumentation +import android.content.Context +import android.net.ConnectivityManager +import android.net.LinkProperties +import android.net.NetworkAgent +import android.net.NetworkAgentConfig +import android.net.NetworkCapabilities +import android.net.NetworkProvider +import android.net.NetworkRequest +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnNetworkUnwanted +import android.os.Build +import android.os.HandlerThread +import android.os.Looper +import androidx.test.InstrumentationRegistry +import androidx.test.runner.AndroidJUnit4 +import com.android.testutils.ArrayTrackRecord +import com.android.testutils.DevSdkIgnoreRule +import com.android.testutils.RecorderCallback.CallbackEntry.Lost +import com.android.testutils.TestableNetworkCallback +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import kotlin.test.assertFailsWith +import kotlin.test.assertTrue + +// This test doesn't really have a constraint on how fast the methods should return. If it's +// going to fail, it will simply wait forever, so setting a high timeout lowers the flake ratio +// without affecting the run time of successful runs. Thus, set a very high timeout. +private const val DEFAULT_TIMEOUT_MS = 5000L +// Any legal score (0~99) for the test network would do, as it is going to be kept up by the +// requests filed by the test and should never match normal internet requests. 70 is the default +// score of Ethernet networks, it's as good a value as any other. +private const val TEST_NETWORK_SCORE = 70 +private val instrumentation: Instrumentation + get() = InstrumentationRegistry.getInstrumentation() +private val context: Context + get() = InstrumentationRegistry.getContext() + +@RunWith(AndroidJUnit4::class) +class NetworkAgentTest { + @Rule @JvmField + val ignoreRule = DevSdkIgnoreRule(ignoreClassUpTo = Build.VERSION_CODES.Q) + + private val mCM = context.getSystemService(ConnectivityManager::class.java) + private val mHandlerThread = HandlerThread("${javaClass.simpleName} handler thread") + + private class Provider(context: Context, looper: Looper) : + NetworkProvider(context, looper, "NetworkAgentTest NetworkProvider") + + @Before + fun setUp() { + instrumentation.getUiAutomation().adoptShellPermissionIdentity() + mHandlerThread.start() + } + + @After + fun tearDown() { + mHandlerThread.quitSafely() + instrumentation.getUiAutomation().dropShellPermissionIdentity() + } + + internal class TestableNetworkAgent( + looper: Looper, + nc: NetworkCapabilities, + lp: LinkProperties, + conf: NetworkAgentConfig + ) : NetworkAgent(context, looper, TestableNetworkAgent::class.java.simpleName /* tag */, + nc, lp, TEST_NETWORK_SCORE, conf, Provider(context, looper)) { + private val history = ArrayTrackRecord().newReadHead() + + sealed class CallbackEntry { + object OnNetworkUnwanted : CallbackEntry() + } + + override fun onNetworkUnwanted() { + super.onNetworkUnwanted() + history.add(OnNetworkUnwanted) + } + + inline fun expectCallback() { + val foundCallback = history.poll(DEFAULT_TIMEOUT_MS) + assertTrue(foundCallback is T, "Expected ${T::class} but found $foundCallback") + } + } + + private fun createNetworkAgent(): TestableNetworkAgent { + val nc = NetworkCapabilities().apply { + addTransportType(NetworkCapabilities.TRANSPORT_TEST) + removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED) + removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED) + addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING) + addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) + } + val lp = LinkProperties() + val config = NetworkAgentConfig.Builder().build() + return TestableNetworkAgent(mHandlerThread.looper, nc, lp, config) + } + + private fun createConnectedNetworkAgent(): Pair { + val request: NetworkRequest = NetworkRequest.Builder() + .clearCapabilities() + .addTransportType(NetworkCapabilities.TRANSPORT_TEST) + .build() + val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS) + mCM.requestNetwork(request, callback) + val agent = createNetworkAgent().also { it.register() } + agent.markConnected() + return agent to callback + } + + @Test + fun testConnectAndUnregister() { + val (agent, callback) = createConnectedNetworkAgent() + callback.expectAvailableThenValidatedCallbacks(agent.network) + agent.unregister() + callback.expectCallback(agent.network) + agent.expectCallback() + assertFailsWith("Must not be able to register an agent twice") { + agent.register() + } + } +} From abf9bc0843c7168a6d7ab91095558b7bd4a4d9e9 Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Wed, 8 Apr 2020 07:58:02 +0000 Subject: [PATCH 0843/1109] Add ProxyInfoTest to test public APIs Add cts to test current public APIs and new public APIs. Bug: 151110319 Bug: 152617305 Test: atest CtsNetTestCasesLatestSdk:ProxyInfoTest Change-Id: I3e7d2cb7b4c5e47fc85d418aa8ef504367b3d8db Merged-In: I451989f7312fb98ec2fa0b7b9ddc856ecf2087be (cherry picked from commit 0a4d5ecc83d56c2c3f400927a2b8af6e26eb8db8) --- .../src/android/net/cts/ProxyInfoTest.java | 135 ++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 tests/cts/net/src/android/net/cts/ProxyInfoTest.java diff --git a/tests/cts/net/src/android/net/cts/ProxyInfoTest.java b/tests/cts/net/src/android/net/cts/ProxyInfoTest.java new file mode 100644 index 0000000000..1c5624ce38 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/ProxyInfoTest.java @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2019 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 static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import android.net.ProxyInfo; +import android.net.Uri; +import android.os.Build; + +import androidx.test.runner.AndroidJUnit4; + +import com.android.testutils.DevSdkIgnoreRule; +import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +@RunWith(AndroidJUnit4.class) +public final class ProxyInfoTest { + private static final String TEST_HOST = "test.example.com"; + private static final int TEST_PORT = 5566; + private static final Uri TEST_URI = Uri.parse("https://test.example.com"); + // This matches android.net.ProxyInfo#LOCAL_EXCL_LIST + private static final String LOCAL_EXCL_LIST = ""; + // This matches android.net.ProxyInfo#LOCAL_HOST + private static final String LOCAL_HOST = "localhost"; + // This matches android.net.ProxyInfo#LOCAL_PORT + private static final int LOCAL_PORT = -1; + + @Rule + public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule(); + + @Test + public void testConstructor() { + final ProxyInfo proxy = new ProxyInfo((ProxyInfo) null); + checkEmpty(proxy); + + assertEquals(proxy, new ProxyInfo(proxy)); + } + + @Test + public void testBuildDirectProxy() { + final ProxyInfo proxy1 = ProxyInfo.buildDirectProxy(TEST_HOST, TEST_PORT); + + assertEquals(TEST_HOST, proxy1.getHost()); + assertEquals(TEST_PORT, proxy1.getPort()); + assertArrayEquals(new String[0], proxy1.getExclusionList()); + assertEquals(Uri.EMPTY, proxy1.getPacFileUrl()); + + final List exclList = new ArrayList<>(); + exclList.add("localhost"); + exclList.add("*.exclusion.com"); + final ProxyInfo proxy2 = ProxyInfo.buildDirectProxy(TEST_HOST, TEST_PORT, exclList); + + assertEquals(TEST_HOST, proxy2.getHost()); + assertEquals(TEST_PORT, proxy2.getPort()); + assertArrayEquals(exclList.toArray(new String[0]), proxy2.getExclusionList()); + assertEquals(Uri.EMPTY, proxy2.getPacFileUrl()); + } + + @Test @IgnoreUpTo(Build.VERSION_CODES.Q) + public void testBuildPacProxy() { + final ProxyInfo proxy1 = ProxyInfo.buildPacProxy(TEST_URI); + + assertEquals(LOCAL_HOST, proxy1.getHost()); + assertEquals(LOCAL_PORT, proxy1.getPort()); + assertArrayEquals(LOCAL_EXCL_LIST.toLowerCase(Locale.ROOT).split(","), + proxy1.getExclusionList()); + assertEquals(TEST_URI, proxy1.getPacFileUrl()); + + final ProxyInfo proxy2 = ProxyInfo.buildPacProxy(TEST_URI, TEST_PORT); + + assertEquals(LOCAL_HOST, proxy2.getHost()); + assertEquals(TEST_PORT, proxy2.getPort()); + assertArrayEquals(LOCAL_EXCL_LIST.toLowerCase(Locale.ROOT).split(","), + proxy2.getExclusionList()); + assertEquals(TEST_URI, proxy2.getPacFileUrl()); + } + + @Test + public void testIsValid() { + final ProxyInfo proxy1 = ProxyInfo.buildDirectProxy(TEST_HOST, TEST_PORT); + assertTrue(proxy1.isValid()); + + // Given empty host + final ProxyInfo proxy2 = ProxyInfo.buildDirectProxy("", TEST_PORT); + assertFalse(proxy2.isValid()); + // Given invalid host + final ProxyInfo proxy3 = ProxyInfo.buildDirectProxy(".invalid.com", TEST_PORT); + assertFalse(proxy3.isValid()); + // Given invalid port. + final ProxyInfo proxy4 = ProxyInfo.buildDirectProxy(TEST_HOST, 0); + assertFalse(proxy4.isValid()); + // Given another invalid port + final ProxyInfo proxy5 = ProxyInfo.buildDirectProxy(TEST_HOST, 65536); + assertFalse(proxy5.isValid()); + // Given invalid exclusion list + final List exclList = new ArrayList<>(); + exclList.add(".invalid.com"); + exclList.add("%.test.net"); + final ProxyInfo proxy6 = ProxyInfo.buildDirectProxy(TEST_HOST, TEST_PORT, exclList); + assertFalse(proxy6.isValid()); + } + + private void checkEmpty(ProxyInfo proxy) { + assertNull(proxy.getHost()); + assertEquals(0, proxy.getPort()); + assertNull(proxy.getExclusionList()); + assertEquals(Uri.EMPTY, proxy.getPacFileUrl()); + } +} From 1522b023d0cb083371e635312b57a8d20da27b79 Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Wed, 8 Apr 2020 07:58:15 +0000 Subject: [PATCH 0844/1109] CTS test for DhcpInfo parcel/unparcel Bug: 139268426 Bug: 135998869 Test: atest CtsNetTestCasesLatestSdk:android.net.cts.DhcpInfoTest Change-Id: I20d9faba899c7eef026e155e329c5c3a89253209 Merged-In: I076241072688fca37b8451873183f9597bc5fe79 (cherry picked from commit 130479fb2aa2457eb590202382ed31f72cc5386e) --- .../net/src/android/net/cts/DhcpInfoTest.java | 105 +++++++++++++----- 1 file changed, 78 insertions(+), 27 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/DhcpInfoTest.java b/tests/cts/net/src/android/net/cts/DhcpInfoTest.java index 085fdd9132..b8d239272a 100644 --- a/tests/cts/net/src/android/net/cts/DhcpInfoTest.java +++ b/tests/cts/net/src/android/net/cts/DhcpInfoTest.java @@ -16,48 +16,99 @@ package android.net.cts; +import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTL; + +import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals; +import static com.android.testutils.ParcelUtilsKt.parcelingRoundTrip; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.annotation.Nullable; import android.net.DhcpInfo; -import android.test.AndroidTestCase; -public class DhcpInfoTest extends AndroidTestCase { +import androidx.test.runner.AndroidJUnit4; - public void testConstructor() { - new DhcpInfo(); +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.net.Inet4Address; +import java.net.InetAddress; + +@RunWith(AndroidJUnit4.class) +public class DhcpInfoTest { + private static final String STR_ADDR1 = "255.255.255.255"; + private static final String STR_ADDR2 = "127.0.0.1"; + private static final String STR_ADDR3 = "192.168.1.1"; + private static final String STR_ADDR4 = "192.168.1.0"; + private static final int LEASE_TIME = 9999; + + private int ipToInteger(String ipString) throws Exception { + return inet4AddressToIntHTL((Inet4Address) InetAddress.getByName(ipString)); } - public void testToString() { - String expectedDefault = "ipaddr 0.0.0.0 gateway 0.0.0.0 netmask 0.0.0.0 dns1 0.0.0.0 " - + "dns2 0.0.0.0 DHCP server 0.0.0.0 lease 0 seconds"; - String STR_ADDR1 = "255.255.255.255"; - String STR_ADDR2 = "127.0.0.1"; - String STR_ADDR3 = "192.168.1.1"; - String STR_ADDR4 = "192.168.1.0"; - int leaseTime = 9999; - String expected = "ipaddr " + STR_ADDR1 + " gateway " + STR_ADDR2 + " netmask " - + STR_ADDR3 + " dns1 " + STR_ADDR4 + " dns2 " + STR_ADDR4 + " DHCP server " - + STR_ADDR2 + " lease " + leaseTime + " seconds"; - - DhcpInfo dhcpInfo = new DhcpInfo(); - - // Test default string. - assertEquals(expectedDefault, dhcpInfo.toString()); - + private DhcpInfo createDhcpInfoObject() throws Exception { + final DhcpInfo dhcpInfo = new DhcpInfo(); dhcpInfo.ipAddress = ipToInteger(STR_ADDR1); dhcpInfo.gateway = ipToInteger(STR_ADDR2); dhcpInfo.netmask = ipToInteger(STR_ADDR3); dhcpInfo.dns1 = ipToInteger(STR_ADDR4); dhcpInfo.dns2 = ipToInteger(STR_ADDR4); dhcpInfo.serverAddress = ipToInteger(STR_ADDR2); - dhcpInfo.leaseDuration = leaseTime; + dhcpInfo.leaseDuration = LEASE_TIME; + return dhcpInfo; + } + @Test + public void testConstructor() { + new DhcpInfo(); + } + + @Test + public void testToString() throws Exception { + final String expectedDefault = "ipaddr 0.0.0.0 gateway 0.0.0.0 netmask 0.0.0.0 " + + "dns1 0.0.0.0 dns2 0.0.0.0 DHCP server 0.0.0.0 lease 0 seconds"; + + DhcpInfo dhcpInfo = new DhcpInfo(); + + // Test default string. + assertEquals(expectedDefault, dhcpInfo.toString()); + + dhcpInfo = createDhcpInfoObject(); + + final String expected = "ipaddr " + STR_ADDR1 + " gateway " + STR_ADDR2 + " netmask " + + STR_ADDR3 + " dns1 " + STR_ADDR4 + " dns2 " + STR_ADDR4 + " DHCP server " + + STR_ADDR2 + " lease " + LEASE_TIME + " seconds"; // Test with new values assertEquals(expected, dhcpInfo.toString()); } - private int ipToInteger(String ipString) { - String ipSegs[] = ipString.split("[.]"); - int tmp = Integer.parseInt(ipSegs[3]) << 24 | Integer.parseInt(ipSegs[2]) << 16 | - Integer.parseInt(ipSegs[1]) << 8 | Integer.parseInt(ipSegs[0]); - return tmp; + private boolean dhcpInfoEquals(@Nullable DhcpInfo left, @Nullable DhcpInfo right) { + if (left == null && right == null) return true; + + if (left == null || right == null) return false; + + return left.ipAddress == right.ipAddress + && left.gateway == right.gateway + && left.netmask == right.netmask + && left.dns1 == right.dns1 + && left.dns2 == right.dns2 + && left.serverAddress == right.serverAddress + && left.leaseDuration == right.leaseDuration; + } + + @Test + public void testParcelDhcpInfo() throws Exception { + // Cannot use assertParcelSane() here because this requires .equals() to work as + // defined, but DhcpInfo has a different legacy behavior that we cannot change. + final DhcpInfo dhcpInfo = createDhcpInfoObject(); + assertFieldCountEquals(7, DhcpInfo.class); + + final DhcpInfo dhcpInfoRoundTrip = parcelingRoundTrip(dhcpInfo); + assertTrue(dhcpInfoEquals(null, null)); + assertFalse(dhcpInfoEquals(null, dhcpInfoRoundTrip)); + assertFalse(dhcpInfoEquals(dhcpInfo, null)); + assertTrue(dhcpInfoEquals(dhcpInfo, dhcpInfoRoundTrip)); } } From 2b1fbd6404b9261d119da5ca34eabba413284be7 Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Tue, 24 Mar 2020 05:32:24 +0000 Subject: [PATCH 0845/1109] Refactor assertion into assertInRange() method It's hard to read in current design, refactor the assertion into assertInRange() for readability. Bug: 153614624 Test: atest android.net.cts.TrafficStatsTest Change-Id: I6d939dd62cad3d6ba23a3c5ca7b1e6a8b4131a90 Merged-In: I6d939dd62cad3d6ba23a3c5ca7b1e6a8b4131a90 (cherry picked from commit af3469bdc7031d80f3d3838518fd7518b3e8eb9c) --- .../src/android/net/cts/TrafficStatsTest.java | 137 +++++++++--------- 1 file changed, 67 insertions(+), 70 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java index 5bd1e208a8..12ab3702d4 100755 --- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java +++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java @@ -24,6 +24,7 @@ import android.os.SystemProperties; import android.platform.test.annotations.AppModeFull; import android.test.AndroidTestCase; import android.util.Log; +import android.util.Range; import java.io.IOException; import java.io.InputStream; @@ -36,6 +37,13 @@ import java.util.concurrent.TimeUnit; public class TrafficStatsTest extends AndroidTestCase { private static final String LOG_TAG = "TrafficStatsTest"; + /** Verify the given value is in range [lower, upper] */ + private void assertInRange(String tag, long value, long lower, long upper) { + final Range range = new Range(lower, upper); + assertTrue(tag + ": " + value + " is not within range [" + lower + ", " + upper + "]", + range.contains(value)); + } + public void testValidMobileStats() { // We can't assume a mobile network is even present in this test, so // we simply assert that a valid value is returned. @@ -107,12 +115,12 @@ public class TrafficStatsTest extends AndroidTestCase { @Override public void run() { try { - Socket socket = new Socket("localhost", server.getLocalPort()); + final Socket socket = new Socket("localhost", server.getLocalPort()); // Make sure that each write()+flush() turns into a packet: // disable Nagle. socket.setTcpNoDelay(true); - OutputStream out = socket.getOutputStream(); - byte[] buf = new byte[byteCount]; + final OutputStream out = socket.getOutputStream(); + final byte[] buf = new byte[byteCount]; TrafficStats.setThreadStatsTag(0x42); TrafficStats.tagSocket(socket); for (int i = 0; i < packetCount; i++) { @@ -135,12 +143,12 @@ public class TrafficStatsTest extends AndroidTestCase { int read = 0; try { - Socket socket = server.accept(); + final Socket socket = server.accept(); socket.setTcpNoDelay(true); TrafficStats.setThreadStatsTag(0x43); TrafficStats.tagSocket(socket); - InputStream in = socket.getInputStream(); - byte[] buf = new byte[byteCount]; + final InputStream in = socket.getInputStream(); + final byte[] buf = new byte[byteCount]; while (read < byteCount * packetCount) { int n = in.read(buf); assertTrue("Unexpected EOF", n > 0); @@ -156,24 +164,24 @@ public class TrafficStatsTest extends AndroidTestCase { Thread.sleep(1000); } catch (InterruptedException e) { } - NetworkStats testStats = TrafficStats.stopDataProfiling(null); + final NetworkStats testStats = TrafficStats.stopDataProfiling(null); - long mobileTxPacketsAfter = TrafficStats.getMobileTxPackets(); - long mobileRxPacketsAfter = TrafficStats.getMobileRxPackets(); - long mobileTxBytesAfter = TrafficStats.getMobileTxBytes(); - long mobileRxBytesAfter = TrafficStats.getMobileRxBytes(); - long totalTxPacketsAfter = TrafficStats.getTotalTxPackets(); - long totalRxPacketsAfter = TrafficStats.getTotalRxPackets(); - long totalTxBytesAfter = TrafficStats.getTotalTxBytes(); - long totalRxBytesAfter = TrafficStats.getTotalRxBytes(); - long uidTxBytesAfter = TrafficStats.getUidTxBytes(Process.myUid()); - long uidRxBytesAfter = TrafficStats.getUidRxBytes(Process.myUid()); - long uidTxPacketsAfter = TrafficStats.getUidTxPackets(Process.myUid()); - long uidRxPacketsAfter = TrafficStats.getUidRxPackets(Process.myUid()); - long uidTxDeltaBytes = uidTxBytesAfter - uidTxBytesBefore; - long uidTxDeltaPackets = uidTxPacketsAfter - uidTxPacketsBefore; - long uidRxDeltaBytes = uidRxBytesAfter - uidRxBytesBefore; - long uidRxDeltaPackets = uidRxPacketsAfter - uidRxPacketsBefore; + final long mobileTxPacketsAfter = TrafficStats.getMobileTxPackets(); + final long mobileRxPacketsAfter = TrafficStats.getMobileRxPackets(); + final long mobileTxBytesAfter = TrafficStats.getMobileTxBytes(); + final long mobileRxBytesAfter = TrafficStats.getMobileRxBytes(); + final long totalTxPacketsAfter = TrafficStats.getTotalTxPackets(); + final long totalRxPacketsAfter = TrafficStats.getTotalRxPackets(); + final long totalTxBytesAfter = TrafficStats.getTotalTxBytes(); + final long totalRxBytesAfter = TrafficStats.getTotalRxBytes(); + final long uidTxBytesAfter = TrafficStats.getUidTxBytes(Process.myUid()); + final long uidRxBytesAfter = TrafficStats.getUidRxBytes(Process.myUid()); + final long uidTxPacketsAfter = TrafficStats.getUidTxPackets(Process.myUid()); + final long uidRxPacketsAfter = TrafficStats.getUidRxPackets(Process.myUid()); + final long uidTxDeltaBytes = uidTxBytesAfter - uidTxBytesBefore; + final long uidTxDeltaPackets = uidTxPacketsAfter - uidTxPacketsBefore; + final long uidRxDeltaBytes = uidRxBytesAfter - uidRxBytesBefore; + final long uidRxDeltaPackets = uidRxPacketsAfter - uidRxPacketsBefore; // Localhost traffic *does* count against per-UID stats. /* @@ -192,10 +200,13 @@ public class TrafficStatsTest extends AndroidTestCase { // Some other tests don't cleanup connections correctly. // They have the same UID, so we discount their lingering traffic // which happens only on non-localhost, such as TCP FIN retranmission packets - long deltaTxOtherPackets = (totalTxPacketsAfter - totalTxPacketsBefore) - uidTxDeltaPackets; - long deltaRxOtherPackets = (totalRxPacketsAfter - totalRxPacketsBefore) - uidRxDeltaPackets; + final long deltaTxOtherPackets = (totalTxPacketsAfter - totalTxPacketsBefore) + - uidTxDeltaPackets; + final long deltaRxOtherPackets = (totalRxPacketsAfter - totalRxPacketsBefore) + - uidRxDeltaPackets; if (deltaTxOtherPackets > 0 || deltaRxOtherPackets > 0) { - Log.i(LOG_TAG, "lingering traffic data: " + deltaTxOtherPackets + "/" + deltaRxOtherPackets); + Log.i(LOG_TAG, "lingering traffic data: " + deltaTxOtherPackets + "/" + + deltaRxOtherPackets); } // Check the per uid stats read from data profiling have the stats expected. The data @@ -203,39 +214,29 @@ public class TrafficStatsTest extends AndroidTestCase { // networkStatsService and in this way we can verify the detail networkStats of a given uid // is correct. NetworkStats.Entry entry = testStats.getTotal(null, Process.myUid()); - assertTrue("txPackets detail: " + entry.txPackets + " uidTxPackets: " + uidTxDeltaPackets, - entry.txPackets >= packetCount + minExpectedExtraPackets - && entry.txPackets <= uidTxDeltaPackets); - assertTrue("rxPackets detail: " + entry.rxPackets + " uidRxPackets: " + uidRxDeltaPackets, - entry.rxPackets >= packetCount + minExpectedExtraPackets - && entry.rxPackets <= uidRxDeltaPackets); - assertTrue("txBytes detail: " + entry.txBytes + " uidTxDeltaBytes: " + uidTxDeltaBytes, - entry.txBytes >= tcpPacketToIpBytes(packetCount, byteCount) - + tcpPacketToIpBytes(minExpectedExtraPackets, 0) && entry.txBytes <= uidTxDeltaBytes); - assertTrue("rxBytes detail: " + entry.rxBytes + " uidRxDeltaBytes: " + uidRxDeltaBytes, - entry.rxBytes >= tcpPacketToIpBytes(packetCount, byteCount) - + tcpPacketToIpBytes(minExpectedExtraPackets, 0) && entry.rxBytes <= uidRxDeltaBytes); + assertInRange("txPackets detail", entry.txPackets, packetCount + minExpectedExtraPackets, + uidTxDeltaPackets); + assertInRange("rxPackets detail", entry.rxPackets, packetCount + minExpectedExtraPackets, + uidRxDeltaPackets); + assertInRange("txBytes detail", entry.txBytes, tcpPacketToIpBytes(packetCount, byteCount) + + tcpPacketToIpBytes(minExpectedExtraPackets, 0), uidTxDeltaBytes); + assertInRange("rxBytes detail", entry.rxBytes, tcpPacketToIpBytes(packetCount, byteCount) + + tcpPacketToIpBytes(minExpectedExtraPackets, 0), uidRxDeltaBytes); - assertTrue("uidtxp: " + uidTxPacketsBefore + " -> " + uidTxPacketsAfter + " delta=" + uidTxDeltaPackets + - " Wanted: " + uidTxDeltaPackets + ">=" + packetCount + "+" + minExpectedExtraPackets + " && " + - uidTxDeltaPackets + "<=" + packetCount + "+" + packetCount + "+" + maxExpectedExtraPackets + "+" + deltaTxOtherPackets, - uidTxDeltaPackets >= packetCount + minExpectedExtraPackets && - uidTxDeltaPackets <= packetCount + packetCount + maxExpectedExtraPackets + deltaTxOtherPackets); - assertTrue("uidrxp: " + uidRxPacketsBefore + " -> " + uidRxPacketsAfter + " delta=" + uidRxDeltaPackets + - " Wanted: " + uidRxDeltaPackets + ">=" + packetCount + "+" + minExpectedExtraPackets + " && " + - uidRxDeltaPackets + "<=" + packetCount + "+" + packetCount + "+" + maxExpectedExtraPackets, - uidRxDeltaPackets >= packetCount + minExpectedExtraPackets && - uidRxDeltaPackets <= packetCount + packetCount + maxExpectedExtraPackets + deltaRxOtherPackets); - assertTrue("uidtxb: " + uidTxBytesBefore + " -> " + uidTxBytesAfter + " delta=" + uidTxDeltaBytes + - " Wanted: " + uidTxDeltaBytes + ">=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(minExpectedExtraPackets, 0) + " && " + - uidTxDeltaBytes + "<=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets, 0), - uidTxDeltaBytes >= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(minExpectedExtraPackets, 0) && - uidTxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets + deltaTxOtherPackets, 0)); - assertTrue("uidrxb: " + uidRxBytesBefore + " -> " + uidRxBytesAfter + " delta=" + uidRxDeltaBytes + - " Wanted: " + uidRxDeltaBytes + ">=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(minExpectedExtraPackets, 0) + " && " + - uidRxDeltaBytes + "<=" + tcpPacketToIpBytes(packetCount, byteCount) + "+" + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets, 0), - uidRxDeltaBytes >= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(minExpectedExtraPackets, 0) && - uidRxDeltaBytes <= tcpPacketToIpBytes(packetCount, byteCount) + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets + deltaRxOtherPackets, 0)); + assertInRange("uidtxp", uidTxDeltaPackets, packetCount + minExpectedExtraPackets, + packetCount + packetCount + maxExpectedExtraPackets + deltaTxOtherPackets); + assertInRange("uidrxp", uidRxDeltaPackets, packetCount + minExpectedExtraPackets, + packetCount + packetCount + maxExpectedExtraPackets + deltaRxOtherPackets); + assertInRange("uidtxb", uidTxDeltaBytes, tcpPacketToIpBytes(packetCount, byteCount) + + tcpPacketToIpBytes(minExpectedExtraPackets, 0), + tcpPacketToIpBytes(packetCount, byteCount) + + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets + + deltaTxOtherPackets, 0)); + assertInRange("uidrxb", uidRxDeltaBytes, tcpPacketToIpBytes(packetCount, byteCount) + + tcpPacketToIpBytes(minExpectedExtraPackets, 0), + tcpPacketToIpBytes(packetCount, byteCount) + + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets + + deltaRxOtherPackets, 0)); // Localhost traffic *does* count against total stats. // Check the total stats increased after test data transfer over localhost has been made. @@ -272,17 +273,13 @@ public class TrafficStatsTest extends AndroidTestCase { // Localhost traffic should *not* count against mobile stats, // There might be some other traffic, but nowhere near 1MB. - assertTrue("mtxp: " + mobileTxPacketsBefore + " -> " + mobileTxPacketsAfter, - mobileTxPacketsAfter >= mobileTxPacketsBefore && - mobileTxPacketsAfter <= mobileTxPacketsBefore + 500); - assertTrue("mrxp: " + mobileRxPacketsBefore + " -> " + mobileRxPacketsAfter, - mobileRxPacketsAfter >= mobileRxPacketsBefore && - mobileRxPacketsAfter <= mobileRxPacketsBefore + 500); - assertTrue("mtxb: " + mobileTxBytesBefore + " -> " + mobileTxBytesAfter, - mobileTxBytesAfter >= mobileTxBytesBefore && - mobileTxBytesAfter <= mobileTxBytesBefore + 200000); - assertTrue("mrxb: " + mobileRxBytesBefore + " -> " + mobileRxBytesAfter, - mobileRxBytesAfter >= mobileRxBytesBefore && - mobileRxBytesAfter <= mobileRxBytesBefore + 200000); + assertInRange("mtxp", mobileTxPacketsAfter, mobileTxPacketsBefore, + mobileTxPacketsBefore + 500); + assertInRange("mrxp", mobileRxPacketsAfter, mobileRxPacketsBefore, + mobileRxPacketsBefore + 500); + assertInRange("mtxb", mobileTxBytesAfter, mobileTxBytesBefore, + mobileTxBytesBefore + 200000); + assertInRange("mrxb", mobileRxBytesAfter, mobileRxBytesBefore, + mobileRxBytesBefore + 200000); } } From ed041b098a610e624cffc32b221234bfe54c54e7 Mon Sep 17 00:00:00 2001 From: paulhu Date: Fri, 10 Apr 2020 09:21:41 +0800 Subject: [PATCH 0846/1109] Add TetherableInterfaceRegexps CTS tests Test APIs below: getTetherableWifiRegexs() getTetherableUsbRegexs() getTetherableBluetoothRegexs() TetheringInterfaceRegexps.getTetherableWifiRegexs() TetheringInterfaceRegexps.getTetherableUsbRegexs() TetheringInterfaceRegexps.getTetherableBluetoothRegexs() Bug: 152737526 Test: atest CtsTetheringTest Change-Id: Icb7d8718d0aa6574b4c9dd1e17d7feb300fad2aa --- .../tethering/cts/TetheringManagerTest.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java index b132982e1a..193a5dc3a4 100644 --- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java +++ b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java @@ -428,4 +428,30 @@ public class TetheringManagerTest { tetherEventCallback.expectTetheredInterfacesChanged(null); mTM.unregisterTetheringEventCallback(tetherEventCallback); } + + @Test + public void testGetTetherableInterfaceRegexps() { + if (!mTM.isTetheringSupported()) return; + + final TestTetheringEventCallback tetherEventCallback = new TestTetheringEventCallback(); + mTM.registerTetheringEventCallback(c -> c.run(), tetherEventCallback); + tetherEventCallback.expectCallbackStarted(); + + final TetheringInterfaceRegexps tetherableRegexs = + tetherEventCallback.getTetheringInterfaceRegexps(); + final List wifiRegexs = tetherableRegexs.getTetherableWifiRegexs(); + final List usbRegexs = tetherableRegexs.getTetherableUsbRegexs(); + final List btRegexs = tetherableRegexs.getTetherableBluetoothRegexs(); + + assertEquals(wifiRegexs, Arrays.asList(mTM.getTetherableWifiRegexs())); + assertEquals(usbRegexs, Arrays.asList(mTM.getTetherableUsbRegexs())); + assertEquals(btRegexs, Arrays.asList(mTM.getTetherableBluetoothRegexs())); + + //Verify that any of interface name should only contain in one array. + wifiRegexs.forEach(s -> assertFalse(usbRegexs.contains(s))); + wifiRegexs.forEach(s -> assertFalse(btRegexs.contains(s))); + usbRegexs.forEach(s -> assertFalse(btRegexs.contains(s))); + + mTM.unregisterTetheringEventCallback(tetherEventCallback); + } } From ab9f1262702da216e9fa6cf798192ad1fb15a006 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Fri, 13 Mar 2020 21:08:39 +0900 Subject: [PATCH 0847/1109] Test onBandwidthUpdateRequested Test: this Bug: 139268426 Change-Id: I427ae6ac2c8910683e47f503ba71a05e35507571 --- .../net/src/android/net/cts/NetworkAgentTest.kt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 85c94e7db2..2fdd5fb201 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -24,6 +24,7 @@ import android.net.NetworkAgentConfig import android.net.NetworkCapabilities import android.net.NetworkProvider import android.net.NetworkRequest +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnBandwidthUpdateRequested import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnNetworkUnwanted import android.os.Build import android.os.HandlerThread @@ -88,9 +89,15 @@ class NetworkAgentTest { private val history = ArrayTrackRecord().newReadHead() sealed class CallbackEntry { + object OnBandwidthUpdateRequested : CallbackEntry() object OnNetworkUnwanted : CallbackEntry() } + override fun onBandwidthUpdateRequested() { + super.onBandwidthUpdateRequested() + history.add(OnBandwidthUpdateRequested) + } + override fun onNetworkUnwanted() { super.onNetworkUnwanted() history.add(OnNetworkUnwanted) @@ -139,4 +146,13 @@ class NetworkAgentTest { agent.register() } } + + @Test + fun testOnBandwidthUpdateRequested() { + val (agent, callback) = createConnectedNetworkAgent() + callback.expectAvailableThenValidatedCallbacks(agent.network) + mCM.requestBandwidthUpdate(agent.network) + agent.expectCallback() + agent.unregister() + } } From bbd10f21a0b7ffa4584f1066170d34ffb2856cc8 Mon Sep 17 00:00:00 2001 From: Mark Chien Date: Wed, 8 Apr 2020 13:10:26 +0000 Subject: [PATCH 0848/1109] Add testRegisterTetheringEventCallback for CtsTetheringTest Bug: 150632712 Bug: 150631563 Test: atest CtsTetheringTest Merged-In: I55895c8b26acb7ec905d75d1f4b2a8964b13187a Change-Id: I55895c8b26acb7ec905d75d1f4b2a8964b13187a --- .../tethering/cts/TetheringManagerTest.java | 181 +++++++++++++++++- 1 file changed, 179 insertions(+), 2 deletions(-) diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java index 86fe54ce54..b132982e1a 100644 --- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java +++ b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java @@ -29,9 +29,14 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.LinkAddress; +import android.net.Network; +import android.net.TetheredClient; import android.net.TetheringManager; +import android.net.TetheringManager.TetheringEventCallback; +import android.net.TetheringManager.TetheringInterfaceRegexps; import android.net.TetheringManager.TetheringRequest; +import androidx.annotation.NonNull; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; @@ -42,6 +47,8 @@ import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.List; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; @@ -195,8 +202,12 @@ public class TetheringManagerTest { } } - private static boolean isIfaceMatch(final String[] ifaceRegexs, - final ArrayList ifaces) { + private static boolean isIfaceMatch(final List ifaceRegexs, + final List ifaces) { + return isIfaceMatch(ifaceRegexs.toArray(new String[0]), ifaces); + } + + private static boolean isIfaceMatch(final String[] ifaceRegexs, final List ifaces) { if (ifaceRegexs == null) fail("ifaceRegexs should not be null"); if (ifaces == null) return false; @@ -251,4 +262,170 @@ public class TetheringManagerTest { assertTrue(tr2.isExemptFromEntitlementCheck()); assertFalse(tr2.getShouldShowEntitlementUi()); } + + // Must poll the callback before looking at the member. + private static class TestTetheringEventCallback implements TetheringEventCallback { + public enum CallbackType { + ON_SUPPORTED, + ON_UPSTREAM, + ON_TETHERABLE_REGEX, + ON_TETHERABLE_IFACES, + ON_TETHERED_IFACES, + ON_ERROR, + ON_CLIENTS, + }; + + public static class CallbackValue { + public final CallbackType callbackType; + public final Object callbackParam; + public final int callbackParam2; + + private CallbackValue(final CallbackType type, final Object param, final int param2) { + this.callbackType = type; + this.callbackParam = param; + this.callbackParam2 = param2; + } + } + private final LinkedBlockingQueue mCallbacks = new LinkedBlockingQueue<>(); + + private TetheringInterfaceRegexps mTetherableRegex; + private List mTetherableIfaces; + private List mTetheredIfaces; + + @Override + public void onTetheringSupported(boolean supported) { + mCallbacks.add(new CallbackValue(CallbackType.ON_SUPPORTED, null, 0)); + } + + @Override + public void onUpstreamChanged(Network network) { + mCallbacks.add(new CallbackValue(CallbackType.ON_UPSTREAM, network, 0)); + } + + @Override + public void onTetherableInterfaceRegexpsChanged(TetheringInterfaceRegexps reg) { + mTetherableRegex = reg; + mCallbacks.add(new CallbackValue(CallbackType.ON_TETHERABLE_REGEX, reg, 0)); + } + + @Override + public void onTetherableInterfacesChanged(List interfaces) { + mTetherableIfaces = interfaces; + mCallbacks.add(new CallbackValue(CallbackType.ON_TETHERABLE_IFACES, interfaces, 0)); + } + + @Override + public void onTetheredInterfacesChanged(List interfaces) { + mTetheredIfaces = interfaces; + mCallbacks.add(new CallbackValue(CallbackType.ON_TETHERED_IFACES, interfaces, 0)); + } + + @Override + public void onError(String ifName, int error) { + mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, ifName, error)); + } + + @Override + public void onClientsChanged(Collection clients) { + mCallbacks.add(new CallbackValue(CallbackType.ON_CLIENTS, clients, 0)); + } + + public CallbackValue pollCallback() { + try { + return mCallbacks.poll(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + fail("Callback not seen"); + } + return null; + } + + public void expectTetherableInterfacesChanged(@NonNull List regexs) { + while (true) { + final CallbackValue cv = pollCallback(); + if (cv == null) fail("No expected tetherable ifaces callback"); + if (cv.callbackType != CallbackType.ON_TETHERABLE_IFACES) continue; + + final List interfaces = (List) cv.callbackParam; + if (isIfaceMatch(regexs, interfaces)) break; + } + } + + public void expectTetheredInterfacesChanged(@NonNull List regexs) { + while (true) { + final CallbackValue cv = pollCallback(); + if (cv == null) fail("No expected tethered ifaces callback"); + if (cv.callbackType != CallbackType.ON_TETHERED_IFACES) continue; + + final List interfaces = (List) cv.callbackParam; + + // Null regexs means no active tethering. + if (regexs == null) { + if (interfaces.size() == 0) break; + } else if (isIfaceMatch(regexs, interfaces)) { + break; + } + } + } + + public void expectCallbackStarted() { + // The each bit represent a type from CallbackType.ON_*. + // Expect all of callbacks except for ON_ERROR. + final int expectedBitMap = 0x7f ^ (1 << CallbackType.ON_ERROR.ordinal()); + int receivedBitMap = 0; + while (receivedBitMap != expectedBitMap) { + final CallbackValue cv = pollCallback(); + if (cv == null) { + fail("No expected callbacks, " + "expected bitmap: " + + expectedBitMap + ", actual: " + receivedBitMap); + } + receivedBitMap = receivedBitMap | (1 << cv.callbackType.ordinal()); + } + } + + public TetheringInterfaceRegexps getTetheringInterfaceRegexps() { + return mTetherableRegex; + } + + public List getTetherableInterfaces() { + return mTetherableIfaces; + } + + public List getTetheredInterfaces() { + return mTetheredIfaces; + } + } + + @Test + public void testRegisterTetheringEventCallback() throws Exception { + if (!mTM.isTetheringSupported()) return; + + final TestTetheringEventCallback tetherEventCallback = new TestTetheringEventCallback(); + + mTM.registerTetheringEventCallback(c -> c.run(), tetherEventCallback); + tetherEventCallback.expectCallbackStarted(); + + final TetheringInterfaceRegexps tetherableRegexs = + tetherEventCallback.getTetheringInterfaceRegexps(); + final List wifiRegexs = tetherableRegexs.getTetherableWifiRegexs(); + if (wifiRegexs.size() == 0) return; + + final boolean isIfaceAvailWhenNoTethering = + isIfaceMatch(wifiRegexs, tetherEventCallback.getTetherableInterfaces()); + + mTM.startTethering(new TetheringRequest.Builder(TETHERING_WIFI).build(), c -> c.run(), + new StartTetheringCallback()); + + // If interface is already available before starting tethering, the available callback may + // not be sent after tethering enabled. + if (!isIfaceAvailWhenNoTethering) { + tetherEventCallback.expectTetherableInterfacesChanged(wifiRegexs); + } + + tetherEventCallback.expectTetheredInterfacesChanged(wifiRegexs); + + mTM.stopTethering(TETHERING_WIFI); + + tetherEventCallback.expectTetheredInterfacesChanged(null); + mTM.unregisterTetheringEventCallback(tetherEventCallback); + } } From 853c428964aa6d607c65132080f8986541191bd0 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Fri, 10 Apr 2020 11:34:58 -0600 Subject: [PATCH 0849/1109] Fix logic inversion bug from Android 1.0. Bug: 73822755 Test: atest CtsNetTestCases:android.net.cts.UrlQuerySanitizerTest Change-Id: Ice98bb0813918341d8cffd3197cd9758d0cbf285 --- .../android/net/cts/UrlQuerySanitizerTest.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java b/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java index 2d615bbe86..82b3b14d34 100644 --- a/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java +++ b/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java @@ -16,14 +16,15 @@ package android.net.cts; -import java.util.List; -import java.util.Set; import android.net.UrlQuerySanitizer; import android.net.UrlQuerySanitizer.IllegalCharacterValueSanitizer; import android.net.UrlQuerySanitizer.ParameterValuePair; import android.net.UrlQuerySanitizer.ValueSanitizer; import android.test.AndroidTestCase; +import java.util.List; +import java.util.Set; + public class UrlQuerySanitizerTest extends AndroidTestCase { private static final int ALL_OK = IllegalCharacterValueSanitizer.ALL_OK; @@ -209,6 +210,17 @@ public class UrlQuerySanitizerTest extends AndroidTestCase { } + public void testScriptUrlOk_73822755() { + ValueSanitizer sanitizer = new UrlQuerySanitizer.IllegalCharacterValueSanitizer( + UrlQuerySanitizer.IllegalCharacterValueSanitizer.SCRIPT_URL_OK); + assertEquals("javascript:alert()", sanitizer.sanitize("javascript:alert()")); + } + + public void testScriptUrlBlocked_73822755() { + ValueSanitizer sanitizer = UrlQuerySanitizer.getUrlAndSpaceLegal(); + assertEquals("", sanitizer.sanitize("javascript:alert()")); + } + private static class MockValueSanitizer implements ValueSanitizer{ public String sanitize(String value) { From 848b78d9fb307336337560aff274ca8c8ef51543 Mon Sep 17 00:00:00 2001 From: evitayan Date: Sun, 8 Mar 2020 18:41:02 -0700 Subject: [PATCH 0850/1109] Add CTS for building IKE and Child SaProposal Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: Ic50d70f35216a065ff398c38262f2de0b370c5ef --- .../net/ipsec/ike/cts/SaProposalTest.java | 232 +++++++++++++++++- 1 file changed, 229 insertions(+), 3 deletions(-) diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java index 47e8f0174d..e0d3be0540 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java @@ -16,15 +16,241 @@ package android.net.ipsec.ike.cts; +import static android.net.ipsec.ike.SaProposal.DH_GROUP_1024_BIT_MODP; +import static android.net.ipsec.ike.SaProposal.DH_GROUP_2048_BIT_MODP; +import static android.net.ipsec.ike.SaProposal.DH_GROUP_NONE; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_3DES; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_CBC; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_AES_XCBC_96; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_384_192; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_512_256; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_NONE; +import static android.net.ipsec.ike.SaProposal.KEY_LEN_AES_128; +import static android.net.ipsec.ike.SaProposal.KEY_LEN_AES_192; +import static android.net.ipsec.ike.SaProposal.KEY_LEN_AES_256; +import static android.net.ipsec.ike.SaProposal.KEY_LEN_UNUSED; +import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC; +import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1; +import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_SHA2_256; +import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_SHA2_384; +import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_SHA2_512; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import android.net.ipsec.ike.ChildSaProposal; +import android.net.ipsec.ike.IkeSaProposal; +import android.util.Pair; + import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + @RunWith(AndroidJUnit4.class) public class SaProposalTest { - @Test - public void testBuildIkeSaProposal() { - // TODO(b/148689509): Add real tests here + private static final List> NORMAL_MODE_CIPHERS = new ArrayList<>(); + private static final List> COMBINED_MODE_CIPHERS = new ArrayList<>(); + private static final List INTEGRITY_ALGOS = new ArrayList<>(); + private static final List DH_GROUPS = new ArrayList<>(); + private static final List DH_GROUPS_WITH_NONE = new ArrayList<>(); + private static final List PRFS = new ArrayList<>(); + + static { + NORMAL_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED)); + NORMAL_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_128)); + NORMAL_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_192)); + NORMAL_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_256)); + + COMBINED_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_GCM_8, KEY_LEN_AES_128)); + COMBINED_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_192)); + COMBINED_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_256)); + + INTEGRITY_ALGOS.add(INTEGRITY_ALGORITHM_HMAC_SHA1_96); + INTEGRITY_ALGOS.add(INTEGRITY_ALGORITHM_AES_XCBC_96); + INTEGRITY_ALGOS.add(INTEGRITY_ALGORITHM_HMAC_SHA2_256_128); + INTEGRITY_ALGOS.add(INTEGRITY_ALGORITHM_HMAC_SHA2_384_192); + INTEGRITY_ALGOS.add(INTEGRITY_ALGORITHM_HMAC_SHA2_512_256); + + DH_GROUPS.add(DH_GROUP_1024_BIT_MODP); + DH_GROUPS.add(DH_GROUP_2048_BIT_MODP); + + DH_GROUPS_WITH_NONE.add(DH_GROUP_NONE); + DH_GROUPS_WITH_NONE.addAll(DH_GROUPS); + + PRFS.add(PSEUDORANDOM_FUNCTION_HMAC_SHA1); + PRFS.add(PSEUDORANDOM_FUNCTION_AES128_XCBC); + PRFS.add(PSEUDORANDOM_FUNCTION_SHA2_256); + PRFS.add(PSEUDORANDOM_FUNCTION_SHA2_384); + PRFS.add(PSEUDORANDOM_FUNCTION_SHA2_512); } + + // Package private + static IkeSaProposal buildIkeSaProposalWithNormalModeCipher() { + return buildIkeSaProposal(NORMAL_MODE_CIPHERS, INTEGRITY_ALGOS, PRFS, DH_GROUPS); + } + + // Package private + static IkeSaProposal buildIkeSaProposalWithCombinedModeCipher() { + return buildIkeSaProposalWithCombinedModeCipher(true /* hasIntegrityNone */); + } + + private static IkeSaProposal buildIkeSaProposalWithCombinedModeCipher( + boolean hasIntegrityNone) { + List integerAlgos = new ArrayList<>(); + if (hasIntegrityNone) { + integerAlgos.add(INTEGRITY_ALGORITHM_NONE); + } + return buildIkeSaProposal(COMBINED_MODE_CIPHERS, integerAlgos, PRFS, DH_GROUPS); + } + + private static IkeSaProposal buildIkeSaProposal( + List> ciphers, + List integrityAlgos, + List prfs, + List dhGroups) { + IkeSaProposal.Builder builder = new IkeSaProposal.Builder(); + + for (Pair pair : ciphers) { + builder.addEncryptionAlgorithm(pair.first, pair.second); + } + for (int algo : integrityAlgos) { + builder.addIntegrityAlgorithm(algo); + } + for (int algo : prfs) { + builder.addPseudorandomFunction(algo); + } + for (int algo : dhGroups) { + builder.addDhGroup(algo); + } + + return builder.build(); + } + + // Package private + static ChildSaProposal buildChildSaProposalWithNormalModeCipher() { + return buildChildSaProposal(NORMAL_MODE_CIPHERS, INTEGRITY_ALGOS, DH_GROUPS_WITH_NONE); + } + + // Package private + static ChildSaProposal buildChildSaProposalWithCombinedModeCipher() { + return buildChildSaProposalWithCombinedModeCipher(true /* hasIntegrityNone */); + } + + private static ChildSaProposal buildChildSaProposalWithCombinedModeCipher( + boolean hasIntegrityNone) { + List integerAlgos = new ArrayList<>(); + if (hasIntegrityNone) { + integerAlgos.add(INTEGRITY_ALGORITHM_NONE); + } + + return buildChildSaProposal(COMBINED_MODE_CIPHERS, integerAlgos, DH_GROUPS_WITH_NONE); + } + + private static ChildSaProposal buildChildSaProposal( + List> ciphers, + List integrityAlgos, + List dhGroups) { + ChildSaProposal.Builder builder = new ChildSaProposal.Builder(); + + for (Pair pair : ciphers) { + builder.addEncryptionAlgorithm(pair.first, pair.second); + } + for (int algo : integrityAlgos) { + builder.addIntegrityAlgorithm(algo); + } + for (int algo : dhGroups) { + builder.addDhGroup(algo); + } + + return builder.build(); + } + + // Package private + static ChildSaProposal buildChildSaProposalWithOnlyCiphers() { + return buildChildSaProposal( + COMBINED_MODE_CIPHERS, Collections.EMPTY_LIST, Collections.EMPTY_LIST); + } + + @Test + public void testBuildIkeSaProposalWithNormalModeCipher() { + IkeSaProposal saProposal = buildIkeSaProposalWithNormalModeCipher(); + + assertEquals(NORMAL_MODE_CIPHERS, saProposal.getEncryptionAlgorithms()); + assertEquals(INTEGRITY_ALGOS, saProposal.getIntegrityAlgorithms()); + assertEquals(PRFS, saProposal.getPseudorandomFunctions()); + assertEquals(DH_GROUPS, saProposal.getDhGroups()); + } + + @Test + public void testBuildIkeSaProposalWithCombinedModeCipher() { + IkeSaProposal saProposal = + buildIkeSaProposalWithCombinedModeCipher(false /* hasIntegrityNone */); + + assertEquals(COMBINED_MODE_CIPHERS, saProposal.getEncryptionAlgorithms()); + assertEquals(PRFS, saProposal.getPseudorandomFunctions()); + assertEquals(DH_GROUPS, saProposal.getDhGroups()); + assertTrue(saProposal.getIntegrityAlgorithms().isEmpty()); + } + + @Test + public void testBuildIkeSaProposalWithCombinedModeCipherAndIntegrityNone() { + IkeSaProposal saProposal = + buildIkeSaProposalWithCombinedModeCipher(true /* hasIntegrityNone */); + + assertEquals(COMBINED_MODE_CIPHERS, saProposal.getEncryptionAlgorithms()); + assertEquals(PRFS, saProposal.getPseudorandomFunctions()); + assertEquals(DH_GROUPS, saProposal.getDhGroups()); + assertEquals(Arrays.asList(INTEGRITY_ALGORITHM_NONE), saProposal.getIntegrityAlgorithms()); + } + + @Test + public void testBuildChildSaProposalWithNormalModeCipher() { + ChildSaProposal saProposal = buildChildSaProposalWithNormalModeCipher(); + + assertEquals(NORMAL_MODE_CIPHERS, saProposal.getEncryptionAlgorithms()); + assertEquals(INTEGRITY_ALGOS, saProposal.getIntegrityAlgorithms()); + assertEquals(DH_GROUPS_WITH_NONE, saProposal.getDhGroups()); + } + + @Test + public void testBuildChildProposalWithCombinedModeCipher() { + ChildSaProposal saProposal = + buildChildSaProposalWithCombinedModeCipher(false /* hasIntegrityNone */); + + assertEquals(COMBINED_MODE_CIPHERS, saProposal.getEncryptionAlgorithms()); + assertTrue(saProposal.getIntegrityAlgorithms().isEmpty()); + assertEquals(DH_GROUPS_WITH_NONE, saProposal.getDhGroups()); + } + + @Test + public void testBuildChildProposalWithCombinedModeCipherAndIntegrityNone() { + ChildSaProposal saProposal = + buildChildSaProposalWithCombinedModeCipher(true /* hasIntegrityNone */); + + assertEquals(COMBINED_MODE_CIPHERS, saProposal.getEncryptionAlgorithms()); + assertEquals(Arrays.asList(INTEGRITY_ALGORITHM_NONE), saProposal.getIntegrityAlgorithms()); + assertEquals(DH_GROUPS_WITH_NONE, saProposal.getDhGroups()); + } + + @Test + public void testBuildChildSaProposalWithOnlyCiphers() { + ChildSaProposal saProposal = buildChildSaProposalWithOnlyCiphers(); + + assertEquals(COMBINED_MODE_CIPHERS, saProposal.getEncryptionAlgorithms()); + assertTrue(saProposal.getIntegrityAlgorithms().isEmpty()); + assertTrue(saProposal.getDhGroups().isEmpty()); + } + + // TODO(b/148689509): Test throwing exception when algorithm combination is invalid } From e1236aeae4627ec3b4b5a7b96891f2107fb4c34f Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Thu, 9 Apr 2020 03:26:31 +0000 Subject: [PATCH 0851/1109] Add cts test for traffic stats APIs This change adds test for new public APIs. Bug: 135998869 Test: atest CtsNetTestCasesLatestSdk:TrafficStatsTest Change-Id: Iefc234fb85145b31a1f7842b93b4d6fc4425bab6 Merged-In: I6b4a6773e22a204b6267d28638b9f57a0d0eb65a (cherry picked from commit e5a3234c38c35aaec55029e369f2aac2ec4326cd) --- .../src/android/net/cts/TrafficStatsTest.java | 58 ++++++++++++------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java index 12ab3702d4..577e24ac29 100755 --- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java +++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java @@ -61,6 +61,11 @@ public class TrafficStatsTest extends AndroidTestCase { assertTrue(TrafficStats.getTotalRxBytes() >= 0); } + public void testValidPacketStats() { + assertTrue(TrafficStats.getTxPackets("lo") >= 0); + assertTrue(TrafficStats.getRxPackets("lo") >= 0); + } + public void testThreadStatsTag() throws Exception { TrafficStats.setThreadStatsTag(0xf00d); assertTrue("Tag didn't stick", TrafficStats.getThreadStatsTag() == 0xf00d); @@ -104,6 +109,8 @@ public class TrafficStatsTest extends AndroidTestCase { final long uidRxBytesBefore = TrafficStats.getUidRxBytes(Process.myUid()); final long uidTxPacketsBefore = TrafficStats.getUidTxPackets(Process.myUid()); final long uidRxPacketsBefore = TrafficStats.getUidRxPackets(Process.myUid()); + final long ifaceTxPacketsBefore = TrafficStats.getTxPackets("lo"); + final long ifaceRxPacketsBefore = TrafficStats.getRxPackets("lo"); // Transfer 1MB of data across an explicitly localhost socket. final int byteCount = 1024; @@ -182,6 +189,10 @@ public class TrafficStatsTest extends AndroidTestCase { final long uidTxDeltaPackets = uidTxPacketsAfter - uidTxPacketsBefore; final long uidRxDeltaBytes = uidRxBytesAfter - uidRxBytesBefore; final long uidRxDeltaPackets = uidRxPacketsAfter - uidRxPacketsBefore; + final long ifaceTxPacketsAfter = TrafficStats.getTxPackets("lo"); + final long ifaceRxPacketsAfter = TrafficStats.getRxPackets("lo"); + final long ifaceTxDeltaPackets = ifaceTxPacketsAfter - ifaceTxPacketsBefore; + final long ifaceRxDeltaPackets = ifaceRxPacketsAfter - ifaceRxPacketsBefore; // Localhost traffic *does* count against per-UID stats. /* @@ -209,34 +220,37 @@ public class TrafficStatsTest extends AndroidTestCase { + deltaRxOtherPackets); } - // Check the per uid stats read from data profiling have the stats expected. The data - // profiling snapshot is generated from readNetworkStatsDetail() method in - // networkStatsService and in this way we can verify the detail networkStats of a given uid - // is correct. - NetworkStats.Entry entry = testStats.getTotal(null, Process.myUid()); + // Check that the per-uid stats obtained from data profiling contain the expected values. + // The data profiling snapshot is generated from the readNetworkStatsDetail() method in + // networkStatsService, so it's possible to verify that the detailed stats for a given + // uid are correct. + final NetworkStats.Entry entry = testStats.getTotal(null, Process.myUid()); + final long pktBytes = tcpPacketToIpBytes(packetCount, byteCount); + final long pktWithNoDataBytes = tcpPacketToIpBytes(packetCount, 0); + final long minExpExtraPktBytes = tcpPacketToIpBytes(minExpectedExtraPackets, 0); + final long maxExpExtraPktBytes = tcpPacketToIpBytes(maxExpectedExtraPackets, 0); + final long deltaTxOtherPktBytes = tcpPacketToIpBytes(deltaTxOtherPackets, 0); + final long deltaRxOtherPktBytes = tcpPacketToIpBytes(deltaRxOtherPackets, 0); assertInRange("txPackets detail", entry.txPackets, packetCount + minExpectedExtraPackets, uidTxDeltaPackets); assertInRange("rxPackets detail", entry.rxPackets, packetCount + minExpectedExtraPackets, uidRxDeltaPackets); - assertInRange("txBytes detail", entry.txBytes, tcpPacketToIpBytes(packetCount, byteCount) - + tcpPacketToIpBytes(minExpectedExtraPackets, 0), uidTxDeltaBytes); - assertInRange("rxBytes detail", entry.rxBytes, tcpPacketToIpBytes(packetCount, byteCount) - + tcpPacketToIpBytes(minExpectedExtraPackets, 0), uidRxDeltaBytes); - + assertInRange("txBytes detail", entry.txBytes, pktBytes + minExpExtraPktBytes, + uidTxDeltaBytes); + assertInRange("rxBytes detail", entry.rxBytes, pktBytes + minExpExtraPktBytes, + uidRxDeltaBytes); assertInRange("uidtxp", uidTxDeltaPackets, packetCount + minExpectedExtraPackets, packetCount + packetCount + maxExpectedExtraPackets + deltaTxOtherPackets); assertInRange("uidrxp", uidRxDeltaPackets, packetCount + minExpectedExtraPackets, packetCount + packetCount + maxExpectedExtraPackets + deltaRxOtherPackets); - assertInRange("uidtxb", uidTxDeltaBytes, tcpPacketToIpBytes(packetCount, byteCount) - + tcpPacketToIpBytes(minExpectedExtraPackets, 0), - tcpPacketToIpBytes(packetCount, byteCount) - + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets - + deltaTxOtherPackets, 0)); - assertInRange("uidrxb", uidRxDeltaBytes, tcpPacketToIpBytes(packetCount, byteCount) - + tcpPacketToIpBytes(minExpectedExtraPackets, 0), - tcpPacketToIpBytes(packetCount, byteCount) - + tcpPacketToIpBytes(packetCount + maxExpectedExtraPackets - + deltaRxOtherPackets, 0)); + assertInRange("uidtxb", uidTxDeltaBytes, pktBytes + minExpExtraPktBytes, + pktBytes + pktWithNoDataBytes + maxExpExtraPktBytes + deltaTxOtherPktBytes); + assertInRange("uidrxb", uidRxDeltaBytes, pktBytes + minExpExtraPktBytes, + pktBytes + pktWithNoDataBytes + maxExpExtraPktBytes + deltaRxOtherPktBytes); + assertInRange("iftxp", ifaceTxDeltaPackets, packetCount + minExpectedExtraPackets, + packetCount + packetCount + maxExpectedExtraPackets + deltaTxOtherPackets); + assertInRange("ifrxp", ifaceRxDeltaPackets, packetCount + minExpectedExtraPackets, + packetCount + packetCount + maxExpectedExtraPackets + deltaRxOtherPackets); // Localhost traffic *does* count against total stats. // Check the total stats increased after test data transfer over localhost has been made. @@ -248,6 +262,10 @@ public class TrafficStatsTest extends AndroidTestCase { totalTxBytesAfter >= totalTxBytesBefore + uidTxDeltaBytes); assertTrue("trxb: " + totalRxBytesBefore + " -> " + totalRxBytesAfter, totalRxBytesAfter >= totalRxBytesBefore + uidRxDeltaBytes); + assertTrue("iftxp: " + ifaceTxPacketsBefore + " -> " + ifaceTxPacketsAfter, + totalTxPacketsAfter >= totalTxPacketsBefore + ifaceTxDeltaPackets); + assertTrue("ifrxp: " + ifaceRxPacketsBefore + " -> " + ifaceRxPacketsAfter, + totalRxPacketsAfter >= totalRxPacketsBefore + ifaceRxDeltaPackets); // If the adb TCP port is opened, this test may be run by adb over network. // Huge amount of data traffic might go through the network and accounted into total packets From 9e5d061d736663f99bf1548ac3f2044e43f8402e Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Mon, 13 Apr 2020 17:40:06 +0900 Subject: [PATCH 0852/1109] Add tethering CTS owners. Test: none Change-Id: I552b3bf8d79c4e4480396edc201b51ec5901b87b --- tests/cts/tethering/OWNERS | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 tests/cts/tethering/OWNERS diff --git a/tests/cts/tethering/OWNERS b/tests/cts/tethering/OWNERS new file mode 100644 index 0000000000..cd6abeb6e8 --- /dev/null +++ b/tests/cts/tethering/OWNERS @@ -0,0 +1,4 @@ +# Bug component: 31808 +lorenzo@google.com +satk@google.com + From 01f3fd3d80529fadc23d19683fc822a1f9746349 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Sun, 12 Apr 2020 21:34:11 +0900 Subject: [PATCH 0853/1109] Increase test independence If a test fails without unregistering an agent, other tests will see their requests match the old agent. That means any test failing will fail all subsequent tests, which is not very helpful. Solve this by making sure the agents are unregistered before the test ends. Also ensure the requests are unregistered. Test: NetworkAgentTest Change-Id: I2c167803d478d31fd85dc6e6e621f35d36c68fb4 --- .../src/android/net/cts/NetworkAgentTest.kt | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 2fdd5fb201..d0e3023db6 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -67,6 +67,9 @@ class NetworkAgentTest { private class Provider(context: Context, looper: Looper) : NetworkProvider(context, looper, "NetworkAgentTest NetworkProvider") + private val agentsToCleanUp = mutableListOf() + private val callbacksToCleanUp = mutableListOf() + @Before fun setUp() { instrumentation.getUiAutomation().adoptShellPermissionIdentity() @@ -75,11 +78,13 @@ class NetworkAgentTest { @After fun tearDown() { + agentsToCleanUp.forEach { it.unregister() } + callbacksToCleanUp.forEach { mCM.unregisterNetworkCallback(it) } mHandlerThread.quitSafely() instrumentation.getUiAutomation().dropShellPermissionIdentity() } - internal class TestableNetworkAgent( + private class TestableNetworkAgent( looper: Looper, nc: NetworkCapabilities, lp: LinkProperties, @@ -94,12 +99,10 @@ class NetworkAgentTest { } override fun onBandwidthUpdateRequested() { - super.onBandwidthUpdateRequested() history.add(OnBandwidthUpdateRequested) } override fun onNetworkUnwanted() { - super.onNetworkUnwanted() history.add(OnNetworkUnwanted) } @@ -109,6 +112,11 @@ class NetworkAgentTest { } } + private fun requestNetwork(request: NetworkRequest, callback: TestableNetworkCallback) { + mCM.requestNetwork(request, callback) + callbacksToCleanUp.add(callback) + } + private fun createNetworkAgent(): TestableNetworkAgent { val nc = NetworkCapabilities().apply { addTransportType(NetworkCapabilities.TRANSPORT_TEST) @@ -120,7 +128,9 @@ class NetworkAgentTest { } val lp = LinkProperties() val config = NetworkAgentConfig.Builder().build() - return TestableNetworkAgent(mHandlerThread.looper, nc, lp, config) + return TestableNetworkAgent(mHandlerThread.looper, nc, lp, config).also { + agentsToCleanUp.add(it) + } } private fun createConnectedNetworkAgent(): Pair { @@ -129,8 +139,9 @@ class NetworkAgentTest { .addTransportType(NetworkCapabilities.TRANSPORT_TEST) .build() val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS) - mCM.requestNetwork(request, callback) - val agent = createNetworkAgent().also { it.register() } + requestNetwork(request, callback) + val agent = createNetworkAgent() + agent.register() agent.markConnected() return agent to callback } From 570b76b2735a49bc8008956e088e0f24297bbdcb Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Fri, 13 Mar 2020 21:10:56 +0900 Subject: [PATCH 0854/1109] Test onStartSocketKeepalive Test: this Bug: 139268426 Change-Id: I4e251fa0203a1888badef9ed90495fe8b3340a1c --- .../src/android/net/cts/NetworkAgentTest.kt | 161 +++++++++++++++++- 1 file changed, 155 insertions(+), 6 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index d0e3023db6..32f2bfafe2 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -18,29 +18,51 @@ package android.net.cts import android.app.Instrumentation import android.content.Context import android.net.ConnectivityManager +import android.net.KeepalivePacketData +import android.net.LinkAddress import android.net.LinkProperties +import android.net.Network import android.net.NetworkAgent +import android.net.NetworkAgent.CMD_ADD_KEEPALIVE_PACKET_FILTER +import android.net.NetworkAgent.CMD_REMOVE_KEEPALIVE_PACKET_FILTER +import android.net.NetworkAgent.CMD_START_SOCKET_KEEPALIVE +import android.net.NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE import android.net.NetworkAgentConfig import android.net.NetworkCapabilities import android.net.NetworkProvider import android.net.NetworkRequest -import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnBandwidthUpdateRequested -import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnNetworkUnwanted +import android.net.SocketKeepalive import android.os.Build +import android.os.Handler import android.os.HandlerThread import android.os.Looper +import android.os.Message +import android.os.Messenger +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnAddKeepalivePacketFilter +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnBandwidthUpdateRequested +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnNetworkUnwanted +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnRemoveKeepalivePacketFilter +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStartSocketKeepalive +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStopSocketKeepalive import androidx.test.InstrumentationRegistry import androidx.test.runner.AndroidJUnit4 +import com.android.internal.util.AsyncChannel import com.android.testutils.ArrayTrackRecord import com.android.testutils.DevSdkIgnoreRule import com.android.testutils.RecorderCallback.CallbackEntry.Lost import com.android.testutils.TestableNetworkCallback import org.junit.After +import org.junit.Assert.fail import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import java.net.InetAddress +import java.time.Duration +import kotlin.test.assertEquals import kotlin.test.assertFailsWith +import kotlin.test.assertNotNull +import kotlin.test.assertNull import kotlin.test.assertTrue // This test doesn't really have a constraint on how fast the methods should return. If it's @@ -51,18 +73,29 @@ private const val DEFAULT_TIMEOUT_MS = 5000L // requests filed by the test and should never match normal internet requests. 70 is the default // score of Ethernet networks, it's as good a value as any other. private const val TEST_NETWORK_SCORE = 70 +private const val FAKE_NET_ID = 1098 private val instrumentation: Instrumentation get() = InstrumentationRegistry.getInstrumentation() private val context: Context get() = InstrumentationRegistry.getContext() +private fun Message(what: Int, arg1: Int, arg2: Int, obj: Any?) = Message.obtain().also { + it.what = what + it.arg1 = arg1 + it.arg2 = arg2 + it.obj = obj +} @RunWith(AndroidJUnit4::class) class NetworkAgentTest { @Rule @JvmField val ignoreRule = DevSdkIgnoreRule(ignoreClassUpTo = Build.VERSION_CODES.Q) + private val LOCAL_IPV4_ADDRESS = InetAddress.parseNumericAddress("192.0.2.1") + private val REMOTE_IPV4_ADDRESS = InetAddress.parseNumericAddress("192.0.2.2") + private val mCM = context.getSystemService(ConnectivityManager::class.java) private val mHandlerThread = HandlerThread("${javaClass.simpleName} handler thread") + private val mFakeConnectivityService by lazy { FakeConnectivityService(mHandlerThread.looper) } private class Provider(context: Context, looper: Looper) : NetworkProvider(context, looper, "NetworkAgentTest NetworkProvider") @@ -84,8 +117,37 @@ class NetworkAgentTest { instrumentation.getUiAutomation().dropShellPermissionIdentity() } - private class TestableNetworkAgent( - looper: Looper, + /** + * A fake that helps simulating ConnectivityService talking to a harnessed agent. + * This fake only supports speaking to one harnessed agent at a time because it + * only keeps track of one async channel. + */ + private class FakeConnectivityService(looper: Looper) { + private val msgHistory = ArrayTrackRecord().newReadHead() + private val asyncChannel = AsyncChannel() + private val handler = object : Handler(looper) { + override fun handleMessage(msg: Message) { + msgHistory.add(Message.obtain(msg)) // make a copy as the original will be recycled + when (msg.what) { + AsyncChannel.CMD_CHANNEL_HALF_CONNECTED -> + asyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION) + AsyncChannel.CMD_CHANNEL_DISCONNECT, AsyncChannel.CMD_CHANNEL_DISCONNECTED -> + fail("Agent unexpectedly disconnected") + } + } + } + + fun connect(agentMsngr: Messenger) = asyncChannel.connect(context, handler, agentMsngr) + + fun sendMessage(what: Int, arg1: Int = 0, arg2: Int = 0, obj: Any? = null) = + asyncChannel.sendMessage(Message(what, arg1, arg2, obj)) + + fun expectMessage(what: Int) = + assertNotNull(msgHistory.poll(DEFAULT_TIMEOUT_MS) { it.what == what }) + } + + private open class TestableNetworkAgent( + val looper: Looper, nc: NetworkCapabilities, lp: LinkProperties, conf: NetworkAgentConfig @@ -96,6 +158,17 @@ class NetworkAgentTest { sealed class CallbackEntry { object OnBandwidthUpdateRequested : CallbackEntry() object OnNetworkUnwanted : CallbackEntry() + data class OnAddKeepalivePacketFilter( + val slot: Int, + val packet: KeepalivePacketData + ) : CallbackEntry() + data class OnRemoveKeepalivePacketFilter(val slot: Int) : CallbackEntry() + data class OnStartSocketKeepalive( + val slot: Int, + val interval: Int, + val packet: KeepalivePacketData + ) : CallbackEntry() + data class OnStopSocketKeepalive(val slot: Int) : CallbackEntry() } override fun onBandwidthUpdateRequested() { @@ -106,9 +179,35 @@ class NetworkAgentTest { history.add(OnNetworkUnwanted) } - inline fun expectCallback() { + override fun onAddKeepalivePacketFilter(slot: Int, packet: KeepalivePacketData) { + history.add(OnAddKeepalivePacketFilter(slot, packet)) + } + + override fun onRemoveKeepalivePacketFilter(slot: Int) { + history.add(OnRemoveKeepalivePacketFilter(slot)) + } + + override fun onStartSocketKeepalive( + slot: Int, + interval: Duration, + packet: KeepalivePacketData + ) { + history.add(OnStartSocketKeepalive(slot, interval.seconds.toInt(), packet)) + } + + override fun onStopSocketKeepalive(slot: Int) { + history.add(OnStopSocketKeepalive(slot)) + } + + inline fun expectCallback(): T { val foundCallback = history.poll(DEFAULT_TIMEOUT_MS) assertTrue(foundCallback is T, "Expected ${T::class} but found $foundCallback") + return foundCallback + } + + fun assertNoCallback() { + assertTrue(waitForIdle(DEFAULT_TIMEOUT_MS), "Handler never became idle") + assertNull(history.peek()) } } @@ -126,7 +225,9 @@ class NetworkAgentTest { addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING) addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) } - val lp = LinkProperties() + val lp = LinkProperties().apply { + addLinkAddress(LinkAddress(LOCAL_IPV4_ADDRESS, 0)) + } val config = NetworkAgentConfig.Builder().build() return TestableNetworkAgent(mHandlerThread.looper, nc, lp, config).also { agentsToCleanUp.add(it) @@ -146,6 +247,10 @@ class NetworkAgentTest { return agent to callback } + private fun createNetworkAgentWithFakeCS() = createNetworkAgent().also { + mFakeConnectivityService.connect(it.registerForTest(Network(FAKE_NET_ID))) + } + @Test fun testConnectAndUnregister() { val (agent, callback) = createConnectedNetworkAgent() @@ -166,4 +271,48 @@ class NetworkAgentTest { agent.expectCallback() agent.unregister() } + + @Test + fun testSocketKeepalive(): Unit = createNetworkAgentWithFakeCS().let { agent -> + val packet = object : KeepalivePacketData( + LOCAL_IPV4_ADDRESS /* srcAddress */, 1234 /* srcPort */, + REMOTE_IPV4_ADDRESS /* dstAddress */, 4567 /* dstPort */, + ByteArray(100 /* size */) { it.toByte() /* init */ }) {} + val slot = 4 + val interval = 37 + + mFakeConnectivityService.sendMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER, + arg1 = slot, obj = packet) + mFakeConnectivityService.sendMessage(CMD_START_SOCKET_KEEPALIVE, + arg1 = slot, arg2 = interval, obj = packet) + + agent.expectCallback().let { + assertEquals(it.slot, slot) + assertEquals(it.packet, packet) + } + agent.expectCallback().let { + assertEquals(it.slot, slot) + assertEquals(it.interval, interval) + assertEquals(it.packet, packet) + } + + agent.assertNoCallback() + + // Check that when the agent sends a keepalive event, ConnectivityService receives the + // expected message. + agent.sendSocketKeepaliveEvent(slot, SocketKeepalive.ERROR_UNSUPPORTED) + mFakeConnectivityService.expectMessage(NetworkAgent.EVENT_SOCKET_KEEPALIVE).let() { + assertEquals(slot, it.arg1) + assertEquals(SocketKeepalive.ERROR_UNSUPPORTED, it.arg2) + } + + mFakeConnectivityService.sendMessage(CMD_STOP_SOCKET_KEEPALIVE, arg1 = slot) + mFakeConnectivityService.sendMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER, arg1 = slot) + agent.expectCallback().let { + assertEquals(it.slot, slot) + } + agent.expectCallback().let { + assertEquals(it.slot, slot) + } + } } From 3f138ef9d3d839b08a283c5498a7470dbf229610 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Mon, 13 Apr 2020 14:27:45 +0900 Subject: [PATCH 0855/1109] Test accept unvalidated Test: this Bug: 139268426 Change-Id: I3326a2119d66e67566fce0268ea4861729b1c64c --- .../src/android/net/cts/NetworkAgentTest.kt | 66 ++++++++++++++++++- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 32f2bfafe2..14f52e1e7c 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -24,7 +24,9 @@ import android.net.LinkProperties import android.net.Network import android.net.NetworkAgent import android.net.NetworkAgent.CMD_ADD_KEEPALIVE_PACKET_FILTER +import android.net.NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT import android.net.NetworkAgent.CMD_REMOVE_KEEPALIVE_PACKET_FILTER +import android.net.NetworkAgent.CMD_SAVE_ACCEPT_UNVALIDATED import android.net.NetworkAgent.CMD_START_SOCKET_KEEPALIVE import android.net.NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE import android.net.NetworkAgentConfig @@ -39,9 +41,11 @@ import android.os.Looper import android.os.Message import android.os.Messenger import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnAddKeepalivePacketFilter +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnAutomaticReconnectDisabled import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnBandwidthUpdateRequested import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnNetworkUnwanted import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnRemoveKeepalivePacketFilter +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnSaveAcceptUnvalidated import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStartSocketKeepalive import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStopSocketKeepalive import androidx.test.InstrumentationRegistry @@ -60,6 +64,7 @@ import org.junit.runner.RunWith import java.net.InetAddress import java.time.Duration import kotlin.test.assertEquals +import kotlin.test.assertFalse import kotlin.test.assertFailsWith import kotlin.test.assertNotNull import kotlin.test.assertNull @@ -123,27 +128,38 @@ class NetworkAgentTest { * only keeps track of one async channel. */ private class FakeConnectivityService(looper: Looper) { + private val CMD_EXPECT_DISCONNECT = 1 + private var disconnectExpected = false private val msgHistory = ArrayTrackRecord().newReadHead() private val asyncChannel = AsyncChannel() private val handler = object : Handler(looper) { override fun handleMessage(msg: Message) { msgHistory.add(Message.obtain(msg)) // make a copy as the original will be recycled when (msg.what) { + CMD_EXPECT_DISCONNECT -> disconnectExpected = true AsyncChannel.CMD_CHANNEL_HALF_CONNECTED -> asyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION) - AsyncChannel.CMD_CHANNEL_DISCONNECT, AsyncChannel.CMD_CHANNEL_DISCONNECTED -> - fail("Agent unexpectedly disconnected") + AsyncChannel.CMD_CHANNEL_DISCONNECTED -> + if (!disconnectExpected) { + fail("Agent unexpectedly disconnected") + } else { + disconnectExpected = false + } } } } fun connect(agentMsngr: Messenger) = asyncChannel.connect(context, handler, agentMsngr) + fun disconnect() = asyncChannel.disconnect() + fun sendMessage(what: Int, arg1: Int = 0, arg2: Int = 0, obj: Any? = null) = asyncChannel.sendMessage(Message(what, arg1, arg2, obj)) fun expectMessage(what: Int) = assertNotNull(msgHistory.poll(DEFAULT_TIMEOUT_MS) { it.what == what }) + + fun willExpectDisconnectOnce() = handler.sendEmptyMessage(CMD_EXPECT_DISCONNECT) } private open class TestableNetworkAgent( @@ -169,6 +185,8 @@ class NetworkAgentTest { val packet: KeepalivePacketData ) : CallbackEntry() data class OnStopSocketKeepalive(val slot: Int) : CallbackEntry() + data class OnSaveAcceptUnvalidated(val accept: Boolean) : CallbackEntry() + object OnAutomaticReconnectDisabled : CallbackEntry() } override fun onBandwidthUpdateRequested() { @@ -199,6 +217,14 @@ class NetworkAgentTest { history.add(OnStopSocketKeepalive(slot)) } + override fun onSaveAcceptUnvalidated(accept: Boolean) { + history.add(OnSaveAcceptUnvalidated(accept)) + } + + override fun onAutomaticReconnectDisabled() { + history.add(OnAutomaticReconnectDisabled) + } + inline fun expectCallback(): T { val foundCallback = history.poll(DEFAULT_TIMEOUT_MS) assertTrue(foundCallback is T, "Expected ${T::class} but found $foundCallback") @@ -315,4 +341,40 @@ class NetworkAgentTest { assertEquals(it.slot, slot) } } + + @Test + fun testSetAcceptUnvalidated() { + createNetworkAgentWithFakeCS().let { agent -> + mFakeConnectivityService.sendMessage(CMD_SAVE_ACCEPT_UNVALIDATED, 1) + agent.expectCallback().let { + assertTrue(it.accept) + } + agent.assertNoCallback() + } + createNetworkAgentWithFakeCS().let { agent -> + mFakeConnectivityService.sendMessage(CMD_SAVE_ACCEPT_UNVALIDATED, 0) + mFakeConnectivityService.sendMessage(CMD_PREVENT_AUTOMATIC_RECONNECT) + agent.expectCallback().let { + assertFalse(it.accept) + } + agent.expectCallback() + agent.assertNoCallback() + // When automatic reconnect is turned off, the network is torn down and + // ConnectivityService sends a disconnect. This in turn causes the agent + // to send a DISCONNECTED message to CS. + mFakeConnectivityService.willExpectDisconnectOnce() + mFakeConnectivityService.disconnect() + mFakeConnectivityService.expectMessage(AsyncChannel.CMD_CHANNEL_DISCONNECTED) + agent.expectCallback() + } + createNetworkAgentWithFakeCS().let { agent -> + mFakeConnectivityService.sendMessage(CMD_PREVENT_AUTOMATIC_RECONNECT) + agent.expectCallback() + agent.assertNoCallback() + mFakeConnectivityService.willExpectDisconnectOnce() + mFakeConnectivityService.disconnect() + mFakeConnectivityService.expectMessage(AsyncChannel.CMD_CHANNEL_DISCONNECTED) + agent.expectCallback() + } + } } From 788d19d376d0373f97e4c1c5cecc5917cdd0b1f7 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Fri, 10 Apr 2020 23:36:48 +0900 Subject: [PATCH 0856/1109] Test validation status Test: this Bug: 139268426 Change-Id: I8499d9da8643cf60c912570e7a2ac2207d662e16 --- .../src/android/net/cts/NetworkAgentTest.kt | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 14f52e1e7c..97a15ef634 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -26,15 +26,20 @@ import android.net.NetworkAgent import android.net.NetworkAgent.CMD_ADD_KEEPALIVE_PACKET_FILTER import android.net.NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT import android.net.NetworkAgent.CMD_REMOVE_KEEPALIVE_PACKET_FILTER +import android.net.NetworkAgent.CMD_REPORT_NETWORK_STATUS import android.net.NetworkAgent.CMD_SAVE_ACCEPT_UNVALIDATED import android.net.NetworkAgent.CMD_START_SOCKET_KEEPALIVE import android.net.NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE +import android.net.NetworkAgent.INVALID_NETWORK +import android.net.NetworkAgent.VALID_NETWORK import android.net.NetworkAgentConfig import android.net.NetworkCapabilities import android.net.NetworkProvider import android.net.NetworkRequest import android.net.SocketKeepalive +import android.net.Uri import android.os.Build +import android.os.Bundle import android.os.Handler import android.os.HandlerThread import android.os.Looper @@ -48,6 +53,7 @@ import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnRem import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnSaveAcceptUnvalidated import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStartSocketKeepalive import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStopSocketKeepalive +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnValidationStatus import androidx.test.InstrumentationRegistry import androidx.test.runner.AndroidJUnit4 import com.android.internal.util.AsyncChannel @@ -187,6 +193,7 @@ class NetworkAgentTest { data class OnStopSocketKeepalive(val slot: Int) : CallbackEntry() data class OnSaveAcceptUnvalidated(val accept: Boolean) : CallbackEntry() object OnAutomaticReconnectDisabled : CallbackEntry() + data class OnValidationStatus(val status: Int, val uri: Uri?) : CallbackEntry() } override fun onBandwidthUpdateRequested() { @@ -225,6 +232,23 @@ class NetworkAgentTest { history.add(OnAutomaticReconnectDisabled) } + override fun onValidationStatus(status: Int, uri: Uri?) { + history.add(OnValidationStatus(status, uri)) + } + + // Expects the initial validation event that always occurs immediately after registering + // a NetworkAgent whose network does not require validation (which test networks do + // not, since they lack the INTERNET capability). It always contains the default argument + // for the URI. + fun expectNoInternetValidationStatus() = expectCallback().let { + assertEquals(it.status, VALID_NETWORK) + // The returned Uri is parsed from the empty string, which means it's an + // instance of the (private) Uri.StringUri. There are no real good ways + // to check this, the least bad is to just convert it to a string and + // make sure it's empty. + assertEquals("", it.uri.toString()) + } + inline fun expectCallback(): T { val foundCallback = history.poll(DEFAULT_TIMEOUT_MS) assertTrue(foundCallback is T, "Expected ${T::class} but found $foundCallback") @@ -281,6 +305,7 @@ class NetworkAgentTest { fun testConnectAndUnregister() { val (agent, callback) = createConnectedNetworkAgent() callback.expectAvailableThenValidatedCallbacks(agent.network) + agent.expectNoInternetValidationStatus() agent.unregister() callback.expectCallback(agent.network) agent.expectCallback() @@ -293,6 +318,7 @@ class NetworkAgentTest { fun testOnBandwidthUpdateRequested() { val (agent, callback) = createConnectedNetworkAgent() callback.expectAvailableThenValidatedCallbacks(agent.network) + agent.expectNoInternetValidationStatus() mCM.requestBandwidthUpdate(agent.network) agent.expectCallback() agent.unregister() @@ -377,4 +403,25 @@ class NetworkAgentTest { agent.expectCallback() } } + + @Test + fun testValidationStatus() = createNetworkAgentWithFakeCS().let { agent -> + val uri = Uri.parse("http://www.google.com") + val bundle = Bundle().apply { + putString(NetworkAgent.REDIRECT_URL_KEY, uri.toString()) + } + mFakeConnectivityService.sendMessage(CMD_REPORT_NETWORK_STATUS, + arg1 = VALID_NETWORK, obj = bundle) + agent.expectCallback().let { + assertEquals(it.status, VALID_NETWORK) + assertEquals(it.uri, uri) + } + + mFakeConnectivityService.sendMessage(CMD_REPORT_NETWORK_STATUS, + arg1 = INVALID_NETWORK, obj = Bundle()) + agent.expectCallback().let { + assertEquals(it.status, INVALID_NETWORK) + assertNull(it.uri) + } + } } From d5f249c24c8824b57ae51d8eab1238580bd7667f Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Sat, 11 Apr 2020 02:47:05 +0900 Subject: [PATCH 0857/1109] Test sendCaps and sendProps Test: this Bug: 139268426 Change-Id: Idefce1174b82668d23c53dd1bf95bc660cb21c28 --- .../src/android/net/cts/NetworkAgentTest.kt | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 97a15ef634..4de3a086ce 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -84,6 +84,7 @@ private const val DEFAULT_TIMEOUT_MS = 5000L // requests filed by the test and should never match normal internet requests. 70 is the default // score of Ethernet networks, it's as good a value as any other. private const val TEST_NETWORK_SCORE = 70 +private const val BETTER_NETWORK_SCORE = 75 private const val FAKE_NET_ID = 1098 private val instrumentation: Instrumentation get() = InstrumentationRegistry.getInstrumentation() @@ -170,8 +171,8 @@ class NetworkAgentTest { private open class TestableNetworkAgent( val looper: Looper, - nc: NetworkCapabilities, - lp: LinkProperties, + val nc: NetworkCapabilities, + val lp: LinkProperties, conf: NetworkAgentConfig ) : NetworkAgent(context, looper, TestableNetworkAgent::class.java.simpleName /* tag */, nc, lp, TEST_NETWORK_SCORE, conf, Provider(context, looper)) { @@ -368,6 +369,25 @@ class NetworkAgentTest { } } + @Test + fun testSendUpdates(): Unit = createConnectedNetworkAgent().let { (agent, callback) -> + callback.expectAvailableThenValidatedCallbacks(agent.network) + agent.expectNoInternetValidationStatus() + val ifaceName = "adhocIface" + val lp = LinkProperties(agent.lp) + lp.setInterfaceName(ifaceName) + agent.sendLinkProperties(lp) + callback.expectLinkPropertiesThat(agent.network) { + it.getInterfaceName() == ifaceName + } + val nc = NetworkCapabilities(agent.nc) + nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED) + agent.sendNetworkCapabilities(nc) + callback.expectCapabilitiesThat(agent.network) { + it.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED) + } + } + @Test fun testSetAcceptUnvalidated() { createNetworkAgentWithFakeCS().let { agent -> From 80ee14e0e7215c04ba26924f5cbaa86551a2b0e1 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Sat, 11 Apr 2020 03:12:42 +0900 Subject: [PATCH 0858/1109] Test sendNetworkScore Test: this Bug: 139268426 Change-Id: I66cea443f0c6aa9235da577817787d764fbd030b --- .../src/android/net/cts/NetworkAgentTest.kt | 66 ++++++++++++++++++- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 4de3a086ce..659950a0db 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -37,6 +37,7 @@ import android.net.NetworkCapabilities import android.net.NetworkProvider import android.net.NetworkRequest import android.net.SocketKeepalive +import android.net.StringNetworkSpecifier import android.net.Uri import android.os.Build import android.os.Bundle @@ -59,8 +60,10 @@ import androidx.test.runner.AndroidJUnit4 import com.android.internal.util.AsyncChannel import com.android.testutils.ArrayTrackRecord import com.android.testutils.DevSdkIgnoreRule +import com.android.testutils.RecorderCallback.CallbackEntry.Available import com.android.testutils.RecorderCallback.CallbackEntry.Lost import com.android.testutils.TestableNetworkCallback +import java.util.UUID import org.junit.After import org.junit.Assert.fail import org.junit.Before @@ -197,6 +200,8 @@ class NetworkAgentTest { data class OnValidationStatus(val status: Int, val uri: Uri?) : CallbackEntry() } + fun getName(): String? = (nc.getNetworkSpecifier() as? StringNetworkSpecifier)?.specifier + override fun onBandwidthUpdateRequested() { history.add(OnBandwidthUpdateRequested) } @@ -267,7 +272,7 @@ class NetworkAgentTest { callbacksToCleanUp.add(callback) } - private fun createNetworkAgent(): TestableNetworkAgent { + private fun createNetworkAgent(name: String? = null): TestableNetworkAgent { val nc = NetworkCapabilities().apply { addTransportType(NetworkCapabilities.TRANSPORT_TEST) removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED) @@ -275,6 +280,9 @@ class NetworkAgentTest { addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED) addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING) addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) + if (null != name) { + setNetworkSpecifier(StringNetworkSpecifier(name)) + } } val lp = LinkProperties().apply { addLinkAddress(LinkAddress(LOCAL_IPV4_ADDRESS, 0)) @@ -285,14 +293,15 @@ class NetworkAgentTest { } } - private fun createConnectedNetworkAgent(): Pair { + private fun createConnectedNetworkAgent(name: String? = null): + Pair { val request: NetworkRequest = NetworkRequest.Builder() .clearCapabilities() .addTransportType(NetworkCapabilities.TRANSPORT_TEST) .build() val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS) requestNetwork(request, callback) - val agent = createNetworkAgent() + val agent = createNetworkAgent(name) agent.register() agent.markConnected() return agent to callback @@ -388,6 +397,57 @@ class NetworkAgentTest { } } + @Test + fun testSendScore() { + // This test will create two networks and check that the one with the stronger + // score wins out for a request that matches them both. + // First create requests to make sure both networks are kept up, using the + // specifier so they are specific to each network + val name1 = UUID.randomUUID().toString() + val name2 = UUID.randomUUID().toString() + val request1 = NetworkRequest.Builder() + .clearCapabilities() + .addTransportType(NetworkCapabilities.TRANSPORT_TEST) + .setNetworkSpecifier(StringNetworkSpecifier(name1)) + .build() + val request2 = NetworkRequest.Builder() + .clearCapabilities() + .addTransportType(NetworkCapabilities.TRANSPORT_TEST) + .setNetworkSpecifier(StringNetworkSpecifier(name2)) + .build() + val callback1 = TestableNetworkCallback() + val callback2 = TestableNetworkCallback() + requestNetwork(request1, callback1) + requestNetwork(request2, callback2) + + // Then file the interesting request + val request = NetworkRequest.Builder() + .clearCapabilities() + .addTransportType(NetworkCapabilities.TRANSPORT_TEST) + .build() + val callback = TestableNetworkCallback() + requestNetwork(request, callback) + + // Connect the first Network + createConnectedNetworkAgent(name1).let { (agent1, _) -> + callback.expectAvailableThenValidatedCallbacks(agent1.network) + // Upgrade agent1 to a better score so that there is no ambiguity when + // agent2 connects that agent1 is still better + agent1.sendNetworkScore(BETTER_NETWORK_SCORE - 1) + // Connect the second agent + createConnectedNetworkAgent(name2).let { (agent2, _) -> + agent2.markConnected() + // The callback should not see anything yet + callback.assertNoCallback(200) + // Now update the score and expect the callback now prefers agent2 + agent2.sendNetworkScore(BETTER_NETWORK_SCORE) + callback.expectCallback(agent2.network) + } + } + + // tearDown() will unregister the requests and agents + } + @Test fun testSetAcceptUnvalidated() { createNetworkAgentWithFakeCS().let { agent -> From da5800cc8687f13f2bcbae1c6e0fbde9a745142d Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Mon, 13 Apr 2020 16:32:39 +0900 Subject: [PATCH 0859/1109] Test Signal thresholds Test: this Bug: 139268426 Change-Id: I136f246d0e3ad6744989e7d6f4f8034cc6674def --- .../src/android/net/cts/NetworkAgentTest.kt | 81 ++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 659950a0db..9d1eee9da9 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -52,6 +52,7 @@ import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnBan import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnNetworkUnwanted import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnRemoveKeepalivePacketFilter import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnSaveAcceptUnvalidated +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnSignalStrengthThresholdsUpdated import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStartSocketKeepalive import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStopSocketKeepalive import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnValidationStatus @@ -65,6 +66,7 @@ import com.android.testutils.RecorderCallback.CallbackEntry.Lost import com.android.testutils.TestableNetworkCallback import java.util.UUID import org.junit.After +import org.junit.Assert.assertArrayEquals import org.junit.Assert.fail import org.junit.Before import org.junit.Rule @@ -83,6 +85,11 @@ import kotlin.test.assertTrue // going to fail, it will simply wait forever, so setting a high timeout lowers the flake ratio // without affecting the run time of successful runs. Thus, set a very high timeout. private const val DEFAULT_TIMEOUT_MS = 5000L +// When waiting for a NetworkCallback to determine there was no timeout, waiting is the +// only possible thing (the relevant handler is the one in the real ConnectivityService, +// and then there is the Binder call), so have a short timeout for this as it will be +// exhausted every time. +private const val NO_CALLBACK_TIMEOUT = 200L // Any legal score (0~99) for the test network would do, as it is going to be kept up by the // requests filed by the test and should never match normal internet requests. 70 is the default // score of Ethernet networks, it's as good a value as any other. @@ -198,6 +205,7 @@ class NetworkAgentTest { data class OnSaveAcceptUnvalidated(val accept: Boolean) : CallbackEntry() object OnAutomaticReconnectDisabled : CallbackEntry() data class OnValidationStatus(val status: Int, val uri: Uri?) : CallbackEntry() + data class OnSignalStrengthThresholdsUpdated(val thresholds: IntArray) : CallbackEntry() } fun getName(): String? = (nc.getNetworkSpecifier() as? StringNetworkSpecifier)?.specifier @@ -238,6 +246,17 @@ class NetworkAgentTest { history.add(OnAutomaticReconnectDisabled) } + override fun onSignalStrengthThresholdsUpdated(thresholds: IntArray) { + history.add(OnSignalStrengthThresholdsUpdated(thresholds)) + } + + fun expectEmptySignalStrengths() { + expectCallback().let { + // intArrayOf() without arguments makes an empty array + assertArrayEquals(intArrayOf(), it.thresholds) + } + } + override fun onValidationStatus(status: Int, uri: Uri?) { history.add(OnValidationStatus(status, uri)) } @@ -272,6 +291,14 @@ class NetworkAgentTest { callbacksToCleanUp.add(callback) } + private fun registerNetworkCallback( + request: NetworkRequest, + callback: TestableNetworkCallback + ) { + mCM.registerNetworkCallback(request, callback) + callbacksToCleanUp.add(callback) + } + private fun createNetworkAgent(name: String? = null): TestableNetworkAgent { val nc = NetworkCapabilities().apply { addTransportType(NetworkCapabilities.TRANSPORT_TEST) @@ -315,6 +342,7 @@ class NetworkAgentTest { fun testConnectAndUnregister() { val (agent, callback) = createConnectedNetworkAgent() callback.expectAvailableThenValidatedCallbacks(agent.network) + agent.expectEmptySignalStrengths() agent.expectNoInternetValidationStatus() agent.unregister() callback.expectCallback(agent.network) @@ -328,12 +356,62 @@ class NetworkAgentTest { fun testOnBandwidthUpdateRequested() { val (agent, callback) = createConnectedNetworkAgent() callback.expectAvailableThenValidatedCallbacks(agent.network) + agent.expectEmptySignalStrengths() agent.expectNoInternetValidationStatus() mCM.requestBandwidthUpdate(agent.network) agent.expectCallback() agent.unregister() } + @Test + fun testSignalStrengthThresholds() { + val thresholds = intArrayOf(30, 50, 65) + val callbacks = thresholds.map { strength -> + val request = NetworkRequest.Builder() + .clearCapabilities() + .addTransportType(NetworkCapabilities.TRANSPORT_TEST) + .setSignalStrength(strength) + .build() + TestableNetworkCallback(DEFAULT_TIMEOUT_MS).also { + registerNetworkCallback(request, it) + } + } + createConnectedNetworkAgent().let { (agent, callback) -> + callback.expectAvailableThenValidatedCallbacks(agent.network) + agent.expectCallback().let { + assertArrayEquals(it.thresholds, thresholds) + } + agent.expectNoInternetValidationStatus() + + // Send signal strength and check that the callbacks are called appropriately. + val nc = NetworkCapabilities(agent.nc) + nc.setSignalStrength(20) + agent.sendNetworkCapabilities(nc) + callbacks.forEach { it.assertNoCallback(NO_CALLBACK_TIMEOUT) } + + nc.setSignalStrength(40) + agent.sendNetworkCapabilities(nc) + callbacks[0].expectAvailableCallbacks(agent.network) + callbacks[1].assertNoCallback(NO_CALLBACK_TIMEOUT) + callbacks[2].assertNoCallback(NO_CALLBACK_TIMEOUT) + + nc.setSignalStrength(80) + agent.sendNetworkCapabilities(nc) + callbacks[0].expectCapabilitiesThat(agent.network) { it.signalStrength == 80 } + callbacks[1].expectAvailableCallbacks(agent.network) + callbacks[2].expectAvailableCallbacks(agent.network) + + nc.setSignalStrength(55) + agent.sendNetworkCapabilities(nc) + callbacks[0].expectCapabilitiesThat(agent.network) { it.signalStrength == 55 } + callbacks[1].expectCapabilitiesThat(agent.network) { it.signalStrength == 55 } + callbacks[2].expectCallback(agent.network) + } + callbacks.forEach { + mCM.unregisterNetworkCallback(it) + } + } + @Test fun testSocketKeepalive(): Unit = createNetworkAgentWithFakeCS().let { agent -> val packet = object : KeepalivePacketData( @@ -381,6 +459,7 @@ class NetworkAgentTest { @Test fun testSendUpdates(): Unit = createConnectedNetworkAgent().let { (agent, callback) -> callback.expectAvailableThenValidatedCallbacks(agent.network) + agent.expectEmptySignalStrengths() agent.expectNoInternetValidationStatus() val ifaceName = "adhocIface" val lp = LinkProperties(agent.lp) @@ -438,7 +517,7 @@ class NetworkAgentTest { createConnectedNetworkAgent(name2).let { (agent2, _) -> agent2.markConnected() // The callback should not see anything yet - callback.assertNoCallback(200) + callback.assertNoCallback(NO_CALLBACK_TIMEOUT) // Now update the score and expect the callback now prefers agent2 agent2.sendNetworkScore(BETTER_NETWORK_SCORE) callback.expectCallback(agent2.network) From 2cef9f7da56fe0a723f930c33baabaaa48078f38 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Mon, 13 Apr 2020 22:18:48 +0900 Subject: [PATCH 0860/1109] Address comments from aosp/1284557 Test: this Bug: 139268426 Change-Id: I5edbff1d7eed2f939ba26f1ebd7ead49ac67b978 --- tests/cts/net/src/android/net/cts/NetworkAgentTest.kt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 9d1eee9da9..89d3dff66c 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -281,7 +281,8 @@ class NetworkAgentTest { } fun assertNoCallback() { - assertTrue(waitForIdle(DEFAULT_TIMEOUT_MS), "Handler never became idle") + assertTrue(waitForIdle(DEFAULT_TIMEOUT_MS), + "Handler didn't became idle after ${DEFAULT_TIMEOUT_MS}ms") assertNull(history.peek()) } } @@ -536,6 +537,10 @@ class NetworkAgentTest { } agent.assertNoCallback() } + } + + @Test + fun testSetAcceptUnvalidatedPreventAutomaticReconnect() { createNetworkAgentWithFakeCS().let { agent -> mFakeConnectivityService.sendMessage(CMD_SAVE_ACCEPT_UNVALIDATED, 0) mFakeConnectivityService.sendMessage(CMD_PREVENT_AUTOMATIC_RECONNECT) @@ -552,6 +557,10 @@ class NetworkAgentTest { mFakeConnectivityService.expectMessage(AsyncChannel.CMD_CHANNEL_DISCONNECTED) agent.expectCallback() } + } + + @Test + fun testPreventAutomaticReconnect() { createNetworkAgentWithFakeCS().let { agent -> mFakeConnectivityService.sendMessage(CMD_PREVENT_AUTOMATIC_RECONNECT) agent.expectCallback() From 6f4d0a0d64f0e035a4b4fb740e1d58599e9f1d25 Mon Sep 17 00:00:00 2001 From: evitayan Date: Thu, 2 Apr 2020 18:19:56 -0700 Subject: [PATCH 0861/1109] Test setting proposal, TS and lifetime for ChildSessionParams Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: If19fb12c92f65d487478fda172acb21f6cfb1717 --- .../ipsec/ike/cts/ChildSessionParamsTest.java | 140 ++++++++++++++++++ .../net/ipsec/ike/cts/IkeTestBase.java | 83 +++++++++++ 2 files changed, 223 insertions(+) create mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java create mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java new file mode 100644 index 0000000000..316355252a --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java @@ -0,0 +1,140 @@ +/* + * 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.ipsec.ike.cts; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import android.net.ipsec.ike.ChildSaProposal; +import android.net.ipsec.ike.ChildSessionParams; +import android.net.ipsec.ike.TransportModeChildSessionParams; +import android.net.ipsec.ike.TunnelModeChildSessionParams; + +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Arrays; +import java.util.concurrent.TimeUnit; + +@RunWith(AndroidJUnit4.class) +public class ChildSessionParamsTest extends IkeTestBase { + private static final int HARD_LIFETIME_SECONDS = (int) TimeUnit.HOURS.toSeconds(3L); + private static final int SOFT_LIFETIME_SECONDS = (int) TimeUnit.HOURS.toSeconds(1L); + + // Random proposal. Content doesn't matter + private final ChildSaProposal mSaProposal = + SaProposalTest.buildChildSaProposalWithCombinedModeCipher(); + + private void verifyTunnelModeChildParamsWithDefaultValues(ChildSessionParams childParams) { + assertTrue(childParams instanceof TunnelModeChildSessionParams); + verifyChildParamsWithDefaultValues(childParams); + } + + private void verifyTunnelModeChildParamsWithCustomizedValues(ChildSessionParams childParams) { + assertTrue(childParams instanceof TunnelModeChildSessionParams); + verifyChildParamsWithCustomizedValues(childParams); + } + + private void verifyTransportModeChildParamsWithDefaultValues(ChildSessionParams childParams) { + assertTrue(childParams instanceof TransportModeChildSessionParams); + verifyChildParamsWithDefaultValues(childParams); + } + + private void verifyTransportModeChildParamsWithCustomizedValues( + ChildSessionParams childParams) { + assertTrue(childParams instanceof TransportModeChildSessionParams); + verifyChildParamsWithCustomizedValues(childParams); + } + + private void verifyChildParamsWithDefaultValues(ChildSessionParams childParams) { + assertEquals(Arrays.asList(mSaProposal), childParams.getSaProposals()); + + // Do not do assertEquals to the default values to be avoid being a change-detector test + assertTrue(childParams.getHardLifetimeSeconds() > childParams.getSoftLifetimeSeconds()); + assertTrue(childParams.getSoftLifetimeSeconds() > 0); + + assertEquals( + Arrays.asList(DEFAULT_V4_TS, DEFAULT_V6_TS), + childParams.getInboundTrafficSelectors()); + assertEquals( + Arrays.asList(DEFAULT_V4_TS, DEFAULT_V6_TS), + childParams.getOutboundTrafficSelectors()); + } + + private void verifyChildParamsWithCustomizedValues(ChildSessionParams childParams) { + assertEquals(Arrays.asList(mSaProposal), childParams.getSaProposals()); + + assertEquals(HARD_LIFETIME_SECONDS, childParams.getHardLifetimeSeconds()); + assertEquals(SOFT_LIFETIME_SECONDS, childParams.getSoftLifetimeSeconds()); + + assertEquals( + Arrays.asList(INBOUND_V4_TS, INBOUND_V6_TS), + childParams.getInboundTrafficSelectors()); + assertEquals( + Arrays.asList(OUTBOUND_V4_TS, OUTBOUND_V6_TS), + childParams.getOutboundTrafficSelectors()); + } + + @Test + public void testBuildTransportModeParamsWithDefaultValues() { + TransportModeChildSessionParams childParams = + new TransportModeChildSessionParams.Builder().addSaProposal(mSaProposal).build(); + + verifyTransportModeChildParamsWithDefaultValues(childParams); + } + + @Test + public void testBuildTunnelModeParamsWithDefaultValues() { + TunnelModeChildSessionParams childParams = + new TunnelModeChildSessionParams.Builder().addSaProposal(mSaProposal).build(); + + verifyTunnelModeChildParamsWithDefaultValues(childParams); + assertTrue(childParams.getConfigurationRequests().isEmpty()); + } + + @Test + public void testBuildTransportModeParamsWithCustomizedValues() { + TransportModeChildSessionParams childParams = + new TransportModeChildSessionParams.Builder() + .addSaProposal(mSaProposal) + .setLifetimeSeconds(HARD_LIFETIME_SECONDS, SOFT_LIFETIME_SECONDS) + .addInboundTrafficSelectors(INBOUND_V4_TS) + .addInboundTrafficSelectors(INBOUND_V6_TS) + .addOutboundTrafficSelectors(OUTBOUND_V4_TS) + .addOutboundTrafficSelectors(OUTBOUND_V6_TS) + .build(); + + verifyTransportModeChildParamsWithCustomizedValues(childParams); + } + + @Test + public void testBuildTunnelModeParamsWithCustomizedValues() { + TunnelModeChildSessionParams childParams = + new TunnelModeChildSessionParams.Builder() + .addSaProposal(mSaProposal) + .setLifetimeSeconds(HARD_LIFETIME_SECONDS, SOFT_LIFETIME_SECONDS) + .addInboundTrafficSelectors(INBOUND_V4_TS) + .addInboundTrafficSelectors(INBOUND_V6_TS) + .addOutboundTrafficSelectors(OUTBOUND_V4_TS) + .addOutboundTrafficSelectors(OUTBOUND_V6_TS) + .build(); + + verifyTunnelModeChildParamsWithCustomizedValues(childParams); + } +} diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java new file mode 100644 index 0000000000..d4b431e837 --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.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.ipsec.ike.cts; + +import android.net.InetAddresses; +import android.net.ipsec.ike.IkeTrafficSelector; + +import java.net.Inet4Address; +import java.net.Inet6Address; + +/** Shared parameters and util methods for testing different components of IKE */ +abstract class IkeTestBase { + private static final int MIN_PORT = 0; + private static final int MAX_PORT = 65535; + private static final int INBOUND_TS_START_PORT = MIN_PORT; + private static final int INBOUND_TS_END_PORT = 65520; + private static final int OUTBOUND_TS_START_PORT = 16; + private static final int OUTBOUND_TS_END_PORT = MAX_PORT; + + static final int IP4_PREFIX_LEN = 32; + static final int IP6_PREFIX_LEN = 64; + + static final Inet4Address IPV4_ADDRESS_LOCAL = + (Inet4Address) (InetAddresses.parseNumericAddress("192.0.2.100")); + static final Inet4Address IPV4_ADDRESS_REMOTE = + (Inet4Address) (InetAddresses.parseNumericAddress("198.51.100.100")); + static final Inet6Address IPV6_ADDRESS_LOCAL = + (Inet6Address) (InetAddresses.parseNumericAddress("2001:db8::100")); + static final Inet6Address IPV6_ADDRESS_REMOTE = + (Inet6Address) (InetAddresses.parseNumericAddress("2001:db8:255::100")); + + static final IkeTrafficSelector DEFAULT_V4_TS = + new IkeTrafficSelector( + MIN_PORT, + MAX_PORT, + InetAddresses.parseNumericAddress("0.0.0.0"), + InetAddresses.parseNumericAddress("255.255.255.255")); + static final IkeTrafficSelector DEFAULT_V6_TS = + new IkeTrafficSelector( + MIN_PORT, + MAX_PORT, + InetAddresses.parseNumericAddress("::"), + InetAddresses.parseNumericAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")); + static final IkeTrafficSelector INBOUND_V4_TS = + new IkeTrafficSelector( + INBOUND_TS_START_PORT, + INBOUND_TS_END_PORT, + InetAddresses.parseNumericAddress("192.0.2.10"), + InetAddresses.parseNumericAddress("192.0.2.20")); + static final IkeTrafficSelector OUTBOUND_V4_TS = + new IkeTrafficSelector( + OUTBOUND_TS_START_PORT, + OUTBOUND_TS_END_PORT, + InetAddresses.parseNumericAddress("198.51.100.0"), + InetAddresses.parseNumericAddress("198.51.100.255")); + + static final IkeTrafficSelector INBOUND_V6_TS = + new IkeTrafficSelector( + INBOUND_TS_START_PORT, + INBOUND_TS_END_PORT, + InetAddresses.parseNumericAddress("2001:db8::10"), + InetAddresses.parseNumericAddress("2001:db8::128")); + static final IkeTrafficSelector OUTBOUND_V6_TS = + new IkeTrafficSelector( + OUTBOUND_TS_START_PORT, + OUTBOUND_TS_END_PORT, + InetAddresses.parseNumericAddress("2001:db8:255::64"), + InetAddresses.parseNumericAddress("2001:db8:255::255")); +} From 5eaf009a929d4f7a4bdd1f53767e6ec95cb0cee4 Mon Sep 17 00:00:00 2001 From: Treehugger Robot Date: Mon, 13 Apr 2020 15:02:00 +0000 Subject: [PATCH 0862/1109] Add tethering CTS owners. Test: none Bug: 153921802 Change-Id: I0651e7fa2a705b553f2d24ca573936c28591bb84 Merged-In: I552b3bf8d79c4e4480396edc201b51ec5901b87b (cherry picked from commit 7f210a41827742b1448a82d093a651898f40ad2e) --- tests/cts/tethering/OWNERS | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 tests/cts/tethering/OWNERS diff --git a/tests/cts/tethering/OWNERS b/tests/cts/tethering/OWNERS new file mode 100644 index 0000000000..cd6abeb6e8 --- /dev/null +++ b/tests/cts/tethering/OWNERS @@ -0,0 +1,4 @@ +# Bug component: 31808 +lorenzo@google.com +satk@google.com + From 524f93613fdb5f8ad180681be593133cf77474fb Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Sun, 12 Apr 2020 14:53:45 +0000 Subject: [PATCH 0863/1109] Test onBandwidthUpdateRequested Test: this Bug: 139268426 Change-Id: I5f4b42dc68fdd13f26e59b4e2217d39dcee8f2a1 Merged-In: I427ae6ac2c8910683e47f503ba71a05e35507571 (cherry picked from commit bbe53cd710440468520d5d5713eaa503b6c9d8b9, aosp/1258136) --- .../net/src/android/net/cts/NetworkAgentTest.kt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 85c94e7db2..2fdd5fb201 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -24,6 +24,7 @@ import android.net.NetworkAgentConfig import android.net.NetworkCapabilities import android.net.NetworkProvider import android.net.NetworkRequest +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnBandwidthUpdateRequested import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnNetworkUnwanted import android.os.Build import android.os.HandlerThread @@ -88,9 +89,15 @@ class NetworkAgentTest { private val history = ArrayTrackRecord().newReadHead() sealed class CallbackEntry { + object OnBandwidthUpdateRequested : CallbackEntry() object OnNetworkUnwanted : CallbackEntry() } + override fun onBandwidthUpdateRequested() { + super.onBandwidthUpdateRequested() + history.add(OnBandwidthUpdateRequested) + } + override fun onNetworkUnwanted() { super.onNetworkUnwanted() history.add(OnNetworkUnwanted) @@ -139,4 +146,13 @@ class NetworkAgentTest { agent.register() } } + + @Test + fun testOnBandwidthUpdateRequested() { + val (agent, callback) = createConnectedNetworkAgent() + callback.expectAvailableThenValidatedCallbacks(agent.network) + mCM.requestBandwidthUpdate(agent.network) + agent.expectCallback() + agent.unregister() + } } From 7f1975092f146bc53a00d20c93556ca2f755d338 Mon Sep 17 00:00:00 2001 From: paulhu Date: Fri, 10 Apr 2020 15:34:04 +0800 Subject: [PATCH 0864/1109] Add TetheringEventCallback CTS test Test APIs below: onOffloadStatusChanged(int) Bug: 153619369 Test: atests CtsTetheringTest Change-Id: Ia7edd0d3d8184e30373ac8b657299107ff9b4c1e --- .../tethering/cts/TetheringManagerTest.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java index b132982e1a..718b4f8892 100644 --- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java +++ b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java @@ -15,6 +15,9 @@ */ package android.tethering.test; +import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED; +import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED; +import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED; import static android.net.TetheringManager.TETHERING_USB; import static android.net.TetheringManager.TETHERING_WIFI; @@ -273,6 +276,7 @@ public class TetheringManagerTest { ON_TETHERED_IFACES, ON_ERROR, ON_CLIENTS, + ON_OFFLOAD_STATUS, }; public static class CallbackValue { @@ -330,6 +334,11 @@ public class TetheringManagerTest { mCallbacks.add(new CallbackValue(CallbackType.ON_CLIENTS, clients, 0)); } + @Override + public void onOffloadStatusChanged(int status) { + mCallbacks.add(new CallbackValue(CallbackType.ON_OFFLOAD_STATUS, status, 0)); + } + public CallbackValue pollCallback() { try { return mCallbacks.poll(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS); @@ -382,6 +391,17 @@ public class TetheringManagerTest { } } + public void expectOneOfOffloadStatusChanged(int... offloadStatuses) { + while (true) { + final CallbackValue cv = pollCallback(); + if (cv == null) fail("No expected offload status change callback"); + if (cv.callbackType != CallbackType.ON_OFFLOAD_STATUS) continue; + + final int status = (int) cv.callbackParam; + for (int offloadStatus : offloadStatuses) if (offloadStatus == status) return; + } + } + public TetheringInterfaceRegexps getTetheringInterfaceRegexps() { return mTetherableRegex; } @@ -403,6 +423,7 @@ public class TetheringManagerTest { mTM.registerTetheringEventCallback(c -> c.run(), tetherEventCallback); tetherEventCallback.expectCallbackStarted(); + tetherEventCallback.expectOneOfOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); final TetheringInterfaceRegexps tetherableRegexs = tetherEventCallback.getTetheringInterfaceRegexps(); @@ -422,10 +443,14 @@ public class TetheringManagerTest { } tetherEventCallback.expectTetheredInterfacesChanged(wifiRegexs); + tetherEventCallback.expectOneOfOffloadStatusChanged( + TETHER_HARDWARE_OFFLOAD_STARTED, + TETHER_HARDWARE_OFFLOAD_FAILED); mTM.stopTethering(TETHERING_WIFI); tetherEventCallback.expectTetheredInterfacesChanged(null); + tetherEventCallback.expectOneOfOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); mTM.unregisterTetheringEventCallback(tetherEventCallback); } } From 9849d899e82ca196032c5c212e09c3db25f6e005 Mon Sep 17 00:00:00 2001 From: Paul Hu Date: Tue, 14 Apr 2020 10:04:07 +0000 Subject: [PATCH 0865/1109] Add TetherableInterfaceRegexps CTS tests Test APIs below: getTetherableWifiRegexs() getTetherableUsbRegexs() getTetherableBluetoothRegexs() TetheringInterfaceRegexps.getTetherableWifiRegexs() TetheringInterfaceRegexps.getTetherableUsbRegexs() TetheringInterfaceRegexps.getTetherableBluetoothRegexs() Bug: 152737526 Test: atest CtsTetheringTest Change-Id: Icb7d8718d0aa6574b4c9dd1e17d7feb300fad2aa Merged-In: Icb7d8718d0aa6574b4c9dd1e17d7feb300fad2aa (cherry picked from commit 9f11d903a1d8cc6705481360bae4fb97cfbb966d, aosp/1271822) --- .../tethering/cts/TetheringManagerTest.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java index b132982e1a..193a5dc3a4 100644 --- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java +++ b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java @@ -428,4 +428,30 @@ public class TetheringManagerTest { tetherEventCallback.expectTetheredInterfacesChanged(null); mTM.unregisterTetheringEventCallback(tetherEventCallback); } + + @Test + public void testGetTetherableInterfaceRegexps() { + if (!mTM.isTetheringSupported()) return; + + final TestTetheringEventCallback tetherEventCallback = new TestTetheringEventCallback(); + mTM.registerTetheringEventCallback(c -> c.run(), tetherEventCallback); + tetherEventCallback.expectCallbackStarted(); + + final TetheringInterfaceRegexps tetherableRegexs = + tetherEventCallback.getTetheringInterfaceRegexps(); + final List wifiRegexs = tetherableRegexs.getTetherableWifiRegexs(); + final List usbRegexs = tetherableRegexs.getTetherableUsbRegexs(); + final List btRegexs = tetherableRegexs.getTetherableBluetoothRegexs(); + + assertEquals(wifiRegexs, Arrays.asList(mTM.getTetherableWifiRegexs())); + assertEquals(usbRegexs, Arrays.asList(mTM.getTetherableUsbRegexs())); + assertEquals(btRegexs, Arrays.asList(mTM.getTetherableBluetoothRegexs())); + + //Verify that any of interface name should only contain in one array. + wifiRegexs.forEach(s -> assertFalse(usbRegexs.contains(s))); + wifiRegexs.forEach(s -> assertFalse(btRegexs.contains(s))); + usbRegexs.forEach(s -> assertFalse(btRegexs.contains(s))); + + mTM.unregisterTetheringEventCallback(tetherEventCallback); + } } From cb778b120003ae76aaff9b0d2574a570089a3d16 Mon Sep 17 00:00:00 2001 From: evitayan Date: Tue, 7 Apr 2020 13:07:14 -0700 Subject: [PATCH 0866/1109] Test setting config requests for TunnelModeChildSessionParams Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: Ib3e803159cdf42a8655c0e4d0f22faeabe161c4c --- .../ipsec/ike/cts/ChildSessionParamsTest.java | 90 +++++++++++++++++++ .../net/ipsec/ike/cts/IkeTestBase.java | 37 ++++++++ 2 files changed, 127 insertions(+) diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java index 316355252a..7fb1b6dc43 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java @@ -16,20 +16,36 @@ package android.net.ipsec.ike.cts; +import static android.system.OsConstants.AF_INET; +import static android.system.OsConstants.AF_INET6; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import android.net.LinkAddress; import android.net.ipsec.ike.ChildSaProposal; import android.net.ipsec.ike.ChildSessionParams; import android.net.ipsec.ike.TransportModeChildSessionParams; import android.net.ipsec.ike.TunnelModeChildSessionParams; +import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv4Address; +import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv4DhcpServer; +import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv4DnsServer; +import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv4Netmask; +import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv6Address; +import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv6DnsServer; +import android.net.ipsec.ike.TunnelModeChildSessionParams.TunnelModeChildConfigRequest; import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; +import java.net.Inet4Address; import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) @@ -137,4 +153,78 @@ public class ChildSessionParamsTest extends IkeTestBase { verifyTunnelModeChildParamsWithCustomizedValues(childParams); } + + @Test + public void testBuildChildSessionParamsWithConfigReq() { + TunnelModeChildSessionParams childParams = + new TunnelModeChildSessionParams.Builder() + .addSaProposal(mSaProposal) + .addInternalAddressRequest(AF_INET) + .addInternalAddressRequest(AF_INET6) + .addInternalAddressRequest(AF_INET6) + .addInternalAddressRequest(IPV4_ADDRESS_REMOTE) + .addInternalAddressRequest(IPV6_ADDRESS_REMOTE, IP6_PREFIX_LEN) + .addInternalDnsServerRequest(AF_INET) + .addInternalDnsServerRequest(AF_INET6) + .addInternalDhcpServerRequest(AF_INET) + .addInternalDhcpServerRequest(AF_INET) + .build(); + + verifyTunnelModeChildParamsWithDefaultValues(childParams); + + // Verify config request types and number of requests for each type + Map, Integer> expectedAttributeCounts = + new HashMap<>(); + expectedAttributeCounts.put(ConfigRequestIpv4Address.class, 2); + expectedAttributeCounts.put(ConfigRequestIpv6Address.class, 3); + expectedAttributeCounts.put(ConfigRequestIpv4Netmask.class, 1); + expectedAttributeCounts.put(ConfigRequestIpv4DnsServer.class, 1); + expectedAttributeCounts.put(ConfigRequestIpv6DnsServer.class, 1); + expectedAttributeCounts.put(ConfigRequestIpv4DhcpServer.class, 2); + verifyConfigRequestTypes(expectedAttributeCounts, childParams.getConfigurationRequests()); + + // Verify specific IPv4 address request + Set expectedV4Addresses = new HashSet<>(); + expectedV4Addresses.add(IPV4_ADDRESS_REMOTE); + verifySpecificV4AddrConfigReq(expectedV4Addresses, childParams); + + // Verify specific IPv6 address request + Set expectedV6Addresses = new HashSet<>(); + expectedV6Addresses.add(new LinkAddress(IPV6_ADDRESS_REMOTE, IP6_PREFIX_LEN)); + verifySpecificV6AddrConfigReq(expectedV6Addresses, childParams); + } + + protected void verifySpecificV4AddrConfigReq( + Set expectedAddresses, TunnelModeChildSessionParams childParams) { + for (TunnelModeChildConfigRequest req : childParams.getConfigurationRequests()) { + if (req instanceof ConfigRequestIpv4Address + && ((ConfigRequestIpv4Address) req).getAddress() != null) { + Inet4Address address = ((ConfigRequestIpv4Address) req).getAddress(); + + // Fail if expectedAddresses does not contain this address + assertTrue(expectedAddresses.remove(address)); + } + } + + // Fail if any expected address is not found in result + assertTrue(expectedAddresses.isEmpty()); + } + + protected void verifySpecificV6AddrConfigReq( + Set expectedAddresses, TunnelModeChildSessionParams childParams) { + for (TunnelModeChildConfigRequest req : childParams.getConfigurationRequests()) { + if (req instanceof ConfigRequestIpv6Address + && ((ConfigRequestIpv6Address) req).getAddress() != null) { + ConfigRequestIpv6Address ipv6AddrReq = (ConfigRequestIpv6Address) req; + + // Fail if expectedAddresses does not contain this address + LinkAddress address = + new LinkAddress(ipv6AddrReq.getAddress(), ipv6AddrReq.getPrefixLength()); + assertTrue(expectedAddresses.remove(address)); + } + } + + // Fail if any expected address is not found in result + assertTrue(expectedAddresses.isEmpty()); + } } diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java index d4b431e837..d3aa8d03d5 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java @@ -16,11 +16,17 @@ package android.net.ipsec.ike.cts; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + import android.net.InetAddresses; import android.net.ipsec.ike.IkeTrafficSelector; import java.net.Inet4Address; import java.net.Inet6Address; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** Shared parameters and util methods for testing different components of IKE */ abstract class IkeTestBase { @@ -80,4 +86,35 @@ abstract class IkeTestBase { OUTBOUND_TS_END_PORT, InetAddresses.parseNumericAddress("2001:db8:255::64"), InetAddresses.parseNumericAddress("2001:db8:255::255")); + + // Verify Config requests in TunnelModeChildSessionParams and IkeSessionParams + void verifyConfigRequestTypes( + Map, Integer> expectedReqCntMap, List resultReqList) { + Map, Integer> resultReqCntMap = new HashMap<>(); + + // Verify that every config request type in resultReqList is expected, and build + // resultReqCntMap at the same time + for (T resultReq : resultReqList) { + boolean isResultReqExpected = false; + + for (Class expectedReqInterface : expectedReqCntMap.keySet()) { + if (expectedReqInterface.isInstance(resultReq)) { + isResultReqExpected = true; + + resultReqCntMap.put( + expectedReqInterface, + resultReqCntMap.getOrDefault(expectedReqInterface, 0) + 1); + } + } + + if (!isResultReqExpected) { + fail("Failed due to unexpected config request " + resultReq); + } + } + + assertEquals(expectedReqCntMap, resultReqCntMap); + + // TODO: Think of a neat way to validate both counts and values in this method. Probably can + // build Runnables as validators for count and values. + } } From 643abc73d93c0fcc3b316b0b56bc371ebdf47932 Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Mon, 13 Apr 2020 22:39:21 -0700 Subject: [PATCH 0867/1109] Ensure location is enabled before getting SSID. When location is disabled, Wi-Fi scan results and SSID are not available to apps. Fixes: 153850762 Fixes: 153396893 Test: atest hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java Change-Id: I05285811d7131e116d5e1d072137ed2cf9576d05 --- tests/cts/hostside/AndroidTest.xml | 1 + ...ractRestrictBackgroundNetworkTestCase.java | 31 ---------------- .../net/hostside/NetworkPolicyTestUtils.java | 35 +++++++++++++++++-- 3 files changed, 33 insertions(+), 34 deletions(-) diff --git a/tests/cts/hostside/AndroidTest.xml b/tests/cts/hostside/AndroidTest.xml index 7cc0dd19cc..b7fefaf3b5 100644 --- a/tests/cts/hostside/AndroidTest.xml +++ b/tests/cts/hostside/AndroidTest.xml @@ -20,6 +20,7 @@

    Caller MUST have MANAGE_TEST_NETWORKS permission to use this method. + * + * @param connMgr ConnectivityManager to request network. + * @param testNetworkMgr TestNetworkManager to set up test network. + * @param ifname the name of the interface to be used for the Network LinkProperties. + * @param binder a binder object guarding the lifecycle of this test network. + * @return TestNetworkCallback to retrieve the test network. + * @throws RemoteException if test network setup failed. + * @see android.net.TestNetworkManager + */ + public static TestNetworkCallback setupAndGetTestNetwork( + ConnectivityManager connMgr, + TestNetworkManager testNetworkMgr, + String ifname, + IBinder binder) + throws RemoteException { + NetworkRequest nr = + new NetworkRequest.Builder() + .addTransportType(TRANSPORT_TEST) + .removeCapability(NET_CAPABILITY_TRUSTED) + .removeCapability(NET_CAPABILITY_NOT_VPN) + .setNetworkSpecifier(ifname) + .build(); + + TestNetworkCallback cb = new TestNetworkCallback(); + connMgr.requestNetwork(nr, cb); + + // Setup the test network after network request is filed to prevent Network from being + // reaped due to no requests matching it. + testNetworkMgr.setupTestNetwork(ifname, binder); + + return cb; + } +} From 6fe3606924a9b482db264bd412dedee435592f2b Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Sun, 12 Apr 2020 21:34:11 +0900 Subject: [PATCH 0869/1109] Increase test independence If a test fails without unregistering an agent, other tests will see their requests match the old agent. That means any test failing will fail all subsequent tests, which is not very helpful. Solve this by making sure the agents are unregistered before the test ends. Also ensure the requests are unregistered. Test: NetworkAgentTest Bug: 139268426 Change-Id: If183d78298aa2a0bcae9e2487199dee14014cdfb Merged-In: I2c167803d478d31fd85dc6e6e621f35d36c68fb4 (cherry-picked from aosp/1284556) --- .../src/android/net/cts/NetworkAgentTest.kt | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 2fdd5fb201..d0e3023db6 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -67,6 +67,9 @@ class NetworkAgentTest { private class Provider(context: Context, looper: Looper) : NetworkProvider(context, looper, "NetworkAgentTest NetworkProvider") + private val agentsToCleanUp = mutableListOf() + private val callbacksToCleanUp = mutableListOf() + @Before fun setUp() { instrumentation.getUiAutomation().adoptShellPermissionIdentity() @@ -75,11 +78,13 @@ class NetworkAgentTest { @After fun tearDown() { + agentsToCleanUp.forEach { it.unregister() } + callbacksToCleanUp.forEach { mCM.unregisterNetworkCallback(it) } mHandlerThread.quitSafely() instrumentation.getUiAutomation().dropShellPermissionIdentity() } - internal class TestableNetworkAgent( + private class TestableNetworkAgent( looper: Looper, nc: NetworkCapabilities, lp: LinkProperties, @@ -94,12 +99,10 @@ class NetworkAgentTest { } override fun onBandwidthUpdateRequested() { - super.onBandwidthUpdateRequested() history.add(OnBandwidthUpdateRequested) } override fun onNetworkUnwanted() { - super.onNetworkUnwanted() history.add(OnNetworkUnwanted) } @@ -109,6 +112,11 @@ class NetworkAgentTest { } } + private fun requestNetwork(request: NetworkRequest, callback: TestableNetworkCallback) { + mCM.requestNetwork(request, callback) + callbacksToCleanUp.add(callback) + } + private fun createNetworkAgent(): TestableNetworkAgent { val nc = NetworkCapabilities().apply { addTransportType(NetworkCapabilities.TRANSPORT_TEST) @@ -120,7 +128,9 @@ class NetworkAgentTest { } val lp = LinkProperties() val config = NetworkAgentConfig.Builder().build() - return TestableNetworkAgent(mHandlerThread.looper, nc, lp, config) + return TestableNetworkAgent(mHandlerThread.looper, nc, lp, config).also { + agentsToCleanUp.add(it) + } } private fun createConnectedNetworkAgent(): Pair { @@ -129,8 +139,9 @@ class NetworkAgentTest { .addTransportType(NetworkCapabilities.TRANSPORT_TEST) .build() val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS) - mCM.requestNetwork(request, callback) - val agent = createNetworkAgent().also { it.register() } + requestNetwork(request, callback) + val agent = createNetworkAgent() + agent.register() agent.markConnected() return agent to callback } From dce3e15cd347ca563f705b1d5f01c8a7cc70d509 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Fri, 13 Mar 2020 21:10:56 +0900 Subject: [PATCH 0870/1109] Test onStartSocketKeepalive Test: this Bug: 139268426 Change-Id: I26f68fdf9b687a2d87c971525b1cd2c48d4579bb Merged-In: I4e251fa0203a1888badef9ed90495fe8b3340a1c (cherry-picked aosp/1258137) --- .../src/android/net/cts/NetworkAgentTest.kt | 161 +++++++++++++++++- 1 file changed, 155 insertions(+), 6 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index d0e3023db6..32f2bfafe2 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -18,29 +18,51 @@ package android.net.cts import android.app.Instrumentation import android.content.Context import android.net.ConnectivityManager +import android.net.KeepalivePacketData +import android.net.LinkAddress import android.net.LinkProperties +import android.net.Network import android.net.NetworkAgent +import android.net.NetworkAgent.CMD_ADD_KEEPALIVE_PACKET_FILTER +import android.net.NetworkAgent.CMD_REMOVE_KEEPALIVE_PACKET_FILTER +import android.net.NetworkAgent.CMD_START_SOCKET_KEEPALIVE +import android.net.NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE import android.net.NetworkAgentConfig import android.net.NetworkCapabilities import android.net.NetworkProvider import android.net.NetworkRequest -import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnBandwidthUpdateRequested -import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnNetworkUnwanted +import android.net.SocketKeepalive import android.os.Build +import android.os.Handler import android.os.HandlerThread import android.os.Looper +import android.os.Message +import android.os.Messenger +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnAddKeepalivePacketFilter +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnBandwidthUpdateRequested +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnNetworkUnwanted +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnRemoveKeepalivePacketFilter +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStartSocketKeepalive +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStopSocketKeepalive import androidx.test.InstrumentationRegistry import androidx.test.runner.AndroidJUnit4 +import com.android.internal.util.AsyncChannel import com.android.testutils.ArrayTrackRecord import com.android.testutils.DevSdkIgnoreRule import com.android.testutils.RecorderCallback.CallbackEntry.Lost import com.android.testutils.TestableNetworkCallback import org.junit.After +import org.junit.Assert.fail import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import java.net.InetAddress +import java.time.Duration +import kotlin.test.assertEquals import kotlin.test.assertFailsWith +import kotlin.test.assertNotNull +import kotlin.test.assertNull import kotlin.test.assertTrue // This test doesn't really have a constraint on how fast the methods should return. If it's @@ -51,18 +73,29 @@ private const val DEFAULT_TIMEOUT_MS = 5000L // requests filed by the test and should never match normal internet requests. 70 is the default // score of Ethernet networks, it's as good a value as any other. private const val TEST_NETWORK_SCORE = 70 +private const val FAKE_NET_ID = 1098 private val instrumentation: Instrumentation get() = InstrumentationRegistry.getInstrumentation() private val context: Context get() = InstrumentationRegistry.getContext() +private fun Message(what: Int, arg1: Int, arg2: Int, obj: Any?) = Message.obtain().also { + it.what = what + it.arg1 = arg1 + it.arg2 = arg2 + it.obj = obj +} @RunWith(AndroidJUnit4::class) class NetworkAgentTest { @Rule @JvmField val ignoreRule = DevSdkIgnoreRule(ignoreClassUpTo = Build.VERSION_CODES.Q) + private val LOCAL_IPV4_ADDRESS = InetAddress.parseNumericAddress("192.0.2.1") + private val REMOTE_IPV4_ADDRESS = InetAddress.parseNumericAddress("192.0.2.2") + private val mCM = context.getSystemService(ConnectivityManager::class.java) private val mHandlerThread = HandlerThread("${javaClass.simpleName} handler thread") + private val mFakeConnectivityService by lazy { FakeConnectivityService(mHandlerThread.looper) } private class Provider(context: Context, looper: Looper) : NetworkProvider(context, looper, "NetworkAgentTest NetworkProvider") @@ -84,8 +117,37 @@ class NetworkAgentTest { instrumentation.getUiAutomation().dropShellPermissionIdentity() } - private class TestableNetworkAgent( - looper: Looper, + /** + * A fake that helps simulating ConnectivityService talking to a harnessed agent. + * This fake only supports speaking to one harnessed agent at a time because it + * only keeps track of one async channel. + */ + private class FakeConnectivityService(looper: Looper) { + private val msgHistory = ArrayTrackRecord().newReadHead() + private val asyncChannel = AsyncChannel() + private val handler = object : Handler(looper) { + override fun handleMessage(msg: Message) { + msgHistory.add(Message.obtain(msg)) // make a copy as the original will be recycled + when (msg.what) { + AsyncChannel.CMD_CHANNEL_HALF_CONNECTED -> + asyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION) + AsyncChannel.CMD_CHANNEL_DISCONNECT, AsyncChannel.CMD_CHANNEL_DISCONNECTED -> + fail("Agent unexpectedly disconnected") + } + } + } + + fun connect(agentMsngr: Messenger) = asyncChannel.connect(context, handler, agentMsngr) + + fun sendMessage(what: Int, arg1: Int = 0, arg2: Int = 0, obj: Any? = null) = + asyncChannel.sendMessage(Message(what, arg1, arg2, obj)) + + fun expectMessage(what: Int) = + assertNotNull(msgHistory.poll(DEFAULT_TIMEOUT_MS) { it.what == what }) + } + + private open class TestableNetworkAgent( + val looper: Looper, nc: NetworkCapabilities, lp: LinkProperties, conf: NetworkAgentConfig @@ -96,6 +158,17 @@ class NetworkAgentTest { sealed class CallbackEntry { object OnBandwidthUpdateRequested : CallbackEntry() object OnNetworkUnwanted : CallbackEntry() + data class OnAddKeepalivePacketFilter( + val slot: Int, + val packet: KeepalivePacketData + ) : CallbackEntry() + data class OnRemoveKeepalivePacketFilter(val slot: Int) : CallbackEntry() + data class OnStartSocketKeepalive( + val slot: Int, + val interval: Int, + val packet: KeepalivePacketData + ) : CallbackEntry() + data class OnStopSocketKeepalive(val slot: Int) : CallbackEntry() } override fun onBandwidthUpdateRequested() { @@ -106,9 +179,35 @@ class NetworkAgentTest { history.add(OnNetworkUnwanted) } - inline fun expectCallback() { + override fun onAddKeepalivePacketFilter(slot: Int, packet: KeepalivePacketData) { + history.add(OnAddKeepalivePacketFilter(slot, packet)) + } + + override fun onRemoveKeepalivePacketFilter(slot: Int) { + history.add(OnRemoveKeepalivePacketFilter(slot)) + } + + override fun onStartSocketKeepalive( + slot: Int, + interval: Duration, + packet: KeepalivePacketData + ) { + history.add(OnStartSocketKeepalive(slot, interval.seconds.toInt(), packet)) + } + + override fun onStopSocketKeepalive(slot: Int) { + history.add(OnStopSocketKeepalive(slot)) + } + + inline fun expectCallback(): T { val foundCallback = history.poll(DEFAULT_TIMEOUT_MS) assertTrue(foundCallback is T, "Expected ${T::class} but found $foundCallback") + return foundCallback + } + + fun assertNoCallback() { + assertTrue(waitForIdle(DEFAULT_TIMEOUT_MS), "Handler never became idle") + assertNull(history.peek()) } } @@ -126,7 +225,9 @@ class NetworkAgentTest { addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING) addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) } - val lp = LinkProperties() + val lp = LinkProperties().apply { + addLinkAddress(LinkAddress(LOCAL_IPV4_ADDRESS, 0)) + } val config = NetworkAgentConfig.Builder().build() return TestableNetworkAgent(mHandlerThread.looper, nc, lp, config).also { agentsToCleanUp.add(it) @@ -146,6 +247,10 @@ class NetworkAgentTest { return agent to callback } + private fun createNetworkAgentWithFakeCS() = createNetworkAgent().also { + mFakeConnectivityService.connect(it.registerForTest(Network(FAKE_NET_ID))) + } + @Test fun testConnectAndUnregister() { val (agent, callback) = createConnectedNetworkAgent() @@ -166,4 +271,48 @@ class NetworkAgentTest { agent.expectCallback() agent.unregister() } + + @Test + fun testSocketKeepalive(): Unit = createNetworkAgentWithFakeCS().let { agent -> + val packet = object : KeepalivePacketData( + LOCAL_IPV4_ADDRESS /* srcAddress */, 1234 /* srcPort */, + REMOTE_IPV4_ADDRESS /* dstAddress */, 4567 /* dstPort */, + ByteArray(100 /* size */) { it.toByte() /* init */ }) {} + val slot = 4 + val interval = 37 + + mFakeConnectivityService.sendMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER, + arg1 = slot, obj = packet) + mFakeConnectivityService.sendMessage(CMD_START_SOCKET_KEEPALIVE, + arg1 = slot, arg2 = interval, obj = packet) + + agent.expectCallback().let { + assertEquals(it.slot, slot) + assertEquals(it.packet, packet) + } + agent.expectCallback().let { + assertEquals(it.slot, slot) + assertEquals(it.interval, interval) + assertEquals(it.packet, packet) + } + + agent.assertNoCallback() + + // Check that when the agent sends a keepalive event, ConnectivityService receives the + // expected message. + agent.sendSocketKeepaliveEvent(slot, SocketKeepalive.ERROR_UNSUPPORTED) + mFakeConnectivityService.expectMessage(NetworkAgent.EVENT_SOCKET_KEEPALIVE).let() { + assertEquals(slot, it.arg1) + assertEquals(SocketKeepalive.ERROR_UNSUPPORTED, it.arg2) + } + + mFakeConnectivityService.sendMessage(CMD_STOP_SOCKET_KEEPALIVE, arg1 = slot) + mFakeConnectivityService.sendMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER, arg1 = slot) + agent.expectCallback().let { + assertEquals(it.slot, slot) + } + agent.expectCallback().let { + assertEquals(it.slot, slot) + } + } } From d5273557349f3afe6249404876f75df2a628ddaf Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Mon, 13 Apr 2020 14:27:45 +0900 Subject: [PATCH 0871/1109] Test accept unvalidated Test: this Bug: 139268426 Change-Id: I9343f72e1b1f4752e9781ff9b44e2a561d166cfb Merged-In: I3326a2119d66e67566fce0268ea4861729b1c64c (cherry-picked from aosp/1284557) --- .../src/android/net/cts/NetworkAgentTest.kt | 66 ++++++++++++++++++- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 32f2bfafe2..14f52e1e7c 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -24,7 +24,9 @@ import android.net.LinkProperties import android.net.Network import android.net.NetworkAgent import android.net.NetworkAgent.CMD_ADD_KEEPALIVE_PACKET_FILTER +import android.net.NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT import android.net.NetworkAgent.CMD_REMOVE_KEEPALIVE_PACKET_FILTER +import android.net.NetworkAgent.CMD_SAVE_ACCEPT_UNVALIDATED import android.net.NetworkAgent.CMD_START_SOCKET_KEEPALIVE import android.net.NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE import android.net.NetworkAgentConfig @@ -39,9 +41,11 @@ import android.os.Looper import android.os.Message import android.os.Messenger import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnAddKeepalivePacketFilter +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnAutomaticReconnectDisabled import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnBandwidthUpdateRequested import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnNetworkUnwanted import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnRemoveKeepalivePacketFilter +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnSaveAcceptUnvalidated import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStartSocketKeepalive import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStopSocketKeepalive import androidx.test.InstrumentationRegistry @@ -60,6 +64,7 @@ import org.junit.runner.RunWith import java.net.InetAddress import java.time.Duration import kotlin.test.assertEquals +import kotlin.test.assertFalse import kotlin.test.assertFailsWith import kotlin.test.assertNotNull import kotlin.test.assertNull @@ -123,27 +128,38 @@ class NetworkAgentTest { * only keeps track of one async channel. */ private class FakeConnectivityService(looper: Looper) { + private val CMD_EXPECT_DISCONNECT = 1 + private var disconnectExpected = false private val msgHistory = ArrayTrackRecord().newReadHead() private val asyncChannel = AsyncChannel() private val handler = object : Handler(looper) { override fun handleMessage(msg: Message) { msgHistory.add(Message.obtain(msg)) // make a copy as the original will be recycled when (msg.what) { + CMD_EXPECT_DISCONNECT -> disconnectExpected = true AsyncChannel.CMD_CHANNEL_HALF_CONNECTED -> asyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION) - AsyncChannel.CMD_CHANNEL_DISCONNECT, AsyncChannel.CMD_CHANNEL_DISCONNECTED -> - fail("Agent unexpectedly disconnected") + AsyncChannel.CMD_CHANNEL_DISCONNECTED -> + if (!disconnectExpected) { + fail("Agent unexpectedly disconnected") + } else { + disconnectExpected = false + } } } } fun connect(agentMsngr: Messenger) = asyncChannel.connect(context, handler, agentMsngr) + fun disconnect() = asyncChannel.disconnect() + fun sendMessage(what: Int, arg1: Int = 0, arg2: Int = 0, obj: Any? = null) = asyncChannel.sendMessage(Message(what, arg1, arg2, obj)) fun expectMessage(what: Int) = assertNotNull(msgHistory.poll(DEFAULT_TIMEOUT_MS) { it.what == what }) + + fun willExpectDisconnectOnce() = handler.sendEmptyMessage(CMD_EXPECT_DISCONNECT) } private open class TestableNetworkAgent( @@ -169,6 +185,8 @@ class NetworkAgentTest { val packet: KeepalivePacketData ) : CallbackEntry() data class OnStopSocketKeepalive(val slot: Int) : CallbackEntry() + data class OnSaveAcceptUnvalidated(val accept: Boolean) : CallbackEntry() + object OnAutomaticReconnectDisabled : CallbackEntry() } override fun onBandwidthUpdateRequested() { @@ -199,6 +217,14 @@ class NetworkAgentTest { history.add(OnStopSocketKeepalive(slot)) } + override fun onSaveAcceptUnvalidated(accept: Boolean) { + history.add(OnSaveAcceptUnvalidated(accept)) + } + + override fun onAutomaticReconnectDisabled() { + history.add(OnAutomaticReconnectDisabled) + } + inline fun expectCallback(): T { val foundCallback = history.poll(DEFAULT_TIMEOUT_MS) assertTrue(foundCallback is T, "Expected ${T::class} but found $foundCallback") @@ -315,4 +341,40 @@ class NetworkAgentTest { assertEquals(it.slot, slot) } } + + @Test + fun testSetAcceptUnvalidated() { + createNetworkAgentWithFakeCS().let { agent -> + mFakeConnectivityService.sendMessage(CMD_SAVE_ACCEPT_UNVALIDATED, 1) + agent.expectCallback().let { + assertTrue(it.accept) + } + agent.assertNoCallback() + } + createNetworkAgentWithFakeCS().let { agent -> + mFakeConnectivityService.sendMessage(CMD_SAVE_ACCEPT_UNVALIDATED, 0) + mFakeConnectivityService.sendMessage(CMD_PREVENT_AUTOMATIC_RECONNECT) + agent.expectCallback().let { + assertFalse(it.accept) + } + agent.expectCallback() + agent.assertNoCallback() + // When automatic reconnect is turned off, the network is torn down and + // ConnectivityService sends a disconnect. This in turn causes the agent + // to send a DISCONNECTED message to CS. + mFakeConnectivityService.willExpectDisconnectOnce() + mFakeConnectivityService.disconnect() + mFakeConnectivityService.expectMessage(AsyncChannel.CMD_CHANNEL_DISCONNECTED) + agent.expectCallback() + } + createNetworkAgentWithFakeCS().let { agent -> + mFakeConnectivityService.sendMessage(CMD_PREVENT_AUTOMATIC_RECONNECT) + agent.expectCallback() + agent.assertNoCallback() + mFakeConnectivityService.willExpectDisconnectOnce() + mFakeConnectivityService.disconnect() + mFakeConnectivityService.expectMessage(AsyncChannel.CMD_CHANNEL_DISCONNECTED) + agent.expectCallback() + } + } } From 4f9483a9b8f8c1a8d45b879e6f109e31b137070c Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Tue, 14 Apr 2020 03:05:24 +0000 Subject: [PATCH 0872/1109] Test validation status Test: this Bug: 139268426 Change-Id: I04be5cda321af109cb6fd7510362d817ab23b505 Merged-In: I8499d9da8643cf60c912570e7a2ac2207d662e16 (cherry picked from commit 03af30598907add0f64d815f5487ea97e8d61f04, aosp/1284558) --- .../src/android/net/cts/NetworkAgentTest.kt | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 14f52e1e7c..97a15ef634 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -26,15 +26,20 @@ import android.net.NetworkAgent import android.net.NetworkAgent.CMD_ADD_KEEPALIVE_PACKET_FILTER import android.net.NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT import android.net.NetworkAgent.CMD_REMOVE_KEEPALIVE_PACKET_FILTER +import android.net.NetworkAgent.CMD_REPORT_NETWORK_STATUS import android.net.NetworkAgent.CMD_SAVE_ACCEPT_UNVALIDATED import android.net.NetworkAgent.CMD_START_SOCKET_KEEPALIVE import android.net.NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE +import android.net.NetworkAgent.INVALID_NETWORK +import android.net.NetworkAgent.VALID_NETWORK import android.net.NetworkAgentConfig import android.net.NetworkCapabilities import android.net.NetworkProvider import android.net.NetworkRequest import android.net.SocketKeepalive +import android.net.Uri import android.os.Build +import android.os.Bundle import android.os.Handler import android.os.HandlerThread import android.os.Looper @@ -48,6 +53,7 @@ import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnRem import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnSaveAcceptUnvalidated import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStartSocketKeepalive import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStopSocketKeepalive +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnValidationStatus import androidx.test.InstrumentationRegistry import androidx.test.runner.AndroidJUnit4 import com.android.internal.util.AsyncChannel @@ -187,6 +193,7 @@ class NetworkAgentTest { data class OnStopSocketKeepalive(val slot: Int) : CallbackEntry() data class OnSaveAcceptUnvalidated(val accept: Boolean) : CallbackEntry() object OnAutomaticReconnectDisabled : CallbackEntry() + data class OnValidationStatus(val status: Int, val uri: Uri?) : CallbackEntry() } override fun onBandwidthUpdateRequested() { @@ -225,6 +232,23 @@ class NetworkAgentTest { history.add(OnAutomaticReconnectDisabled) } + override fun onValidationStatus(status: Int, uri: Uri?) { + history.add(OnValidationStatus(status, uri)) + } + + // Expects the initial validation event that always occurs immediately after registering + // a NetworkAgent whose network does not require validation (which test networks do + // not, since they lack the INTERNET capability). It always contains the default argument + // for the URI. + fun expectNoInternetValidationStatus() = expectCallback().let { + assertEquals(it.status, VALID_NETWORK) + // The returned Uri is parsed from the empty string, which means it's an + // instance of the (private) Uri.StringUri. There are no real good ways + // to check this, the least bad is to just convert it to a string and + // make sure it's empty. + assertEquals("", it.uri.toString()) + } + inline fun expectCallback(): T { val foundCallback = history.poll(DEFAULT_TIMEOUT_MS) assertTrue(foundCallback is T, "Expected ${T::class} but found $foundCallback") @@ -281,6 +305,7 @@ class NetworkAgentTest { fun testConnectAndUnregister() { val (agent, callback) = createConnectedNetworkAgent() callback.expectAvailableThenValidatedCallbacks(agent.network) + agent.expectNoInternetValidationStatus() agent.unregister() callback.expectCallback(agent.network) agent.expectCallback() @@ -293,6 +318,7 @@ class NetworkAgentTest { fun testOnBandwidthUpdateRequested() { val (agent, callback) = createConnectedNetworkAgent() callback.expectAvailableThenValidatedCallbacks(agent.network) + agent.expectNoInternetValidationStatus() mCM.requestBandwidthUpdate(agent.network) agent.expectCallback() agent.unregister() @@ -377,4 +403,25 @@ class NetworkAgentTest { agent.expectCallback() } } + + @Test + fun testValidationStatus() = createNetworkAgentWithFakeCS().let { agent -> + val uri = Uri.parse("http://www.google.com") + val bundle = Bundle().apply { + putString(NetworkAgent.REDIRECT_URL_KEY, uri.toString()) + } + mFakeConnectivityService.sendMessage(CMD_REPORT_NETWORK_STATUS, + arg1 = VALID_NETWORK, obj = bundle) + agent.expectCallback().let { + assertEquals(it.status, VALID_NETWORK) + assertEquals(it.uri, uri) + } + + mFakeConnectivityService.sendMessage(CMD_REPORT_NETWORK_STATUS, + arg1 = INVALID_NETWORK, obj = Bundle()) + agent.expectCallback().let { + assertEquals(it.status, INVALID_NETWORK) + assertNull(it.uri) + } + } } From e582c5d4be0bf80985abb62f6524872001f2c367 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Tue, 14 Apr 2020 03:05:40 +0000 Subject: [PATCH 0873/1109] Test sendCaps and sendProps Test: this Bug: 139268426 Change-Id: I6d30ac0193225826a97ff3853a98b939e571d074 Merged-In: Idefce1174b82668d23c53dd1bf95bc660cb21c28 (cherry picked from commit 7922d354307e4a41a336c29291285550a94da434, aosp/1284560) --- .../src/android/net/cts/NetworkAgentTest.kt | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 97a15ef634..4de3a086ce 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -84,6 +84,7 @@ private const val DEFAULT_TIMEOUT_MS = 5000L // requests filed by the test and should never match normal internet requests. 70 is the default // score of Ethernet networks, it's as good a value as any other. private const val TEST_NETWORK_SCORE = 70 +private const val BETTER_NETWORK_SCORE = 75 private const val FAKE_NET_ID = 1098 private val instrumentation: Instrumentation get() = InstrumentationRegistry.getInstrumentation() @@ -170,8 +171,8 @@ class NetworkAgentTest { private open class TestableNetworkAgent( val looper: Looper, - nc: NetworkCapabilities, - lp: LinkProperties, + val nc: NetworkCapabilities, + val lp: LinkProperties, conf: NetworkAgentConfig ) : NetworkAgent(context, looper, TestableNetworkAgent::class.java.simpleName /* tag */, nc, lp, TEST_NETWORK_SCORE, conf, Provider(context, looper)) { @@ -368,6 +369,25 @@ class NetworkAgentTest { } } + @Test + fun testSendUpdates(): Unit = createConnectedNetworkAgent().let { (agent, callback) -> + callback.expectAvailableThenValidatedCallbacks(agent.network) + agent.expectNoInternetValidationStatus() + val ifaceName = "adhocIface" + val lp = LinkProperties(agent.lp) + lp.setInterfaceName(ifaceName) + agent.sendLinkProperties(lp) + callback.expectLinkPropertiesThat(agent.network) { + it.getInterfaceName() == ifaceName + } + val nc = NetworkCapabilities(agent.nc) + nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED) + agent.sendNetworkCapabilities(nc) + callback.expectCapabilitiesThat(agent.network) { + it.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED) + } + } + @Test fun testSetAcceptUnvalidated() { createNetworkAgentWithFakeCS().let { agent -> From 2e3c3b8d89d83b138bd06cc31be3fbd5348398a9 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Tue, 14 Apr 2020 03:05:52 +0000 Subject: [PATCH 0874/1109] Test sendNetworkScore Test: this Bug: 139268426 Change-Id: Ie46ff2676944e6d6603bbff271fc6dca9935e548 Merged-In: I66cea443f0c6aa9235da577817787d764fbd030b (cherry picked from commit c7091c91558d56632da237cf0a01567fcde3cba2, aosp/1284561) --- .../src/android/net/cts/NetworkAgentTest.kt | 66 ++++++++++++++++++- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 4de3a086ce..659950a0db 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -37,6 +37,7 @@ import android.net.NetworkCapabilities import android.net.NetworkProvider import android.net.NetworkRequest import android.net.SocketKeepalive +import android.net.StringNetworkSpecifier import android.net.Uri import android.os.Build import android.os.Bundle @@ -59,8 +60,10 @@ import androidx.test.runner.AndroidJUnit4 import com.android.internal.util.AsyncChannel import com.android.testutils.ArrayTrackRecord import com.android.testutils.DevSdkIgnoreRule +import com.android.testutils.RecorderCallback.CallbackEntry.Available import com.android.testutils.RecorderCallback.CallbackEntry.Lost import com.android.testutils.TestableNetworkCallback +import java.util.UUID import org.junit.After import org.junit.Assert.fail import org.junit.Before @@ -197,6 +200,8 @@ class NetworkAgentTest { data class OnValidationStatus(val status: Int, val uri: Uri?) : CallbackEntry() } + fun getName(): String? = (nc.getNetworkSpecifier() as? StringNetworkSpecifier)?.specifier + override fun onBandwidthUpdateRequested() { history.add(OnBandwidthUpdateRequested) } @@ -267,7 +272,7 @@ class NetworkAgentTest { callbacksToCleanUp.add(callback) } - private fun createNetworkAgent(): TestableNetworkAgent { + private fun createNetworkAgent(name: String? = null): TestableNetworkAgent { val nc = NetworkCapabilities().apply { addTransportType(NetworkCapabilities.TRANSPORT_TEST) removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED) @@ -275,6 +280,9 @@ class NetworkAgentTest { addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED) addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING) addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) + if (null != name) { + setNetworkSpecifier(StringNetworkSpecifier(name)) + } } val lp = LinkProperties().apply { addLinkAddress(LinkAddress(LOCAL_IPV4_ADDRESS, 0)) @@ -285,14 +293,15 @@ class NetworkAgentTest { } } - private fun createConnectedNetworkAgent(): Pair { + private fun createConnectedNetworkAgent(name: String? = null): + Pair { val request: NetworkRequest = NetworkRequest.Builder() .clearCapabilities() .addTransportType(NetworkCapabilities.TRANSPORT_TEST) .build() val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS) requestNetwork(request, callback) - val agent = createNetworkAgent() + val agent = createNetworkAgent(name) agent.register() agent.markConnected() return agent to callback @@ -388,6 +397,57 @@ class NetworkAgentTest { } } + @Test + fun testSendScore() { + // This test will create two networks and check that the one with the stronger + // score wins out for a request that matches them both. + // First create requests to make sure both networks are kept up, using the + // specifier so they are specific to each network + val name1 = UUID.randomUUID().toString() + val name2 = UUID.randomUUID().toString() + val request1 = NetworkRequest.Builder() + .clearCapabilities() + .addTransportType(NetworkCapabilities.TRANSPORT_TEST) + .setNetworkSpecifier(StringNetworkSpecifier(name1)) + .build() + val request2 = NetworkRequest.Builder() + .clearCapabilities() + .addTransportType(NetworkCapabilities.TRANSPORT_TEST) + .setNetworkSpecifier(StringNetworkSpecifier(name2)) + .build() + val callback1 = TestableNetworkCallback() + val callback2 = TestableNetworkCallback() + requestNetwork(request1, callback1) + requestNetwork(request2, callback2) + + // Then file the interesting request + val request = NetworkRequest.Builder() + .clearCapabilities() + .addTransportType(NetworkCapabilities.TRANSPORT_TEST) + .build() + val callback = TestableNetworkCallback() + requestNetwork(request, callback) + + // Connect the first Network + createConnectedNetworkAgent(name1).let { (agent1, _) -> + callback.expectAvailableThenValidatedCallbacks(agent1.network) + // Upgrade agent1 to a better score so that there is no ambiguity when + // agent2 connects that agent1 is still better + agent1.sendNetworkScore(BETTER_NETWORK_SCORE - 1) + // Connect the second agent + createConnectedNetworkAgent(name2).let { (agent2, _) -> + agent2.markConnected() + // The callback should not see anything yet + callback.assertNoCallback(200) + // Now update the score and expect the callback now prefers agent2 + agent2.sendNetworkScore(BETTER_NETWORK_SCORE) + callback.expectCallback(agent2.network) + } + } + + // tearDown() will unregister the requests and agents + } + @Test fun testSetAcceptUnvalidated() { createNetworkAgentWithFakeCS().let { agent -> From 6a9699652523662ef197c85d5b24fde401da9e3c Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Tue, 14 Apr 2020 03:06:04 +0000 Subject: [PATCH 0875/1109] Test Signal thresholds Test: this Bug: 139268426 Change-Id: I48ea9afa2a31c3edd4b00a566ed47796912c453a Merged-In: I136f246d0e3ad6744989e7d6f4f8034cc6674def (cherry picked from commit 159bce95cb8ca0aba6cf74a0b57a24dae3aadc05, aosp/1284559) --- .../src/android/net/cts/NetworkAgentTest.kt | 81 ++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 659950a0db..9d1eee9da9 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -52,6 +52,7 @@ import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnBan import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnNetworkUnwanted import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnRemoveKeepalivePacketFilter import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnSaveAcceptUnvalidated +import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnSignalStrengthThresholdsUpdated import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStartSocketKeepalive import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnStopSocketKeepalive import android.net.cts.NetworkAgentTest.TestableNetworkAgent.CallbackEntry.OnValidationStatus @@ -65,6 +66,7 @@ import com.android.testutils.RecorderCallback.CallbackEntry.Lost import com.android.testutils.TestableNetworkCallback import java.util.UUID import org.junit.After +import org.junit.Assert.assertArrayEquals import org.junit.Assert.fail import org.junit.Before import org.junit.Rule @@ -83,6 +85,11 @@ import kotlin.test.assertTrue // going to fail, it will simply wait forever, so setting a high timeout lowers the flake ratio // without affecting the run time of successful runs. Thus, set a very high timeout. private const val DEFAULT_TIMEOUT_MS = 5000L +// When waiting for a NetworkCallback to determine there was no timeout, waiting is the +// only possible thing (the relevant handler is the one in the real ConnectivityService, +// and then there is the Binder call), so have a short timeout for this as it will be +// exhausted every time. +private const val NO_CALLBACK_TIMEOUT = 200L // Any legal score (0~99) for the test network would do, as it is going to be kept up by the // requests filed by the test and should never match normal internet requests. 70 is the default // score of Ethernet networks, it's as good a value as any other. @@ -198,6 +205,7 @@ class NetworkAgentTest { data class OnSaveAcceptUnvalidated(val accept: Boolean) : CallbackEntry() object OnAutomaticReconnectDisabled : CallbackEntry() data class OnValidationStatus(val status: Int, val uri: Uri?) : CallbackEntry() + data class OnSignalStrengthThresholdsUpdated(val thresholds: IntArray) : CallbackEntry() } fun getName(): String? = (nc.getNetworkSpecifier() as? StringNetworkSpecifier)?.specifier @@ -238,6 +246,17 @@ class NetworkAgentTest { history.add(OnAutomaticReconnectDisabled) } + override fun onSignalStrengthThresholdsUpdated(thresholds: IntArray) { + history.add(OnSignalStrengthThresholdsUpdated(thresholds)) + } + + fun expectEmptySignalStrengths() { + expectCallback().let { + // intArrayOf() without arguments makes an empty array + assertArrayEquals(intArrayOf(), it.thresholds) + } + } + override fun onValidationStatus(status: Int, uri: Uri?) { history.add(OnValidationStatus(status, uri)) } @@ -272,6 +291,14 @@ class NetworkAgentTest { callbacksToCleanUp.add(callback) } + private fun registerNetworkCallback( + request: NetworkRequest, + callback: TestableNetworkCallback + ) { + mCM.registerNetworkCallback(request, callback) + callbacksToCleanUp.add(callback) + } + private fun createNetworkAgent(name: String? = null): TestableNetworkAgent { val nc = NetworkCapabilities().apply { addTransportType(NetworkCapabilities.TRANSPORT_TEST) @@ -315,6 +342,7 @@ class NetworkAgentTest { fun testConnectAndUnregister() { val (agent, callback) = createConnectedNetworkAgent() callback.expectAvailableThenValidatedCallbacks(agent.network) + agent.expectEmptySignalStrengths() agent.expectNoInternetValidationStatus() agent.unregister() callback.expectCallback(agent.network) @@ -328,12 +356,62 @@ class NetworkAgentTest { fun testOnBandwidthUpdateRequested() { val (agent, callback) = createConnectedNetworkAgent() callback.expectAvailableThenValidatedCallbacks(agent.network) + agent.expectEmptySignalStrengths() agent.expectNoInternetValidationStatus() mCM.requestBandwidthUpdate(agent.network) agent.expectCallback() agent.unregister() } + @Test + fun testSignalStrengthThresholds() { + val thresholds = intArrayOf(30, 50, 65) + val callbacks = thresholds.map { strength -> + val request = NetworkRequest.Builder() + .clearCapabilities() + .addTransportType(NetworkCapabilities.TRANSPORT_TEST) + .setSignalStrength(strength) + .build() + TestableNetworkCallback(DEFAULT_TIMEOUT_MS).also { + registerNetworkCallback(request, it) + } + } + createConnectedNetworkAgent().let { (agent, callback) -> + callback.expectAvailableThenValidatedCallbacks(agent.network) + agent.expectCallback().let { + assertArrayEquals(it.thresholds, thresholds) + } + agent.expectNoInternetValidationStatus() + + // Send signal strength and check that the callbacks are called appropriately. + val nc = NetworkCapabilities(agent.nc) + nc.setSignalStrength(20) + agent.sendNetworkCapabilities(nc) + callbacks.forEach { it.assertNoCallback(NO_CALLBACK_TIMEOUT) } + + nc.setSignalStrength(40) + agent.sendNetworkCapabilities(nc) + callbacks[0].expectAvailableCallbacks(agent.network) + callbacks[1].assertNoCallback(NO_CALLBACK_TIMEOUT) + callbacks[2].assertNoCallback(NO_CALLBACK_TIMEOUT) + + nc.setSignalStrength(80) + agent.sendNetworkCapabilities(nc) + callbacks[0].expectCapabilitiesThat(agent.network) { it.signalStrength == 80 } + callbacks[1].expectAvailableCallbacks(agent.network) + callbacks[2].expectAvailableCallbacks(agent.network) + + nc.setSignalStrength(55) + agent.sendNetworkCapabilities(nc) + callbacks[0].expectCapabilitiesThat(agent.network) { it.signalStrength == 55 } + callbacks[1].expectCapabilitiesThat(agent.network) { it.signalStrength == 55 } + callbacks[2].expectCallback(agent.network) + } + callbacks.forEach { + mCM.unregisterNetworkCallback(it) + } + } + @Test fun testSocketKeepalive(): Unit = createNetworkAgentWithFakeCS().let { agent -> val packet = object : KeepalivePacketData( @@ -381,6 +459,7 @@ class NetworkAgentTest { @Test fun testSendUpdates(): Unit = createConnectedNetworkAgent().let { (agent, callback) -> callback.expectAvailableThenValidatedCallbacks(agent.network) + agent.expectEmptySignalStrengths() agent.expectNoInternetValidationStatus() val ifaceName = "adhocIface" val lp = LinkProperties(agent.lp) @@ -438,7 +517,7 @@ class NetworkAgentTest { createConnectedNetworkAgent(name2).let { (agent2, _) -> agent2.markConnected() // The callback should not see anything yet - callback.assertNoCallback(200) + callback.assertNoCallback(NO_CALLBACK_TIMEOUT) // Now update the score and expect the callback now prefers agent2 agent2.sendNetworkScore(BETTER_NETWORK_SCORE) callback.expectCallback(agent2.network) From 5217786c6c1fe9b2276915dfbafc4bd104500021 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Tue, 14 Apr 2020 03:06:14 +0000 Subject: [PATCH 0876/1109] Address comments from aosp/1284557 Test: this Bug: 139268426 Change-Id: I5d90fe2716032b7ebd2b425225fe8e96900fe63b Merged-In: I5edbff1d7eed2f939ba26f1ebd7ead49ac67b978 (cherry picked from commit 55d7923c1d75e3d91b79461e2bd3846abdd9eed2, aosp/1284569) --- tests/cts/net/src/android/net/cts/NetworkAgentTest.kt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 9d1eee9da9..89d3dff66c 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -281,7 +281,8 @@ class NetworkAgentTest { } fun assertNoCallback() { - assertTrue(waitForIdle(DEFAULT_TIMEOUT_MS), "Handler never became idle") + assertTrue(waitForIdle(DEFAULT_TIMEOUT_MS), + "Handler didn't became idle after ${DEFAULT_TIMEOUT_MS}ms") assertNull(history.peek()) } } @@ -536,6 +537,10 @@ class NetworkAgentTest { } agent.assertNoCallback() } + } + + @Test + fun testSetAcceptUnvalidatedPreventAutomaticReconnect() { createNetworkAgentWithFakeCS().let { agent -> mFakeConnectivityService.sendMessage(CMD_SAVE_ACCEPT_UNVALIDATED, 0) mFakeConnectivityService.sendMessage(CMD_PREVENT_AUTOMATIC_RECONNECT) @@ -552,6 +557,10 @@ class NetworkAgentTest { mFakeConnectivityService.expectMessage(AsyncChannel.CMD_CHANNEL_DISCONNECTED) agent.expectCallback() } + } + + @Test + fun testPreventAutomaticReconnect() { createNetworkAgentWithFakeCS().let { agent -> mFakeConnectivityService.sendMessage(CMD_PREVENT_AUTOMATIC_RECONNECT) agent.expectCallback() From da03c6a3f5e5291abeacbbdd931e007765dfaf0a Mon Sep 17 00:00:00 2001 From: Chiachang Wang Date: Tue, 14 Apr 2020 21:49:50 +0800 Subject: [PATCH 0877/1109] Add test for NetworkRequest#canBeSatisfiedBy Test: atest CtsNetTestCasesLatestSdk:android.net.cts.NetworkRequestTest on both Q and R device Bug: 153972141 Change-Id: I614963cdd5f26bf3d47246fdc9eb11e74d05a460 --- .../android/net/cts/NetworkRequestTest.java | 45 ++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java index 8b97c8cb92..751418657f 100644 --- a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java @@ -16,8 +16,11 @@ package android.net.cts; +import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS; import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH; +import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; +import static android.net.NetworkCapabilities.TRANSPORT_VPN; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static org.junit.Assert.assertEquals; @@ -26,13 +29,12 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import android.net.MacAddress; +import android.net.NetworkCapabilities; import android.net.NetworkRequest; import android.net.NetworkSpecifier; -import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiNetworkSpecifier; import android.os.Build; import android.os.PatternMatcher; -import android.util.Pair; import androidx.test.runner.AndroidJUnit4; @@ -49,6 +51,7 @@ public class NetworkRequestTest { public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule(); private static final String TEST_SSID = "TestSSID"; + private static final String OTHER_SSID = "OtherSSID"; private static final int TEST_UID = 2097; private static final String TEST_PACKAGE_NAME = "test.package.name"; private static final MacAddress ARBITRARY_ADDRESS = MacAddress.fromString("3:5:8:12:9:2"); @@ -84,4 +87,42 @@ public class NetworkRequestTest { .getNetworkSpecifier(); assertEquals(obtainedSpecifier, specifier); } + + @Test + @IgnoreUpTo(Build.VERSION_CODES.Q) + public void testCanBeSatisfiedBy() { + final WifiNetworkSpecifier specifier1 = new WifiNetworkSpecifier.Builder() + .setSsidPattern(new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL)) + .setBssidPattern(ARBITRARY_ADDRESS, ARBITRARY_ADDRESS) + .build(); + final WifiNetworkSpecifier specifier2 = new WifiNetworkSpecifier.Builder() + .setSsidPattern(new PatternMatcher(OTHER_SSID, PatternMatcher.PATTERN_LITERAL)) + .setBssidPattern(ARBITRARY_ADDRESS, ARBITRARY_ADDRESS) + .build(); + final NetworkCapabilities cap = new NetworkCapabilities() + .addTransportType(TRANSPORT_WIFI) + .addCapability(NET_CAPABILITY_INTERNET); + final NetworkCapabilities capWithSp = + new NetworkCapabilities(cap).setNetworkSpecifier(specifier1); + final NetworkCapabilities cellCap = new NetworkCapabilities() + .addTransportType(TRANSPORT_CELLULAR) + .addCapability(NET_CAPABILITY_MMS) + .addCapability(NET_CAPABILITY_INTERNET); + final NetworkRequest request = new NetworkRequest.Builder() + .addTransportType(TRANSPORT_WIFI) + .addCapability(NET_CAPABILITY_INTERNET) + .setNetworkSpecifier(specifier1) + .build(); + assertFalse(request.canBeSatisfiedBy(null)); + assertFalse(request.canBeSatisfiedBy(new NetworkCapabilities())); + assertTrue(request.canBeSatisfiedBy(cap)); + assertTrue(request.canBeSatisfiedBy( + new NetworkCapabilities(cap).addTransportType(TRANSPORT_VPN))); + assertTrue(request.canBeSatisfiedBy(capWithSp)); + assertFalse(request.canBeSatisfiedBy( + new NetworkCapabilities(cap).setNetworkSpecifier(specifier2))); + assertFalse(request.canBeSatisfiedBy(cellCap)); + assertEquals(request.canBeSatisfiedBy(capWithSp), + new NetworkCapabilities(capWithSp).satisfiedByNetworkCapabilities(capWithSp)); + } } From ff7fe1e5fe7cbfc5e3f89062baa6a8f52155336b Mon Sep 17 00:00:00 2001 From: Yan Yan Date: Wed, 15 Apr 2020 00:49:54 +0000 Subject: [PATCH 0878/1109] Add CTS for building IKE and Child SaProposal Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: Ic50d70f35216a065ff398c38262f2de0b370c5ef Merged-In: Ic50d70f35216a065ff398c38262f2de0b370c5ef (cherry picked from commit 7f95e39c2534b370a28e4d6cf08ebb8b74950fcb) --- .../net/ipsec/ike/cts/SaProposalTest.java | 232 +++++++++++++++++- 1 file changed, 229 insertions(+), 3 deletions(-) diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java index 47e8f0174d..e0d3be0540 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java @@ -16,15 +16,241 @@ package android.net.ipsec.ike.cts; +import static android.net.ipsec.ike.SaProposal.DH_GROUP_1024_BIT_MODP; +import static android.net.ipsec.ike.SaProposal.DH_GROUP_2048_BIT_MODP; +import static android.net.ipsec.ike.SaProposal.DH_GROUP_NONE; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_3DES; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_CBC; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_AES_XCBC_96; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_384_192; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_512_256; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_NONE; +import static android.net.ipsec.ike.SaProposal.KEY_LEN_AES_128; +import static android.net.ipsec.ike.SaProposal.KEY_LEN_AES_192; +import static android.net.ipsec.ike.SaProposal.KEY_LEN_AES_256; +import static android.net.ipsec.ike.SaProposal.KEY_LEN_UNUSED; +import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC; +import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1; +import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_SHA2_256; +import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_SHA2_384; +import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_SHA2_512; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import android.net.ipsec.ike.ChildSaProposal; +import android.net.ipsec.ike.IkeSaProposal; +import android.util.Pair; + import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + @RunWith(AndroidJUnit4.class) public class SaProposalTest { - @Test - public void testBuildIkeSaProposal() { - // TODO(b/148689509): Add real tests here + private static final List> NORMAL_MODE_CIPHERS = new ArrayList<>(); + private static final List> COMBINED_MODE_CIPHERS = new ArrayList<>(); + private static final List INTEGRITY_ALGOS = new ArrayList<>(); + private static final List DH_GROUPS = new ArrayList<>(); + private static final List DH_GROUPS_WITH_NONE = new ArrayList<>(); + private static final List PRFS = new ArrayList<>(); + + static { + NORMAL_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED)); + NORMAL_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_128)); + NORMAL_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_192)); + NORMAL_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_256)); + + COMBINED_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_GCM_8, KEY_LEN_AES_128)); + COMBINED_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_192)); + COMBINED_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_256)); + + INTEGRITY_ALGOS.add(INTEGRITY_ALGORITHM_HMAC_SHA1_96); + INTEGRITY_ALGOS.add(INTEGRITY_ALGORITHM_AES_XCBC_96); + INTEGRITY_ALGOS.add(INTEGRITY_ALGORITHM_HMAC_SHA2_256_128); + INTEGRITY_ALGOS.add(INTEGRITY_ALGORITHM_HMAC_SHA2_384_192); + INTEGRITY_ALGOS.add(INTEGRITY_ALGORITHM_HMAC_SHA2_512_256); + + DH_GROUPS.add(DH_GROUP_1024_BIT_MODP); + DH_GROUPS.add(DH_GROUP_2048_BIT_MODP); + + DH_GROUPS_WITH_NONE.add(DH_GROUP_NONE); + DH_GROUPS_WITH_NONE.addAll(DH_GROUPS); + + PRFS.add(PSEUDORANDOM_FUNCTION_HMAC_SHA1); + PRFS.add(PSEUDORANDOM_FUNCTION_AES128_XCBC); + PRFS.add(PSEUDORANDOM_FUNCTION_SHA2_256); + PRFS.add(PSEUDORANDOM_FUNCTION_SHA2_384); + PRFS.add(PSEUDORANDOM_FUNCTION_SHA2_512); } + + // Package private + static IkeSaProposal buildIkeSaProposalWithNormalModeCipher() { + return buildIkeSaProposal(NORMAL_MODE_CIPHERS, INTEGRITY_ALGOS, PRFS, DH_GROUPS); + } + + // Package private + static IkeSaProposal buildIkeSaProposalWithCombinedModeCipher() { + return buildIkeSaProposalWithCombinedModeCipher(true /* hasIntegrityNone */); + } + + private static IkeSaProposal buildIkeSaProposalWithCombinedModeCipher( + boolean hasIntegrityNone) { + List integerAlgos = new ArrayList<>(); + if (hasIntegrityNone) { + integerAlgos.add(INTEGRITY_ALGORITHM_NONE); + } + return buildIkeSaProposal(COMBINED_MODE_CIPHERS, integerAlgos, PRFS, DH_GROUPS); + } + + private static IkeSaProposal buildIkeSaProposal( + List> ciphers, + List integrityAlgos, + List prfs, + List dhGroups) { + IkeSaProposal.Builder builder = new IkeSaProposal.Builder(); + + for (Pair pair : ciphers) { + builder.addEncryptionAlgorithm(pair.first, pair.second); + } + for (int algo : integrityAlgos) { + builder.addIntegrityAlgorithm(algo); + } + for (int algo : prfs) { + builder.addPseudorandomFunction(algo); + } + for (int algo : dhGroups) { + builder.addDhGroup(algo); + } + + return builder.build(); + } + + // Package private + static ChildSaProposal buildChildSaProposalWithNormalModeCipher() { + return buildChildSaProposal(NORMAL_MODE_CIPHERS, INTEGRITY_ALGOS, DH_GROUPS_WITH_NONE); + } + + // Package private + static ChildSaProposal buildChildSaProposalWithCombinedModeCipher() { + return buildChildSaProposalWithCombinedModeCipher(true /* hasIntegrityNone */); + } + + private static ChildSaProposal buildChildSaProposalWithCombinedModeCipher( + boolean hasIntegrityNone) { + List integerAlgos = new ArrayList<>(); + if (hasIntegrityNone) { + integerAlgos.add(INTEGRITY_ALGORITHM_NONE); + } + + return buildChildSaProposal(COMBINED_MODE_CIPHERS, integerAlgos, DH_GROUPS_WITH_NONE); + } + + private static ChildSaProposal buildChildSaProposal( + List> ciphers, + List integrityAlgos, + List dhGroups) { + ChildSaProposal.Builder builder = new ChildSaProposal.Builder(); + + for (Pair pair : ciphers) { + builder.addEncryptionAlgorithm(pair.first, pair.second); + } + for (int algo : integrityAlgos) { + builder.addIntegrityAlgorithm(algo); + } + for (int algo : dhGroups) { + builder.addDhGroup(algo); + } + + return builder.build(); + } + + // Package private + static ChildSaProposal buildChildSaProposalWithOnlyCiphers() { + return buildChildSaProposal( + COMBINED_MODE_CIPHERS, Collections.EMPTY_LIST, Collections.EMPTY_LIST); + } + + @Test + public void testBuildIkeSaProposalWithNormalModeCipher() { + IkeSaProposal saProposal = buildIkeSaProposalWithNormalModeCipher(); + + assertEquals(NORMAL_MODE_CIPHERS, saProposal.getEncryptionAlgorithms()); + assertEquals(INTEGRITY_ALGOS, saProposal.getIntegrityAlgorithms()); + assertEquals(PRFS, saProposal.getPseudorandomFunctions()); + assertEquals(DH_GROUPS, saProposal.getDhGroups()); + } + + @Test + public void testBuildIkeSaProposalWithCombinedModeCipher() { + IkeSaProposal saProposal = + buildIkeSaProposalWithCombinedModeCipher(false /* hasIntegrityNone */); + + assertEquals(COMBINED_MODE_CIPHERS, saProposal.getEncryptionAlgorithms()); + assertEquals(PRFS, saProposal.getPseudorandomFunctions()); + assertEquals(DH_GROUPS, saProposal.getDhGroups()); + assertTrue(saProposal.getIntegrityAlgorithms().isEmpty()); + } + + @Test + public void testBuildIkeSaProposalWithCombinedModeCipherAndIntegrityNone() { + IkeSaProposal saProposal = + buildIkeSaProposalWithCombinedModeCipher(true /* hasIntegrityNone */); + + assertEquals(COMBINED_MODE_CIPHERS, saProposal.getEncryptionAlgorithms()); + assertEquals(PRFS, saProposal.getPseudorandomFunctions()); + assertEquals(DH_GROUPS, saProposal.getDhGroups()); + assertEquals(Arrays.asList(INTEGRITY_ALGORITHM_NONE), saProposal.getIntegrityAlgorithms()); + } + + @Test + public void testBuildChildSaProposalWithNormalModeCipher() { + ChildSaProposal saProposal = buildChildSaProposalWithNormalModeCipher(); + + assertEquals(NORMAL_MODE_CIPHERS, saProposal.getEncryptionAlgorithms()); + assertEquals(INTEGRITY_ALGOS, saProposal.getIntegrityAlgorithms()); + assertEquals(DH_GROUPS_WITH_NONE, saProposal.getDhGroups()); + } + + @Test + public void testBuildChildProposalWithCombinedModeCipher() { + ChildSaProposal saProposal = + buildChildSaProposalWithCombinedModeCipher(false /* hasIntegrityNone */); + + assertEquals(COMBINED_MODE_CIPHERS, saProposal.getEncryptionAlgorithms()); + assertTrue(saProposal.getIntegrityAlgorithms().isEmpty()); + assertEquals(DH_GROUPS_WITH_NONE, saProposal.getDhGroups()); + } + + @Test + public void testBuildChildProposalWithCombinedModeCipherAndIntegrityNone() { + ChildSaProposal saProposal = + buildChildSaProposalWithCombinedModeCipher(true /* hasIntegrityNone */); + + assertEquals(COMBINED_MODE_CIPHERS, saProposal.getEncryptionAlgorithms()); + assertEquals(Arrays.asList(INTEGRITY_ALGORITHM_NONE), saProposal.getIntegrityAlgorithms()); + assertEquals(DH_GROUPS_WITH_NONE, saProposal.getDhGroups()); + } + + @Test + public void testBuildChildSaProposalWithOnlyCiphers() { + ChildSaProposal saProposal = buildChildSaProposalWithOnlyCiphers(); + + assertEquals(COMBINED_MODE_CIPHERS, saProposal.getEncryptionAlgorithms()); + assertTrue(saProposal.getIntegrityAlgorithms().isEmpty()); + assertTrue(saProposal.getDhGroups().isEmpty()); + } + + // TODO(b/148689509): Test throwing exception when algorithm combination is invalid } From 2b98dce4e9dcb18d18a1567822afc3edcf3c26de Mon Sep 17 00:00:00 2001 From: Yan Yan Date: Wed, 15 Apr 2020 00:50:24 +0000 Subject: [PATCH 0879/1109] Test setting proposal, TS and lifetime for ChildSessionParams Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: If19fb12c92f65d487478fda172acb21f6cfb1717 Merged-In: If19fb12c92f65d487478fda172acb21f6cfb1717 (cherry picked from commit ee06cc4c06e54c7cf9cb46acd38066106bdc1cba) --- .../ipsec/ike/cts/ChildSessionParamsTest.java | 140 ++++++++++++++++++ .../net/ipsec/ike/cts/IkeTestBase.java | 83 +++++++++++ 2 files changed, 223 insertions(+) create mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java create mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java new file mode 100644 index 0000000000..316355252a --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java @@ -0,0 +1,140 @@ +/* + * 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.ipsec.ike.cts; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import android.net.ipsec.ike.ChildSaProposal; +import android.net.ipsec.ike.ChildSessionParams; +import android.net.ipsec.ike.TransportModeChildSessionParams; +import android.net.ipsec.ike.TunnelModeChildSessionParams; + +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Arrays; +import java.util.concurrent.TimeUnit; + +@RunWith(AndroidJUnit4.class) +public class ChildSessionParamsTest extends IkeTestBase { + private static final int HARD_LIFETIME_SECONDS = (int) TimeUnit.HOURS.toSeconds(3L); + private static final int SOFT_LIFETIME_SECONDS = (int) TimeUnit.HOURS.toSeconds(1L); + + // Random proposal. Content doesn't matter + private final ChildSaProposal mSaProposal = + SaProposalTest.buildChildSaProposalWithCombinedModeCipher(); + + private void verifyTunnelModeChildParamsWithDefaultValues(ChildSessionParams childParams) { + assertTrue(childParams instanceof TunnelModeChildSessionParams); + verifyChildParamsWithDefaultValues(childParams); + } + + private void verifyTunnelModeChildParamsWithCustomizedValues(ChildSessionParams childParams) { + assertTrue(childParams instanceof TunnelModeChildSessionParams); + verifyChildParamsWithCustomizedValues(childParams); + } + + private void verifyTransportModeChildParamsWithDefaultValues(ChildSessionParams childParams) { + assertTrue(childParams instanceof TransportModeChildSessionParams); + verifyChildParamsWithDefaultValues(childParams); + } + + private void verifyTransportModeChildParamsWithCustomizedValues( + ChildSessionParams childParams) { + assertTrue(childParams instanceof TransportModeChildSessionParams); + verifyChildParamsWithCustomizedValues(childParams); + } + + private void verifyChildParamsWithDefaultValues(ChildSessionParams childParams) { + assertEquals(Arrays.asList(mSaProposal), childParams.getSaProposals()); + + // Do not do assertEquals to the default values to be avoid being a change-detector test + assertTrue(childParams.getHardLifetimeSeconds() > childParams.getSoftLifetimeSeconds()); + assertTrue(childParams.getSoftLifetimeSeconds() > 0); + + assertEquals( + Arrays.asList(DEFAULT_V4_TS, DEFAULT_V6_TS), + childParams.getInboundTrafficSelectors()); + assertEquals( + Arrays.asList(DEFAULT_V4_TS, DEFAULT_V6_TS), + childParams.getOutboundTrafficSelectors()); + } + + private void verifyChildParamsWithCustomizedValues(ChildSessionParams childParams) { + assertEquals(Arrays.asList(mSaProposal), childParams.getSaProposals()); + + assertEquals(HARD_LIFETIME_SECONDS, childParams.getHardLifetimeSeconds()); + assertEquals(SOFT_LIFETIME_SECONDS, childParams.getSoftLifetimeSeconds()); + + assertEquals( + Arrays.asList(INBOUND_V4_TS, INBOUND_V6_TS), + childParams.getInboundTrafficSelectors()); + assertEquals( + Arrays.asList(OUTBOUND_V4_TS, OUTBOUND_V6_TS), + childParams.getOutboundTrafficSelectors()); + } + + @Test + public void testBuildTransportModeParamsWithDefaultValues() { + TransportModeChildSessionParams childParams = + new TransportModeChildSessionParams.Builder().addSaProposal(mSaProposal).build(); + + verifyTransportModeChildParamsWithDefaultValues(childParams); + } + + @Test + public void testBuildTunnelModeParamsWithDefaultValues() { + TunnelModeChildSessionParams childParams = + new TunnelModeChildSessionParams.Builder().addSaProposal(mSaProposal).build(); + + verifyTunnelModeChildParamsWithDefaultValues(childParams); + assertTrue(childParams.getConfigurationRequests().isEmpty()); + } + + @Test + public void testBuildTransportModeParamsWithCustomizedValues() { + TransportModeChildSessionParams childParams = + new TransportModeChildSessionParams.Builder() + .addSaProposal(mSaProposal) + .setLifetimeSeconds(HARD_LIFETIME_SECONDS, SOFT_LIFETIME_SECONDS) + .addInboundTrafficSelectors(INBOUND_V4_TS) + .addInboundTrafficSelectors(INBOUND_V6_TS) + .addOutboundTrafficSelectors(OUTBOUND_V4_TS) + .addOutboundTrafficSelectors(OUTBOUND_V6_TS) + .build(); + + verifyTransportModeChildParamsWithCustomizedValues(childParams); + } + + @Test + public void testBuildTunnelModeParamsWithCustomizedValues() { + TunnelModeChildSessionParams childParams = + new TunnelModeChildSessionParams.Builder() + .addSaProposal(mSaProposal) + .setLifetimeSeconds(HARD_LIFETIME_SECONDS, SOFT_LIFETIME_SECONDS) + .addInboundTrafficSelectors(INBOUND_V4_TS) + .addInboundTrafficSelectors(INBOUND_V6_TS) + .addOutboundTrafficSelectors(OUTBOUND_V4_TS) + .addOutboundTrafficSelectors(OUTBOUND_V6_TS) + .build(); + + verifyTunnelModeChildParamsWithCustomizedValues(childParams); + } +} diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java new file mode 100644 index 0000000000..d4b431e837 --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.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.ipsec.ike.cts; + +import android.net.InetAddresses; +import android.net.ipsec.ike.IkeTrafficSelector; + +import java.net.Inet4Address; +import java.net.Inet6Address; + +/** Shared parameters and util methods for testing different components of IKE */ +abstract class IkeTestBase { + private static final int MIN_PORT = 0; + private static final int MAX_PORT = 65535; + private static final int INBOUND_TS_START_PORT = MIN_PORT; + private static final int INBOUND_TS_END_PORT = 65520; + private static final int OUTBOUND_TS_START_PORT = 16; + private static final int OUTBOUND_TS_END_PORT = MAX_PORT; + + static final int IP4_PREFIX_LEN = 32; + static final int IP6_PREFIX_LEN = 64; + + static final Inet4Address IPV4_ADDRESS_LOCAL = + (Inet4Address) (InetAddresses.parseNumericAddress("192.0.2.100")); + static final Inet4Address IPV4_ADDRESS_REMOTE = + (Inet4Address) (InetAddresses.parseNumericAddress("198.51.100.100")); + static final Inet6Address IPV6_ADDRESS_LOCAL = + (Inet6Address) (InetAddresses.parseNumericAddress("2001:db8::100")); + static final Inet6Address IPV6_ADDRESS_REMOTE = + (Inet6Address) (InetAddresses.parseNumericAddress("2001:db8:255::100")); + + static final IkeTrafficSelector DEFAULT_V4_TS = + new IkeTrafficSelector( + MIN_PORT, + MAX_PORT, + InetAddresses.parseNumericAddress("0.0.0.0"), + InetAddresses.parseNumericAddress("255.255.255.255")); + static final IkeTrafficSelector DEFAULT_V6_TS = + new IkeTrafficSelector( + MIN_PORT, + MAX_PORT, + InetAddresses.parseNumericAddress("::"), + InetAddresses.parseNumericAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")); + static final IkeTrafficSelector INBOUND_V4_TS = + new IkeTrafficSelector( + INBOUND_TS_START_PORT, + INBOUND_TS_END_PORT, + InetAddresses.parseNumericAddress("192.0.2.10"), + InetAddresses.parseNumericAddress("192.0.2.20")); + static final IkeTrafficSelector OUTBOUND_V4_TS = + new IkeTrafficSelector( + OUTBOUND_TS_START_PORT, + OUTBOUND_TS_END_PORT, + InetAddresses.parseNumericAddress("198.51.100.0"), + InetAddresses.parseNumericAddress("198.51.100.255")); + + static final IkeTrafficSelector INBOUND_V6_TS = + new IkeTrafficSelector( + INBOUND_TS_START_PORT, + INBOUND_TS_END_PORT, + InetAddresses.parseNumericAddress("2001:db8::10"), + InetAddresses.parseNumericAddress("2001:db8::128")); + static final IkeTrafficSelector OUTBOUND_V6_TS = + new IkeTrafficSelector( + OUTBOUND_TS_START_PORT, + OUTBOUND_TS_END_PORT, + InetAddresses.parseNumericAddress("2001:db8:255::64"), + InetAddresses.parseNumericAddress("2001:db8:255::255")); +} From 5e89d115fbb0ac48c55484ace010cd7ceb0c6414 Mon Sep 17 00:00:00 2001 From: Yan Yan Date: Wed, 15 Apr 2020 17:29:01 +0000 Subject: [PATCH 0880/1109] Test setting config requests for TunnelModeChildSessionParams Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: Ib3e803159cdf42a8655c0e4d0f22faeabe161c4c Merged-In: Ib3e803159cdf42a8655c0e4d0f22faeabe161c4c (cherry picked from commit 7ec4cf34cc443984889c5728a2b538ea91ec5036) --- .../ipsec/ike/cts/ChildSessionParamsTest.java | 90 +++++++++++++++++++ .../net/ipsec/ike/cts/IkeTestBase.java | 37 ++++++++ 2 files changed, 127 insertions(+) diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java index 316355252a..7fb1b6dc43 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java @@ -16,20 +16,36 @@ package android.net.ipsec.ike.cts; +import static android.system.OsConstants.AF_INET; +import static android.system.OsConstants.AF_INET6; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import android.net.LinkAddress; import android.net.ipsec.ike.ChildSaProposal; import android.net.ipsec.ike.ChildSessionParams; import android.net.ipsec.ike.TransportModeChildSessionParams; import android.net.ipsec.ike.TunnelModeChildSessionParams; +import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv4Address; +import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv4DhcpServer; +import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv4DnsServer; +import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv4Netmask; +import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv6Address; +import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv6DnsServer; +import android.net.ipsec.ike.TunnelModeChildSessionParams.TunnelModeChildConfigRequest; import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; +import java.net.Inet4Address; import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) @@ -137,4 +153,78 @@ public class ChildSessionParamsTest extends IkeTestBase { verifyTunnelModeChildParamsWithCustomizedValues(childParams); } + + @Test + public void testBuildChildSessionParamsWithConfigReq() { + TunnelModeChildSessionParams childParams = + new TunnelModeChildSessionParams.Builder() + .addSaProposal(mSaProposal) + .addInternalAddressRequest(AF_INET) + .addInternalAddressRequest(AF_INET6) + .addInternalAddressRequest(AF_INET6) + .addInternalAddressRequest(IPV4_ADDRESS_REMOTE) + .addInternalAddressRequest(IPV6_ADDRESS_REMOTE, IP6_PREFIX_LEN) + .addInternalDnsServerRequest(AF_INET) + .addInternalDnsServerRequest(AF_INET6) + .addInternalDhcpServerRequest(AF_INET) + .addInternalDhcpServerRequest(AF_INET) + .build(); + + verifyTunnelModeChildParamsWithDefaultValues(childParams); + + // Verify config request types and number of requests for each type + Map, Integer> expectedAttributeCounts = + new HashMap<>(); + expectedAttributeCounts.put(ConfigRequestIpv4Address.class, 2); + expectedAttributeCounts.put(ConfigRequestIpv6Address.class, 3); + expectedAttributeCounts.put(ConfigRequestIpv4Netmask.class, 1); + expectedAttributeCounts.put(ConfigRequestIpv4DnsServer.class, 1); + expectedAttributeCounts.put(ConfigRequestIpv6DnsServer.class, 1); + expectedAttributeCounts.put(ConfigRequestIpv4DhcpServer.class, 2); + verifyConfigRequestTypes(expectedAttributeCounts, childParams.getConfigurationRequests()); + + // Verify specific IPv4 address request + Set expectedV4Addresses = new HashSet<>(); + expectedV4Addresses.add(IPV4_ADDRESS_REMOTE); + verifySpecificV4AddrConfigReq(expectedV4Addresses, childParams); + + // Verify specific IPv6 address request + Set expectedV6Addresses = new HashSet<>(); + expectedV6Addresses.add(new LinkAddress(IPV6_ADDRESS_REMOTE, IP6_PREFIX_LEN)); + verifySpecificV6AddrConfigReq(expectedV6Addresses, childParams); + } + + protected void verifySpecificV4AddrConfigReq( + Set expectedAddresses, TunnelModeChildSessionParams childParams) { + for (TunnelModeChildConfigRequest req : childParams.getConfigurationRequests()) { + if (req instanceof ConfigRequestIpv4Address + && ((ConfigRequestIpv4Address) req).getAddress() != null) { + Inet4Address address = ((ConfigRequestIpv4Address) req).getAddress(); + + // Fail if expectedAddresses does not contain this address + assertTrue(expectedAddresses.remove(address)); + } + } + + // Fail if any expected address is not found in result + assertTrue(expectedAddresses.isEmpty()); + } + + protected void verifySpecificV6AddrConfigReq( + Set expectedAddresses, TunnelModeChildSessionParams childParams) { + for (TunnelModeChildConfigRequest req : childParams.getConfigurationRequests()) { + if (req instanceof ConfigRequestIpv6Address + && ((ConfigRequestIpv6Address) req).getAddress() != null) { + ConfigRequestIpv6Address ipv6AddrReq = (ConfigRequestIpv6Address) req; + + // Fail if expectedAddresses does not contain this address + LinkAddress address = + new LinkAddress(ipv6AddrReq.getAddress(), ipv6AddrReq.getPrefixLength()); + assertTrue(expectedAddresses.remove(address)); + } + } + + // Fail if any expected address is not found in result + assertTrue(expectedAddresses.isEmpty()); + } } diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java index d4b431e837..d3aa8d03d5 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java @@ -16,11 +16,17 @@ package android.net.ipsec.ike.cts; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + import android.net.InetAddresses; import android.net.ipsec.ike.IkeTrafficSelector; import java.net.Inet4Address; import java.net.Inet6Address; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** Shared parameters and util methods for testing different components of IKE */ abstract class IkeTestBase { @@ -80,4 +86,35 @@ abstract class IkeTestBase { OUTBOUND_TS_END_PORT, InetAddresses.parseNumericAddress("2001:db8:255::64"), InetAddresses.parseNumericAddress("2001:db8:255::255")); + + // Verify Config requests in TunnelModeChildSessionParams and IkeSessionParams + void verifyConfigRequestTypes( + Map, Integer> expectedReqCntMap, List resultReqList) { + Map, Integer> resultReqCntMap = new HashMap<>(); + + // Verify that every config request type in resultReqList is expected, and build + // resultReqCntMap at the same time + for (T resultReq : resultReqList) { + boolean isResultReqExpected = false; + + for (Class expectedReqInterface : expectedReqCntMap.keySet()) { + if (expectedReqInterface.isInstance(resultReq)) { + isResultReqExpected = true; + + resultReqCntMap.put( + expectedReqInterface, + resultReqCntMap.getOrDefault(expectedReqInterface, 0) + 1); + } + } + + if (!isResultReqExpected) { + fail("Failed due to unexpected config request " + resultReq); + } + } + + assertEquals(expectedReqCntMap, resultReqCntMap); + + // TODO: Think of a neat way to validate both counts and values in this method. Probably can + // build Runnables as validators for count and values. + } } From 1e16d9862c532a9aaab39c99ffb3a5f8bfc5466c Mon Sep 17 00:00:00 2001 From: Paul Hu Date: Thu, 16 Apr 2020 00:17:32 +0000 Subject: [PATCH 0881/1109] Add TetheringEventCallback CTS test Test APIs below: onOffloadStatusChanged(int) Bug: 153619369 Test: atests CtsTetheringTest Change-Id: Ia7edd0d3d8184e30373ac8b657299107ff9b4c1e Merged-In: Ia7edd0d3d8184e30373ac8b657299107ff9b4c1e (cherry picked from commit c1153b7348dac9d4f0b0ad89acf17e52d00e83b9, aosp/1284554) --- .../tethering/cts/TetheringManagerTest.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java index 193a5dc3a4..f430f22371 100644 --- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java +++ b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java @@ -15,6 +15,9 @@ */ package android.tethering.test; +import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED; +import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED; +import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED; import static android.net.TetheringManager.TETHERING_USB; import static android.net.TetheringManager.TETHERING_WIFI; @@ -273,6 +276,7 @@ public class TetheringManagerTest { ON_TETHERED_IFACES, ON_ERROR, ON_CLIENTS, + ON_OFFLOAD_STATUS, }; public static class CallbackValue { @@ -330,6 +334,11 @@ public class TetheringManagerTest { mCallbacks.add(new CallbackValue(CallbackType.ON_CLIENTS, clients, 0)); } + @Override + public void onOffloadStatusChanged(int status) { + mCallbacks.add(new CallbackValue(CallbackType.ON_OFFLOAD_STATUS, status, 0)); + } + public CallbackValue pollCallback() { try { return mCallbacks.poll(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS); @@ -382,6 +391,17 @@ public class TetheringManagerTest { } } + public void expectOneOfOffloadStatusChanged(int... offloadStatuses) { + while (true) { + final CallbackValue cv = pollCallback(); + if (cv == null) fail("No expected offload status change callback"); + if (cv.callbackType != CallbackType.ON_OFFLOAD_STATUS) continue; + + final int status = (int) cv.callbackParam; + for (int offloadStatus : offloadStatuses) if (offloadStatus == status) return; + } + } + public TetheringInterfaceRegexps getTetheringInterfaceRegexps() { return mTetherableRegex; } @@ -403,6 +423,7 @@ public class TetheringManagerTest { mTM.registerTetheringEventCallback(c -> c.run(), tetherEventCallback); tetherEventCallback.expectCallbackStarted(); + tetherEventCallback.expectOneOfOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); final TetheringInterfaceRegexps tetherableRegexs = tetherEventCallback.getTetheringInterfaceRegexps(); @@ -422,10 +443,14 @@ public class TetheringManagerTest { } tetherEventCallback.expectTetheredInterfacesChanged(wifiRegexs); + tetherEventCallback.expectOneOfOffloadStatusChanged( + TETHER_HARDWARE_OFFLOAD_STARTED, + TETHER_HARDWARE_OFFLOAD_FAILED); mTM.stopTethering(TETHERING_WIFI); tetherEventCallback.expectTetheredInterfacesChanged(null); + tetherEventCallback.expectOneOfOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); mTM.unregisterTetheringEventCallback(tetherEventCallback); } From 13301d025a340f69493e3c77880c32dd96b51170 Mon Sep 17 00:00:00 2001 From: Chiachang Wang Date: Thu, 16 Apr 2020 00:18:31 +0000 Subject: [PATCH 0882/1109] Add test for NetworkRequest#canBeSatisfiedBy Test: atest CtsNetTestCasesLatestSdk:android.net.cts.NetworkRequestTest on both Q and R device Bug: 153972141 Change-Id: I614963cdd5f26bf3d47246fdc9eb11e74d05a460 Merged-In: I614963cdd5f26bf3d47246fdc9eb11e74d05a460 (cherry picked from commit 8f9325fcf28c4248eb3eb4bf21ec6a103eec614a) --- .../android/net/cts/NetworkRequestTest.java | 45 ++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java index 8b97c8cb92..751418657f 100644 --- a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java @@ -16,8 +16,11 @@ package android.net.cts; +import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS; import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH; +import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; +import static android.net.NetworkCapabilities.TRANSPORT_VPN; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static org.junit.Assert.assertEquals; @@ -26,13 +29,12 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import android.net.MacAddress; +import android.net.NetworkCapabilities; import android.net.NetworkRequest; import android.net.NetworkSpecifier; -import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiNetworkSpecifier; import android.os.Build; import android.os.PatternMatcher; -import android.util.Pair; import androidx.test.runner.AndroidJUnit4; @@ -49,6 +51,7 @@ public class NetworkRequestTest { public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule(); private static final String TEST_SSID = "TestSSID"; + private static final String OTHER_SSID = "OtherSSID"; private static final int TEST_UID = 2097; private static final String TEST_PACKAGE_NAME = "test.package.name"; private static final MacAddress ARBITRARY_ADDRESS = MacAddress.fromString("3:5:8:12:9:2"); @@ -84,4 +87,42 @@ public class NetworkRequestTest { .getNetworkSpecifier(); assertEquals(obtainedSpecifier, specifier); } + + @Test + @IgnoreUpTo(Build.VERSION_CODES.Q) + public void testCanBeSatisfiedBy() { + final WifiNetworkSpecifier specifier1 = new WifiNetworkSpecifier.Builder() + .setSsidPattern(new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL)) + .setBssidPattern(ARBITRARY_ADDRESS, ARBITRARY_ADDRESS) + .build(); + final WifiNetworkSpecifier specifier2 = new WifiNetworkSpecifier.Builder() + .setSsidPattern(new PatternMatcher(OTHER_SSID, PatternMatcher.PATTERN_LITERAL)) + .setBssidPattern(ARBITRARY_ADDRESS, ARBITRARY_ADDRESS) + .build(); + final NetworkCapabilities cap = new NetworkCapabilities() + .addTransportType(TRANSPORT_WIFI) + .addCapability(NET_CAPABILITY_INTERNET); + final NetworkCapabilities capWithSp = + new NetworkCapabilities(cap).setNetworkSpecifier(specifier1); + final NetworkCapabilities cellCap = new NetworkCapabilities() + .addTransportType(TRANSPORT_CELLULAR) + .addCapability(NET_CAPABILITY_MMS) + .addCapability(NET_CAPABILITY_INTERNET); + final NetworkRequest request = new NetworkRequest.Builder() + .addTransportType(TRANSPORT_WIFI) + .addCapability(NET_CAPABILITY_INTERNET) + .setNetworkSpecifier(specifier1) + .build(); + assertFalse(request.canBeSatisfiedBy(null)); + assertFalse(request.canBeSatisfiedBy(new NetworkCapabilities())); + assertTrue(request.canBeSatisfiedBy(cap)); + assertTrue(request.canBeSatisfiedBy( + new NetworkCapabilities(cap).addTransportType(TRANSPORT_VPN))); + assertTrue(request.canBeSatisfiedBy(capWithSp)); + assertFalse(request.canBeSatisfiedBy( + new NetworkCapabilities(cap).setNetworkSpecifier(specifier2))); + assertFalse(request.canBeSatisfiedBy(cellCap)); + assertEquals(request.canBeSatisfiedBy(capWithSp), + new NetworkCapabilities(capWithSp).satisfiedByNetworkCapabilities(capWithSp)); + } } From 3936e08f650fad6d7a3c3a57c5ec2ec562992a51 Mon Sep 17 00:00:00 2001 From: paulhu Date: Tue, 14 Apr 2020 15:16:46 +0800 Subject: [PATCH 0883/1109] Add EntitlementResult CTS tests Test APIs below: requestLatestTetheringEntitlementResult(int, boolean, java.util.concurrent.Executor, android.net.TetheringManager.OnTetheringEntitlementResultListener) requestLatestTetheringEntitlementResult(int, android.os.ResultReceiver, boolean) OnTetheringEntitlementResultListener.onTetheringEntitlementResult(int) Bug: 152829363 Test: atests CtsTetheringTest Change-Id: Icf0d9cacd97eeaa7ceb78f4924c5a6be6e588b30 --- .../tethering/cts/TetheringManagerTest.java | 60 ++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java index f430f22371..ccad14cdd2 100644 --- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java +++ b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java @@ -20,6 +20,8 @@ import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED; import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED; import static android.net.TetheringManager.TETHERING_USB; import static android.net.TetheringManager.TETHERING_WIFI; +import static android.net.TetheringManager.TETHERING_WIFI_P2P; +import static android.net.TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -35,9 +37,12 @@ import android.net.LinkAddress; import android.net.Network; import android.net.TetheredClient; import android.net.TetheringManager; +import android.net.TetheringManager.OnTetheringEntitlementResultListener; import android.net.TetheringManager.TetheringEventCallback; import android.net.TetheringManager.TetheringInterfaceRegexps; import android.net.TetheringManager.TetheringRequest; +import android.os.Bundle; +import android.os.ResultReceiver; import androidx.annotation.NonNull; import androidx.test.InstrumentationRegistry; @@ -52,8 +57,12 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.function.Consumer; @RunWith(AndroidJUnit4.class) public class TetheringManagerTest { @@ -472,11 +481,60 @@ public class TetheringManagerTest { assertEquals(usbRegexs, Arrays.asList(mTM.getTetherableUsbRegexs())); assertEquals(btRegexs, Arrays.asList(mTM.getTetherableBluetoothRegexs())); - //Verify that any of interface name should only contain in one array. + //Verify that any regex name should only contain in one array. wifiRegexs.forEach(s -> assertFalse(usbRegexs.contains(s))); wifiRegexs.forEach(s -> assertFalse(btRegexs.contains(s))); usbRegexs.forEach(s -> assertFalse(btRegexs.contains(s))); mTM.unregisterTetheringEventCallback(tetherEventCallback); } + + private class EntitlementResultListener implements OnTetheringEntitlementResultListener { + private final CompletableFuture future = new CompletableFuture<>(); + + @Override + public void onTetheringEntitlementResult(int result) { + future.complete(result); + } + + public int get(long timeout, TimeUnit unit) throws Exception { + return future.get(timeout, unit); + } + + } + + private void assertEntitlementResult(final Consumer functor, + final int expect) throws Exception { + final EntitlementResultListener listener = new EntitlementResultListener(); + functor.accept(listener); + + assertEquals(expect, listener.get(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS)); + } + + @Test + public void testRequestLatestEntitlementResult() throws Exception { + // Verify that requestLatestTetheringEntitlementResult() can get entitlement + // result(TETHER_ERROR_ENTITLEMENT_UNKNOWN due to invalid downstream type) via listener. + assertEntitlementResult(listener -> mTM.requestLatestTetheringEntitlementResult( + TETHERING_WIFI_P2P, false, c -> c.run(), listener), + TETHER_ERROR_ENTITLEMENT_UNKNOWN); + + // Verify that requestLatestTetheringEntitlementResult() can get entitlement + // result(TETHER_ERROR_ENTITLEMENT_UNKNOWN due to invalid downstream type) via receiver. + assertEntitlementResult(listener -> mTM.requestLatestTetheringEntitlementResult( + TETHERING_WIFI_P2P, + new ResultReceiver(null /* handler */) { + @Override + public void onReceiveResult(int resultCode, Bundle resultData) { + listener.onTetheringEntitlementResult(resultCode); + } + }, false), + TETHER_ERROR_ENTITLEMENT_UNKNOWN); + + // Verify that null listener will cause IllegalArgumentException. + try { + mTM.requestLatestTetheringEntitlementResult( + TETHERING_WIFI, false, c -> c.run(), null); + } catch (IllegalArgumentException expect) { } + } } From 5585672f92d679911a461fa37a994b83e5c0bad1 Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Mon, 30 Mar 2020 17:30:46 +0800 Subject: [PATCH 0884/1109] Add tests for NetworkRequest API This change inculdes coverage of NetworkRequest#Builder().clearCapabilities() and NetworkRequest#getRequestorPackageName() Bug: 153614623 Test: atest CtsNetTestCasesLatestSdk:android.net.cts.NetworkRequestTest Change-Id: Id4e31013cfae78c25abd27b557da4e3e9487870c --- .../android/net/cts/NetworkRequestTest.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java index 751418657f..08bf1e424b 100644 --- a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java @@ -62,6 +62,18 @@ public class NetworkRequestTest { .hasCapability(NET_CAPABILITY_MMS)); assertFalse(new NetworkRequest.Builder().removeCapability(NET_CAPABILITY_MMS).build() .hasCapability(NET_CAPABILITY_MMS)); + + final NetworkRequest nr = new NetworkRequest.Builder().clearCapabilities().build(); + // Verify request has no capabilities + verifyNoCapabilities(nr); + } + + private void verifyNoCapabilities(NetworkRequest nr) { + // NetworkCapabilities.mNetworkCapabilities is defined as type long + final int MAX_POSSIBLE_CAPABILITY = Long.SIZE; + for(int bit = 0; bit < MAX_POSSIBLE_CAPABILITY; bit++) { + assertFalse(nr.hasCapability(bit)); + } } @Test @@ -86,6 +98,29 @@ public class NetworkRequestTest { .build() .getNetworkSpecifier(); assertEquals(obtainedSpecifier, specifier); + + assertNull(new NetworkRequest.Builder() + .clearCapabilities() + .build() + .getNetworkSpecifier()); + } + + @Test + @IgnoreUpTo(Build.VERSION_CODES.Q) + public void testRequestorPackageName() { + assertNull(new NetworkRequest.Builder().build().getRequestorPackageName()); + final String pkgName = "android.net.test"; + final NetworkCapabilities nc = new NetworkCapabilities.Builder() + .setRequestorPackageName(pkgName) + .build(); + final NetworkRequest nr = new NetworkRequest.Builder() + .setCapabilities(nc) + .build(); + assertEquals(pkgName, nr.getRequestorPackageName()); + assertNull(new NetworkRequest.Builder() + .clearCapabilities() + .build() + .getRequestorPackageName()); } @Test From 85f0fca1f071250fcb8f286e6bca30d0fcd8a965 Mon Sep 17 00:00:00 2001 From: paulhu Date: Fri, 10 Apr 2020 11:09:14 +0800 Subject: [PATCH 0885/1109] Add more tests to CtsTetheringTest Add TetheringIntegrationTests into CtsTetheringTest Bug: 148636687 Test: atest CtsTetheringTest atest TetheringIntegrationTests Change-Id: I606097a8db9ed3d2b3eaf933bb1d904e437ab27d --- tests/cts/tethering/Android.bp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/cts/tethering/Android.bp b/tests/cts/tethering/Android.bp index 0f98125d6f..63de301d69 100644 --- a/tests/cts/tethering/Android.bp +++ b/tests/cts/tethering/Android.bp @@ -25,12 +25,19 @@ android_test { ], static_libs: [ + "TetheringIntegrationTestsLib", "compatibility-device-util-axt", "ctstestrunner-axt", "junit", "junit-params", ], + jni_libs: [ + // For mockito extended + "libdexmakerjvmtiagent", + "libstaticjvmtiagent", + ], + // Change to system current when TetheringManager move to bootclass path. platform_apis: true, @@ -41,4 +48,6 @@ android_test { "mts", ], + // Include both the 32 and 64 bit versions + compile_multilib: "both", } From bbc5554392548ebebc09c9469b03353b35c4f9f4 Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Fri, 20 Mar 2020 16:36:24 +0800 Subject: [PATCH 0886/1109] Add test for NetworkRequest#getRequestorUid() Add test for new API. Bug: 151110379 Test: atest CtsNetTestCasesLatestSdk:android.net.cts.NetworkRequestTest Change-Id: I9602cac142b3e45d12e66a6f3f35ab594e6590c1 --- .../src/android/net/cts/NetworkRequestTest.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java index 08bf1e424b..6a1d9de6f6 100644 --- a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java @@ -34,6 +34,7 @@ import android.net.NetworkRequest; import android.net.NetworkSpecifier; import android.net.wifi.WifiNetworkSpecifier; import android.os.Build; +import android.os.Process; import android.os.PatternMatcher; import androidx.test.runner.AndroidJUnit4; @@ -160,4 +161,19 @@ public class NetworkRequestTest { assertEquals(request.canBeSatisfiedBy(capWithSp), new NetworkCapabilities(capWithSp).satisfiedByNetworkCapabilities(capWithSp)); } + + @Test @IgnoreUpTo(Build.VERSION_CODES.Q) + public void testRequestorUid() { + final NetworkCapabilities nc = new NetworkCapabilities(); + // Verify default value is INVALID_UID + assertEquals(Process.INVALID_UID, new NetworkRequest.Builder() + .setCapabilities(nc).build().getRequestorUid()); + + nc.setRequestorUid(1314); + final NetworkRequest nr = new NetworkRequest.Builder().setCapabilities(nc).build(); + assertEquals(1314, nr.getRequestorUid()); + + assertEquals(Process.INVALID_UID, new NetworkRequest.Builder() + .clearCapabilities().build().getRequestorUid()); + } } From 23e025e47ccb0b2f19d2dc428809880331d760e0 Mon Sep 17 00:00:00 2001 From: Yan Yan Date: Thu, 16 Apr 2020 00:19:16 +0000 Subject: [PATCH 0887/1109] Create TestNetworkUtils for IKE and IPsec CTS Create TestNetworkUtils that provides interfaces to set up test network. It will be used by both IKE and IPsec CTS Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: I1c49711d3c6ce03ceafdbf3004e25d9d59a6201c Merged-In: I1c49711d3c6ce03ceafdbf3004e25d9d59a6201c (cherry picked from commit 91b034d5c649d8b7de1ff6d936f4859f927eb202) --- .../net/ipsec/ike/cts/TestNetworkUtils.java | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TestNetworkUtils.java diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TestNetworkUtils.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TestNetworkUtils.java new file mode 100644 index 0000000000..5b08cdc8f2 --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TestNetworkUtils.java @@ -0,0 +1,87 @@ +/* + * 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.ipsec.ike.cts; + +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; +import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED; +import static android.net.NetworkCapabilities.TRANSPORT_TEST; + +import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkRequest; +import android.net.TestNetworkManager; +import android.os.IBinder; +import android.os.RemoteException; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; + +// TODO(b/148689509): Share this class with net CTS test (e.g. IpSecManagerTunnelTest) +public class TestNetworkUtils { + private static final int TIMEOUT_MS = 500; + + /** Callback to receive requested test network. */ + public static class TestNetworkCallback extends ConnectivityManager.NetworkCallback { + private final CompletableFuture futureNetwork = new CompletableFuture<>(); + + @Override + public void onAvailable(Network network) { + futureNetwork.complete(network); + } + + public Network getNetworkBlocking() throws Exception { + return futureNetwork.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); + } + } + + /** + * Set up test network. + * + *

    Caller MUST have MANAGE_TEST_NETWORKS permission to use this method. + * + * @param connMgr ConnectivityManager to request network. + * @param testNetworkMgr TestNetworkManager to set up test network. + * @param ifname the name of the interface to be used for the Network LinkProperties. + * @param binder a binder object guarding the lifecycle of this test network. + * @return TestNetworkCallback to retrieve the test network. + * @throws RemoteException if test network setup failed. + * @see android.net.TestNetworkManager + */ + public static TestNetworkCallback setupAndGetTestNetwork( + ConnectivityManager connMgr, + TestNetworkManager testNetworkMgr, + String ifname, + IBinder binder) + throws RemoteException { + NetworkRequest nr = + new NetworkRequest.Builder() + .addTransportType(TRANSPORT_TEST) + .removeCapability(NET_CAPABILITY_TRUSTED) + .removeCapability(NET_CAPABILITY_NOT_VPN) + .setNetworkSpecifier(ifname) + .build(); + + TestNetworkCallback cb = new TestNetworkCallback(); + connMgr.requestNetwork(nr, cb); + + // Setup the test network after network request is filed to prevent Network from being + // reaped due to no requests matching it. + testNetworkMgr.setupTestNetwork(ifname, binder); + + return cb; + } +} From 8d10ebe3d70964c3dd5fc0fe3adfe20d045290fe Mon Sep 17 00:00:00 2001 From: Treehugger Robot Date: Fri, 17 Apr 2020 06:10:14 +0000 Subject: [PATCH 0888/1109] Add EntitlementResult CTS tests Test APIs below: requestLatestTetheringEntitlementResult(int, boolean, java.util.concurrent.Executor, android.net.TetheringManager.OnTetheringEntitlementResultListener) requestLatestTetheringEntitlementResult(int, android.os.ResultReceiver, boolean) OnTetheringEntitlementResultListener.onTetheringEntitlementResult(int) Bug: 152829363 Test: atests CtsTetheringTest Change-Id: Icf0d9cacd97eeaa7ceb78f4924c5a6be6e588b30 Merged-In: Icf0d9cacd97eeaa7ceb78f4924c5a6be6e588b30 (cherry picked from commit 4bed8dff67d4a6824098188cd9602668d8705a7e, aosp/1272946) --- .../tethering/cts/TetheringManagerTest.java | 60 ++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java index f430f22371..ccad14cdd2 100644 --- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java +++ b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java @@ -20,6 +20,8 @@ import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED; import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED; import static android.net.TetheringManager.TETHERING_USB; import static android.net.TetheringManager.TETHERING_WIFI; +import static android.net.TetheringManager.TETHERING_WIFI_P2P; +import static android.net.TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -35,9 +37,12 @@ import android.net.LinkAddress; import android.net.Network; import android.net.TetheredClient; import android.net.TetheringManager; +import android.net.TetheringManager.OnTetheringEntitlementResultListener; import android.net.TetheringManager.TetheringEventCallback; import android.net.TetheringManager.TetheringInterfaceRegexps; import android.net.TetheringManager.TetheringRequest; +import android.os.Bundle; +import android.os.ResultReceiver; import androidx.annotation.NonNull; import androidx.test.InstrumentationRegistry; @@ -52,8 +57,12 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.function.Consumer; @RunWith(AndroidJUnit4.class) public class TetheringManagerTest { @@ -472,11 +481,60 @@ public class TetheringManagerTest { assertEquals(usbRegexs, Arrays.asList(mTM.getTetherableUsbRegexs())); assertEquals(btRegexs, Arrays.asList(mTM.getTetherableBluetoothRegexs())); - //Verify that any of interface name should only contain in one array. + //Verify that any regex name should only contain in one array. wifiRegexs.forEach(s -> assertFalse(usbRegexs.contains(s))); wifiRegexs.forEach(s -> assertFalse(btRegexs.contains(s))); usbRegexs.forEach(s -> assertFalse(btRegexs.contains(s))); mTM.unregisterTetheringEventCallback(tetherEventCallback); } + + private class EntitlementResultListener implements OnTetheringEntitlementResultListener { + private final CompletableFuture future = new CompletableFuture<>(); + + @Override + public void onTetheringEntitlementResult(int result) { + future.complete(result); + } + + public int get(long timeout, TimeUnit unit) throws Exception { + return future.get(timeout, unit); + } + + } + + private void assertEntitlementResult(final Consumer functor, + final int expect) throws Exception { + final EntitlementResultListener listener = new EntitlementResultListener(); + functor.accept(listener); + + assertEquals(expect, listener.get(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS)); + } + + @Test + public void testRequestLatestEntitlementResult() throws Exception { + // Verify that requestLatestTetheringEntitlementResult() can get entitlement + // result(TETHER_ERROR_ENTITLEMENT_UNKNOWN due to invalid downstream type) via listener. + assertEntitlementResult(listener -> mTM.requestLatestTetheringEntitlementResult( + TETHERING_WIFI_P2P, false, c -> c.run(), listener), + TETHER_ERROR_ENTITLEMENT_UNKNOWN); + + // Verify that requestLatestTetheringEntitlementResult() can get entitlement + // result(TETHER_ERROR_ENTITLEMENT_UNKNOWN due to invalid downstream type) via receiver. + assertEntitlementResult(listener -> mTM.requestLatestTetheringEntitlementResult( + TETHERING_WIFI_P2P, + new ResultReceiver(null /* handler */) { + @Override + public void onReceiveResult(int resultCode, Bundle resultData) { + listener.onTetheringEntitlementResult(resultCode); + } + }, false), + TETHER_ERROR_ENTITLEMENT_UNKNOWN); + + // Verify that null listener will cause IllegalArgumentException. + try { + mTM.requestLatestTetheringEntitlementResult( + TETHERING_WIFI, false, c -> c.run(), null); + } catch (IllegalArgumentException expect) { } + } } From 685f072bfde95cf5e38e5406bfa8365ad2c141b5 Mon Sep 17 00:00:00 2001 From: Treehugger Robot Date: Fri, 17 Apr 2020 06:10:36 +0000 Subject: [PATCH 0889/1109] Add more tests to CtsTetheringTest Add TetheringIntegrationTests into CtsTetheringTest Bug: 148636687 Test: atest CtsTetheringTest atest TetheringIntegrationTests Change-Id: I606097a8db9ed3d2b3eaf933bb1d904e437ab27d Merged-In: I606097a8db9ed3d2b3eaf933bb1d904e437ab27d (cherry picked from commit 1f7305c9740a7a1a724c4023f8c55ce827391f73, aosp/1280233) --- tests/cts/tethering/Android.bp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/cts/tethering/Android.bp b/tests/cts/tethering/Android.bp index 0f98125d6f..63de301d69 100644 --- a/tests/cts/tethering/Android.bp +++ b/tests/cts/tethering/Android.bp @@ -25,12 +25,19 @@ android_test { ], static_libs: [ + "TetheringIntegrationTestsLib", "compatibility-device-util-axt", "ctstestrunner-axt", "junit", "junit-params", ], + jni_libs: [ + // For mockito extended + "libdexmakerjvmtiagent", + "libstaticjvmtiagent", + ], + // Change to system current when TetheringManager move to bootclass path. platform_apis: true, @@ -41,4 +48,6 @@ android_test { "mts", ], + // Include both the 32 and 64 bit versions + compile_multilib: "both", } From 48e081279645d56fbe0ad57aaedd1b8c298a6f8d Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Fri, 17 Apr 2020 17:48:53 +0800 Subject: [PATCH 0890/1109] Move DhcpInfoTest to FrameworksNetCommonTests Move to frameworks/base/tests/net/common so that it can be run in cts test and presubmit test. Bug: 154299158 Test: atest CtsNetTestCasesLatestSdk:android.net.DhcpInfoTest Change-Id: I8d70565fe3388fd8351002f2ed87c43343879e57 --- .../net/src/android/net/cts/DhcpInfoTest.java | 114 ------------------ 1 file changed, 114 deletions(-) delete mode 100644 tests/cts/net/src/android/net/cts/DhcpInfoTest.java diff --git a/tests/cts/net/src/android/net/cts/DhcpInfoTest.java b/tests/cts/net/src/android/net/cts/DhcpInfoTest.java deleted file mode 100644 index b8d239272a..0000000000 --- a/tests/cts/net/src/android/net/cts/DhcpInfoTest.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2009 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 static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTL; - -import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals; -import static com.android.testutils.ParcelUtilsKt.parcelingRoundTrip; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import android.annotation.Nullable; -import android.net.DhcpInfo; - -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.Inet4Address; -import java.net.InetAddress; - -@RunWith(AndroidJUnit4.class) -public class DhcpInfoTest { - private static final String STR_ADDR1 = "255.255.255.255"; - private static final String STR_ADDR2 = "127.0.0.1"; - private static final String STR_ADDR3 = "192.168.1.1"; - private static final String STR_ADDR4 = "192.168.1.0"; - private static final int LEASE_TIME = 9999; - - private int ipToInteger(String ipString) throws Exception { - return inet4AddressToIntHTL((Inet4Address) InetAddress.getByName(ipString)); - } - - private DhcpInfo createDhcpInfoObject() throws Exception { - final DhcpInfo dhcpInfo = new DhcpInfo(); - dhcpInfo.ipAddress = ipToInteger(STR_ADDR1); - dhcpInfo.gateway = ipToInteger(STR_ADDR2); - dhcpInfo.netmask = ipToInteger(STR_ADDR3); - dhcpInfo.dns1 = ipToInteger(STR_ADDR4); - dhcpInfo.dns2 = ipToInteger(STR_ADDR4); - dhcpInfo.serverAddress = ipToInteger(STR_ADDR2); - dhcpInfo.leaseDuration = LEASE_TIME; - return dhcpInfo; - } - - @Test - public void testConstructor() { - new DhcpInfo(); - } - - @Test - public void testToString() throws Exception { - final String expectedDefault = "ipaddr 0.0.0.0 gateway 0.0.0.0 netmask 0.0.0.0 " - + "dns1 0.0.0.0 dns2 0.0.0.0 DHCP server 0.0.0.0 lease 0 seconds"; - - DhcpInfo dhcpInfo = new DhcpInfo(); - - // Test default string. - assertEquals(expectedDefault, dhcpInfo.toString()); - - dhcpInfo = createDhcpInfoObject(); - - final String expected = "ipaddr " + STR_ADDR1 + " gateway " + STR_ADDR2 + " netmask " - + STR_ADDR3 + " dns1 " + STR_ADDR4 + " dns2 " + STR_ADDR4 + " DHCP server " - + STR_ADDR2 + " lease " + LEASE_TIME + " seconds"; - // Test with new values - assertEquals(expected, dhcpInfo.toString()); - } - - private boolean dhcpInfoEquals(@Nullable DhcpInfo left, @Nullable DhcpInfo right) { - if (left == null && right == null) return true; - - if (left == null || right == null) return false; - - return left.ipAddress == right.ipAddress - && left.gateway == right.gateway - && left.netmask == right.netmask - && left.dns1 == right.dns1 - && left.dns2 == right.dns2 - && left.serverAddress == right.serverAddress - && left.leaseDuration == right.leaseDuration; - } - - @Test - public void testParcelDhcpInfo() throws Exception { - // Cannot use assertParcelSane() here because this requires .equals() to work as - // defined, but DhcpInfo has a different legacy behavior that we cannot change. - final DhcpInfo dhcpInfo = createDhcpInfoObject(); - assertFieldCountEquals(7, DhcpInfo.class); - - final DhcpInfo dhcpInfoRoundTrip = parcelingRoundTrip(dhcpInfo); - assertTrue(dhcpInfoEquals(null, null)); - assertFalse(dhcpInfoEquals(null, dhcpInfoRoundTrip)); - assertFalse(dhcpInfoEquals(dhcpInfo, null)); - assertTrue(dhcpInfoEquals(dhcpInfo, dhcpInfoRoundTrip)); - } -} From dacbdaa3787d5bf67124ca9fdb564765644a8479 Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Mon, 30 Mar 2020 17:30:46 +0800 Subject: [PATCH 0891/1109] Add tests for NetworkRequest API This change inculdes coverage of NetworkRequest#Builder().clearCapabilities() and NetworkRequest#getRequestorPackageName() Bug: 153614623 Test: atest CtsNetTestCasesLatestSdk:android.net.cts.NetworkRequestTest Change-Id: Id4e31013cfae78c25abd27b557da4e3e9487870c Merged-In: Id4e31013cfae78c25abd27b557da4e3e9487870c --- .../android/net/cts/NetworkRequestTest.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java index 751418657f..08bf1e424b 100644 --- a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java @@ -62,6 +62,18 @@ public class NetworkRequestTest { .hasCapability(NET_CAPABILITY_MMS)); assertFalse(new NetworkRequest.Builder().removeCapability(NET_CAPABILITY_MMS).build() .hasCapability(NET_CAPABILITY_MMS)); + + final NetworkRequest nr = new NetworkRequest.Builder().clearCapabilities().build(); + // Verify request has no capabilities + verifyNoCapabilities(nr); + } + + private void verifyNoCapabilities(NetworkRequest nr) { + // NetworkCapabilities.mNetworkCapabilities is defined as type long + final int MAX_POSSIBLE_CAPABILITY = Long.SIZE; + for(int bit = 0; bit < MAX_POSSIBLE_CAPABILITY; bit++) { + assertFalse(nr.hasCapability(bit)); + } } @Test @@ -86,6 +98,29 @@ public class NetworkRequestTest { .build() .getNetworkSpecifier(); assertEquals(obtainedSpecifier, specifier); + + assertNull(new NetworkRequest.Builder() + .clearCapabilities() + .build() + .getNetworkSpecifier()); + } + + @Test + @IgnoreUpTo(Build.VERSION_CODES.Q) + public void testRequestorPackageName() { + assertNull(new NetworkRequest.Builder().build().getRequestorPackageName()); + final String pkgName = "android.net.test"; + final NetworkCapabilities nc = new NetworkCapabilities.Builder() + .setRequestorPackageName(pkgName) + .build(); + final NetworkRequest nr = new NetworkRequest.Builder() + .setCapabilities(nc) + .build(); + assertEquals(pkgName, nr.getRequestorPackageName()); + assertNull(new NetworkRequest.Builder() + .clearCapabilities() + .build() + .getRequestorPackageName()); } @Test From d1e528ae9cb3157d71ee0b200b6f257dddf58f0d Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Fri, 20 Mar 2020 16:36:24 +0800 Subject: [PATCH 0892/1109] Add test for NetworkRequest#getRequestorUid() Add test for new API. Bug: 151110379 Test: atest CtsNetTestCasesLatestSdk:android.net.cts.NetworkRequestTest Change-Id: I9602cac142b3e45d12e66a6f3f35ab594e6590c1 Merged-In: I9602cac142b3e45d12e66a6f3f35ab594e6590c1 --- .../src/android/net/cts/NetworkRequestTest.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java index 08bf1e424b..6a1d9de6f6 100644 --- a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java @@ -34,6 +34,7 @@ import android.net.NetworkRequest; import android.net.NetworkSpecifier; import android.net.wifi.WifiNetworkSpecifier; import android.os.Build; +import android.os.Process; import android.os.PatternMatcher; import androidx.test.runner.AndroidJUnit4; @@ -160,4 +161,19 @@ public class NetworkRequestTest { assertEquals(request.canBeSatisfiedBy(capWithSp), new NetworkCapabilities(capWithSp).satisfiedByNetworkCapabilities(capWithSp)); } + + @Test @IgnoreUpTo(Build.VERSION_CODES.Q) + public void testRequestorUid() { + final NetworkCapabilities nc = new NetworkCapabilities(); + // Verify default value is INVALID_UID + assertEquals(Process.INVALID_UID, new NetworkRequest.Builder() + .setCapabilities(nc).build().getRequestorUid()); + + nc.setRequestorUid(1314); + final NetworkRequest nr = new NetworkRequest.Builder().setCapabilities(nc).build(); + assertEquals(1314, nr.getRequestorUid()); + + assertEquals(Process.INVALID_UID, new NetworkRequest.Builder() + .clearCapabilities().build().getRequestorUid()); + } } From 170e87344294314a892ab477d5ffcf6f66894093 Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Fri, 17 Apr 2020 16:26:45 +0000 Subject: [PATCH 0893/1109] Move DhcpInfoTest to FrameworksNetCommonTests Move to frameworks/base/tests/net/common so that it can be run in cts test and presubmit test. Bug: 154299158 Test: atest CtsNetTestCasesLatestSdk:android.net.DhcpInfoTest Change-Id: I1052c2b46ce427102429c3c7d8cf25f3e79f2789 Merged-In: I8d70565fe3388fd8351002f2ed87c43343879e57 --- .../net/src/android/net/cts/DhcpInfoTest.java | 114 ------------------ 1 file changed, 114 deletions(-) delete mode 100644 tests/cts/net/src/android/net/cts/DhcpInfoTest.java diff --git a/tests/cts/net/src/android/net/cts/DhcpInfoTest.java b/tests/cts/net/src/android/net/cts/DhcpInfoTest.java deleted file mode 100644 index b8d239272a..0000000000 --- a/tests/cts/net/src/android/net/cts/DhcpInfoTest.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2009 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 static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTL; - -import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals; -import static com.android.testutils.ParcelUtilsKt.parcelingRoundTrip; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import android.annotation.Nullable; -import android.net.DhcpInfo; - -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.net.Inet4Address; -import java.net.InetAddress; - -@RunWith(AndroidJUnit4.class) -public class DhcpInfoTest { - private static final String STR_ADDR1 = "255.255.255.255"; - private static final String STR_ADDR2 = "127.0.0.1"; - private static final String STR_ADDR3 = "192.168.1.1"; - private static final String STR_ADDR4 = "192.168.1.0"; - private static final int LEASE_TIME = 9999; - - private int ipToInteger(String ipString) throws Exception { - return inet4AddressToIntHTL((Inet4Address) InetAddress.getByName(ipString)); - } - - private DhcpInfo createDhcpInfoObject() throws Exception { - final DhcpInfo dhcpInfo = new DhcpInfo(); - dhcpInfo.ipAddress = ipToInteger(STR_ADDR1); - dhcpInfo.gateway = ipToInteger(STR_ADDR2); - dhcpInfo.netmask = ipToInteger(STR_ADDR3); - dhcpInfo.dns1 = ipToInteger(STR_ADDR4); - dhcpInfo.dns2 = ipToInteger(STR_ADDR4); - dhcpInfo.serverAddress = ipToInteger(STR_ADDR2); - dhcpInfo.leaseDuration = LEASE_TIME; - return dhcpInfo; - } - - @Test - public void testConstructor() { - new DhcpInfo(); - } - - @Test - public void testToString() throws Exception { - final String expectedDefault = "ipaddr 0.0.0.0 gateway 0.0.0.0 netmask 0.0.0.0 " - + "dns1 0.0.0.0 dns2 0.0.0.0 DHCP server 0.0.0.0 lease 0 seconds"; - - DhcpInfo dhcpInfo = new DhcpInfo(); - - // Test default string. - assertEquals(expectedDefault, dhcpInfo.toString()); - - dhcpInfo = createDhcpInfoObject(); - - final String expected = "ipaddr " + STR_ADDR1 + " gateway " + STR_ADDR2 + " netmask " - + STR_ADDR3 + " dns1 " + STR_ADDR4 + " dns2 " + STR_ADDR4 + " DHCP server " - + STR_ADDR2 + " lease " + LEASE_TIME + " seconds"; - // Test with new values - assertEquals(expected, dhcpInfo.toString()); - } - - private boolean dhcpInfoEquals(@Nullable DhcpInfo left, @Nullable DhcpInfo right) { - if (left == null && right == null) return true; - - if (left == null || right == null) return false; - - return left.ipAddress == right.ipAddress - && left.gateway == right.gateway - && left.netmask == right.netmask - && left.dns1 == right.dns1 - && left.dns2 == right.dns2 - && left.serverAddress == right.serverAddress - && left.leaseDuration == right.leaseDuration; - } - - @Test - public void testParcelDhcpInfo() throws Exception { - // Cannot use assertParcelSane() here because this requires .equals() to work as - // defined, but DhcpInfo has a different legacy behavior that we cannot change. - final DhcpInfo dhcpInfo = createDhcpInfoObject(); - assertFieldCountEquals(7, DhcpInfo.class); - - final DhcpInfo dhcpInfoRoundTrip = parcelingRoundTrip(dhcpInfo); - assertTrue(dhcpInfoEquals(null, null)); - assertFalse(dhcpInfoEquals(null, dhcpInfoRoundTrip)); - assertFalse(dhcpInfoEquals(dhcpInfo, null)); - assertTrue(dhcpInfoEquals(dhcpInfo, dhcpInfoRoundTrip)); - } -} From 21ec1de1ff8bbc96c1ca42463e84c82f22de2c03 Mon Sep 17 00:00:00 2001 From: Chiachang Wang Date: Fri, 17 Apr 2020 17:26:51 +0800 Subject: [PATCH 0894/1109] Update network object when wifi meterness is changed The new wifi disconnect behavior is introduced. When wifi network is changed from unmetered to metered, the wifi network will disconnect and reconnect. Update the test to verify the same SSID wifi is connected and also update the target network to verfiy the metered preference. Bug: 153400606 Test: atest CtsNetTestCases:android.net.cts.ConnectivityManagerTest\ #testGetMultipathPreference Change-Id: Ic298d3d85d8c6b77c8df7614a945f2c22dcdff38 --- .../net/src/android/net/cts/ConnectivityManagerTest.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index fa7e1381b3..3a52ee60a3 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -709,7 +709,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { @AppModeFull(reason = "Cannot get WifiManager in instant app mode") public void testGetMultipathPreference() throws Exception { final ContentResolver resolver = mContext.getContentResolver(); - final Network network = ensureWifiConnected(); + ensureWifiConnected(); final String ssid = unquoteSSID(mWifiManager.getConnectionInfo().getSSID()); final String oldMeteredSetting = getWifiMeteredStatus(ssid); final String oldMeteredMultipathPreference = Settings.Global.getString( @@ -721,6 +721,10 @@ public class ConnectivityManagerTest extends AndroidTestCase { Integer.toString(newMeteredPreference)); setWifiMeteredStatus(ssid, "true"); waitForActiveNetworkMetered(true); + // Wifi meterness changes from unmetered to metered will disconnect and reconnect since + // R. + final Network network = mCm.getActiveNetwork(); + assertEquals(ssid, unquoteSSID(mWifiManager.getConnectionInfo().getSSID())); assertEquals(mCm.getNetworkCapabilities(network).hasCapability( NET_CAPABILITY_NOT_METERED), false); assertMultipathPreferenceIsEventually(network, initialMeteredPreference, @@ -736,6 +740,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { oldMeteredPreference, newMeteredPreference); setWifiMeteredStatus(ssid, "false"); + // No disconnect from unmetered to metered. waitForActiveNetworkMetered(false); assertEquals(mCm.getNetworkCapabilities(network).hasCapability( NET_CAPABILITY_NOT_METERED), true); From 5cfd8d6bb1c08711af322f9e2f7d5e114b2af16e Mon Sep 17 00:00:00 2001 From: junyulai Date: Mon, 20 Apr 2020 15:34:19 +0800 Subject: [PATCH 0895/1109] Remove upper bound check of getTotal* APIs in TrafficStatsTest Currently, this cause flakiness since some background traffic was counted when performing tests, or the traffic generated by adb over network. While there is no good way to filter out all reasonable cases, disable the upper bound checks. Test: atest TrafficStatsTest Bug: 142978584 Change-Id: I8140310c9caeff6069d1f55590bf40f83bf211e4 --- .../src/android/net/cts/TrafficStatsTest.java | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java index 577e24ac29..37bdd44fbf 100755 --- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java +++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java @@ -16,11 +16,9 @@ package android.net.cts; -import android.content.pm.PackageManager; import android.net.NetworkStats; import android.net.TrafficStats; import android.os.Process; -import android.os.SystemProperties; import android.platform.test.annotations.AppModeFull; import android.test.AndroidTestCase; import android.util.Log; @@ -267,28 +265,6 @@ public class TrafficStatsTest extends AndroidTestCase { assertTrue("ifrxp: " + ifaceRxPacketsBefore + " -> " + ifaceRxPacketsAfter, totalRxPacketsAfter >= totalRxPacketsBefore + ifaceRxDeltaPackets); - // If the adb TCP port is opened, this test may be run by adb over network. - // Huge amount of data traffic might go through the network and accounted into total packets - // stats. The upper bound check would be meaningless. - // TODO: Consider precisely calculate the traffic accounted due to adb over network and - // subtract it when checking upper bound instead of skip checking. - final PackageManager pm = mContext.getPackageManager(); - if (SystemProperties.getInt("persist.adb.tcp.port", -1) > -1 - || SystemProperties.getInt("service.adb.tcp.port", -1) > -1 - || !pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY)) { - Log.i(LOG_TAG, "adb is running over the network, skip the upper bound check"); - } else { - // Fudge by 132 packets of 1500 bytes not related to the test. - assertTrue("ttxp: " + totalTxPacketsBefore + " -> " + totalTxPacketsAfter, - totalTxPacketsAfter <= totalTxPacketsBefore + uidTxDeltaPackets + 132); - assertTrue("trxp: " + totalRxPacketsBefore + " -> " + totalRxPacketsAfter, - totalRxPacketsAfter <= totalRxPacketsBefore + uidRxDeltaPackets + 132); - assertTrue("ttxb: " + totalTxBytesBefore + " -> " + totalTxBytesAfter, - totalTxBytesAfter <= totalTxBytesBefore + uidTxDeltaBytes + 132 * 1500); - assertTrue("trxb: " + totalRxBytesBefore + " -> " + totalRxBytesAfter, - totalRxBytesAfter <= totalRxBytesBefore + uidRxDeltaBytes + 132 * 1500); - } - // Localhost traffic should *not* count against mobile stats, // There might be some other traffic, but nowhere near 1MB. assertInRange("mtxp", mobileTxPacketsAfter, mobileTxPacketsBefore, From 958e8d1ceb9753ab760752dbd35be101a3d0346a Mon Sep 17 00:00:00 2001 From: Remi NGUYEN VAN Date: Mon, 20 Apr 2020 18:51:17 +0900 Subject: [PATCH 0896/1109] Skip new UrlQuerySanitizer tests on Q The tests verify behavior that was only fixed on R, but UrlQuerySanitizerTest is part of MTS which needs to pass on Q. Test: atest CtsNetTestCasesLatestSdk:UrlQuerySanitizerTest Bug: 150904735 Change-Id: I214b2fd8a45732a41e8604db70c83a8e3f4a45e4 --- .../net/cts/UrlQuerySanitizerTest.java | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java b/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java index 82b3b14d34..5a70928e37 100644 --- a/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java +++ b/tests/cts/net/src/android/net/cts/UrlQuerySanitizerTest.java @@ -16,16 +16,38 @@ package android.net.cts; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + import android.net.UrlQuerySanitizer; import android.net.UrlQuerySanitizer.IllegalCharacterValueSanitizer; import android.net.UrlQuerySanitizer.ParameterValuePair; import android.net.UrlQuerySanitizer.ValueSanitizer; -import android.test.AndroidTestCase; +import android.os.Build; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.SmallTest; + +import com.android.testutils.DevSdkIgnoreRule; +import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; import java.util.List; import java.util.Set; -public class UrlQuerySanitizerTest extends AndroidTestCase { +@SmallTest +@RunWith(AndroidJUnit4.class) +public class UrlQuerySanitizerTest { + @Rule + public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule(); + private static final int ALL_OK = IllegalCharacterValueSanitizer.ALL_OK; // URL for test. @@ -42,6 +64,7 @@ public class UrlQuerySanitizerTest extends AndroidTestCase { private static final String AGE = "age"; private static final String HEIGHT = "height"; + @Test public void testUrlQuerySanitizer() { MockUrlQuerySanitizer uqs = new MockUrlQuerySanitizer(); assertFalse(uqs.getAllowUnregisteredParamaters()); @@ -210,12 +233,14 @@ public class UrlQuerySanitizerTest extends AndroidTestCase { } + @Test @IgnoreUpTo(Build.VERSION_CODES.Q) // Only fixed in R public void testScriptUrlOk_73822755() { ValueSanitizer sanitizer = new UrlQuerySanitizer.IllegalCharacterValueSanitizer( UrlQuerySanitizer.IllegalCharacterValueSanitizer.SCRIPT_URL_OK); assertEquals("javascript:alert()", sanitizer.sanitize("javascript:alert()")); } + @Test @IgnoreUpTo(Build.VERSION_CODES.Q) // Only fixed in R public void testScriptUrlBlocked_73822755() { ValueSanitizer sanitizer = UrlQuerySanitizer.getUrlAndSpaceLegal(); assertEquals("", sanitizer.sanitize("javascript:alert()")); From 257cad80525882bf7aec05e172a182e9fd9f2ab4 Mon Sep 17 00:00:00 2001 From: markchien Date: Sat, 11 Apr 2020 18:53:35 +0800 Subject: [PATCH 0897/1109] Test enable tethering permission and stopAllTethering 1. Test whether start tethering is gated by suitable permission. 2. Test stopAllTethering Bug: 153613718 Test: atest CtsTetheringTest Change-Id: I38702886ea355e1aec8eb8ac404fdd46a44582e3 --- tests/cts/tethering/Android.bp | 1 + .../tethering/cts/TetheringManagerTest.java | 274 ++++++++++++------ 2 files changed, 189 insertions(+), 86 deletions(-) diff --git a/tests/cts/tethering/Android.bp b/tests/cts/tethering/Android.bp index 63de301d69..a5930aa98b 100644 --- a/tests/cts/tethering/Android.bp +++ b/tests/cts/tethering/Android.bp @@ -27,6 +27,7 @@ android_test { static_libs: [ "TetheringIntegrationTestsLib", "compatibility-device-util-axt", + "net-tests-utils", "ctstestrunner-axt", "junit", "junit-params", diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java index ccad14cdd2..60f9400363 100644 --- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java +++ b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java @@ -15,20 +15,24 @@ */ package android.tethering.test; -import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED; -import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED; -import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED; import static android.net.TetheringManager.TETHERING_USB; import static android.net.TetheringManager.TETHERING_WIFI; import static android.net.TetheringManager.TETHERING_WIFI_P2P; import static android.net.TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN; +import static android.net.TetheringManager.TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION; +import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR; +import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED; +import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED; +import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import android.app.UiAutomation; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -48,6 +52,8 @@ import androidx.annotation.NonNull; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; +import com.android.testutils.ArrayTrackRecord; + import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -77,11 +83,21 @@ public class TetheringManagerTest { private static final int DEFAULT_TIMEOUT_MS = 60_000; + private void adoptShellPermissionIdentity() { + final UiAutomation uiAutomation = + InstrumentationRegistry.getInstrumentation().getUiAutomation(); + uiAutomation.adoptShellPermissionIdentity(); + } + + private void dropShellPermissionIdentity() { + final UiAutomation uiAutomation = + InstrumentationRegistry.getInstrumentation().getUiAutomation(); + uiAutomation.dropShellPermissionIdentity(); + } + @Before public void setUp() throws Exception { - InstrumentationRegistry.getInstrumentation() - .getUiAutomation() - .adoptShellPermissionIdentity(); + adoptShellPermissionIdentity(); mContext = InstrumentationRegistry.getContext(); mTM = (TetheringManager) mContext.getSystemService(Context.TETHERING_SERVICE); mTetherChangeReceiver = new TetherChangeReceiver(); @@ -93,10 +109,9 @@ public class TetheringManagerTest { @After public void tearDown() throws Exception { + mTM.stopAllTethering(); mContext.unregisterReceiver(mTetherChangeReceiver); - InstrumentationRegistry.getInstrumentation() - .getUiAutomation() - .dropShellPermissionIdentity(); + dropShellPermissionIdentity(); } private class TetherChangeReceiver extends BroadcastReceiver { @@ -202,15 +217,54 @@ public class TetheringManagerTest { } } - private class StartTetheringCallback implements TetheringManager.StartTetheringCallback { + private static class StartTetheringCallback implements TetheringManager.StartTetheringCallback { + private static int TIMEOUT_MS = 30_000; + public static class CallbackValue { + public final int error; + + private CallbackValue(final int e) { + error = e; + } + + public static class OnTetheringStarted extends CallbackValue { + OnTetheringStarted() { super(TETHER_ERROR_NO_ERROR); } + } + + public static class OnTetheringFailed extends CallbackValue { + OnTetheringFailed(final int error) { super(error); } + } + + @Override + public String toString() { + return String.format("%s(%d)", getClass().getSimpleName(), error); + } + } + + private final ArrayTrackRecord.ReadHead mHistory = + new ArrayTrackRecord().newReadHead(); + @Override public void onTetheringStarted() { - // Do nothing, TetherChangeReceiver will wait until it receives the broadcast. + mHistory.add(new CallbackValue.OnTetheringStarted()); } @Override public void onTetheringFailed(final int error) { - fail("startTethering fail: " + error); + mHistory.add(new CallbackValue.OnTetheringFailed(error)); + } + + public void verifyTetheringStarted() { + final CallbackValue cv = mHistory.poll(TIMEOUT_MS, c -> true); + assertNotNull("No onTetheringStarted after " + TIMEOUT_MS + " ms", cv); + assertTrue("Fail start tethering:" + cv, + cv instanceof CallbackValue.OnTetheringStarted); + } + + public void expectTetheringFailed(final int expected) throws InterruptedException { + final CallbackValue cv = mHistory.poll(TIMEOUT_MS, c -> true); + assertNotNull("No onTetheringFailed after " + TIMEOUT_MS + " ms", cv); + assertTrue("Expect fail with error code " + expected + ", but received: " + cv, + (cv instanceof CallbackValue.OnTetheringFailed) && (cv.error == expected)); } } @@ -244,8 +298,10 @@ public class TetheringManagerTest { mTetherChangeReceiver.expectNoActiveTethering(0 /** timeout */); final StartTetheringCallback startTetheringCallback = new StartTetheringCallback(); - mTM.startTethering(new TetheringRequest.Builder(TETHERING_WIFI).build(), c -> c.run(), - startTetheringCallback); + mTM.startTethering(new TetheringRequest.Builder(TETHERING_WIFI).build(), + c -> c.run() /* executor */, startTetheringCallback); + startTetheringCallback.verifyTetheringStarted(); + mTetherChangeReceiver.expectActiveTethering(wifiRegexs); mTM.stopTethering(TETHERING_WIFI); @@ -277,6 +333,7 @@ public class TetheringManagerTest { // Must poll the callback before looking at the member. private static class TestTetheringEventCallback implements TetheringEventCallback { + private static final int TIMEOUT_MS = 30_000; public enum CallbackType { ON_SUPPORTED, ON_UPSTREAM, @@ -299,7 +356,10 @@ public class TetheringManagerTest { this.callbackParam2 = param2; } } - private final LinkedBlockingQueue mCallbacks = new LinkedBlockingQueue<>(); + + private final ArrayTrackRecord.ReadHead mHistory = + new ArrayTrackRecord().newReadHead(); + private TetheringInterfaceRegexps mTetherableRegex; private List mTetherableIfaces; @@ -307,108 +367,96 @@ public class TetheringManagerTest { @Override public void onTetheringSupported(boolean supported) { - mCallbacks.add(new CallbackValue(CallbackType.ON_SUPPORTED, null, 0)); + mHistory.add(new CallbackValue(CallbackType.ON_SUPPORTED, null, 0)); } @Override public void onUpstreamChanged(Network network) { - mCallbacks.add(new CallbackValue(CallbackType.ON_UPSTREAM, network, 0)); + mHistory.add(new CallbackValue(CallbackType.ON_UPSTREAM, network, 0)); } @Override public void onTetherableInterfaceRegexpsChanged(TetheringInterfaceRegexps reg) { mTetherableRegex = reg; - mCallbacks.add(new CallbackValue(CallbackType.ON_TETHERABLE_REGEX, reg, 0)); + mHistory.add(new CallbackValue(CallbackType.ON_TETHERABLE_REGEX, reg, 0)); } @Override public void onTetherableInterfacesChanged(List interfaces) { mTetherableIfaces = interfaces; - mCallbacks.add(new CallbackValue(CallbackType.ON_TETHERABLE_IFACES, interfaces, 0)); + mHistory.add(new CallbackValue(CallbackType.ON_TETHERABLE_IFACES, interfaces, 0)); } @Override public void onTetheredInterfacesChanged(List interfaces) { mTetheredIfaces = interfaces; - mCallbacks.add(new CallbackValue(CallbackType.ON_TETHERED_IFACES, interfaces, 0)); + mHistory.add(new CallbackValue(CallbackType.ON_TETHERED_IFACES, interfaces, 0)); } @Override public void onError(String ifName, int error) { - mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, ifName, error)); + mHistory.add(new CallbackValue(CallbackType.ON_ERROR, ifName, error)); } @Override public void onClientsChanged(Collection clients) { - mCallbacks.add(new CallbackValue(CallbackType.ON_CLIENTS, clients, 0)); + mHistory.add(new CallbackValue(CallbackType.ON_CLIENTS, clients, 0)); } @Override public void onOffloadStatusChanged(int status) { - mCallbacks.add(new CallbackValue(CallbackType.ON_OFFLOAD_STATUS, status, 0)); - } - - public CallbackValue pollCallback() { - try { - return mCallbacks.poll(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - fail("Callback not seen"); - } - return null; + mHistory.add(new CallbackValue(CallbackType.ON_OFFLOAD_STATUS, status, 0)); } public void expectTetherableInterfacesChanged(@NonNull List regexs) { - while (true) { - final CallbackValue cv = pollCallback(); - if (cv == null) fail("No expected tetherable ifaces callback"); - if (cv.callbackType != CallbackType.ON_TETHERABLE_IFACES) continue; - - final List interfaces = (List) cv.callbackParam; - if (isIfaceMatch(regexs, interfaces)) break; - } + assertNotNull("No expected tetherable ifaces callback", mHistory.poll(TIMEOUT_MS, + (cv) -> { + if (cv.callbackType != CallbackType.ON_TETHERABLE_IFACES) return false; + final List interfaces = (List) cv.callbackParam; + return isIfaceMatch(regexs, interfaces); + })); } public void expectTetheredInterfacesChanged(@NonNull List regexs) { - while (true) { - final CallbackValue cv = pollCallback(); - if (cv == null) fail("No expected tethered ifaces callback"); - if (cv.callbackType != CallbackType.ON_TETHERED_IFACES) continue; + assertNotNull("No expected tethered ifaces callback", mHistory.poll(TIMEOUT_MS, + (cv) -> { + if (cv.callbackType != CallbackType.ON_TETHERED_IFACES) return false; - final List interfaces = (List) cv.callbackParam; + final List interfaces = (List) cv.callbackParam; - // Null regexs means no active tethering. - if (regexs == null) { - if (interfaces.size() == 0) break; - } else if (isIfaceMatch(regexs, interfaces)) { - break; - } - } + // Null regexs means no active tethering. + if (regexs == null) return interfaces.isEmpty(); + + return isIfaceMatch(regexs, interfaces); + })); } public void expectCallbackStarted() { + int receivedBitMap = 0; // The each bit represent a type from CallbackType.ON_*. // Expect all of callbacks except for ON_ERROR. - final int expectedBitMap = 0x7f ^ (1 << CallbackType.ON_ERROR.ordinal()); - int receivedBitMap = 0; - while (receivedBitMap != expectedBitMap) { - final CallbackValue cv = pollCallback(); + final int expectedBitMap = 0xff ^ (1 << CallbackType.ON_ERROR.ordinal()); + // Receive ON_ERROR on started callback is not matter. It just means tethering is + // failed last time, should able to continue the test this time. + while ((receivedBitMap & expectedBitMap) != expectedBitMap) { + final CallbackValue cv = mHistory.poll(TIMEOUT_MS, c -> true); if (cv == null) { fail("No expected callbacks, " + "expected bitmap: " + expectedBitMap + ", actual: " + receivedBitMap); } - receivedBitMap = receivedBitMap | (1 << cv.callbackType.ordinal()); + receivedBitMap |= (1 << cv.callbackType.ordinal()); } } public void expectOneOfOffloadStatusChanged(int... offloadStatuses) { - while (true) { - final CallbackValue cv = pollCallback(); - if (cv == null) fail("No expected offload status change callback"); - if (cv.callbackType != CallbackType.ON_OFFLOAD_STATUS) continue; + assertNotNull("No offload status changed", mHistory.poll(TIMEOUT_MS, (cv) -> { + if (cv.callbackType != CallbackType.ON_OFFLOAD_STATUS) return false; final int status = (int) cv.callbackParam; - for (int offloadStatus : offloadStatuses) if (offloadStatus == status) return; - } + for (int offloadStatus : offloadStatuses) if (offloadStatus == status) return true; + + return false; + })); } public TetheringInterfaceRegexps getTetheringInterfaceRegexps() { @@ -424,52 +472,78 @@ public class TetheringManagerTest { } } - @Test - public void testRegisterTetheringEventCallback() throws Exception { - if (!mTM.isTetheringSupported()) return; - + private TestTetheringEventCallback registerTetheringEventCallback() { final TestTetheringEventCallback tetherEventCallback = new TestTetheringEventCallback(); - mTM.registerTetheringEventCallback(c -> c.run(), tetherEventCallback); + mTM.registerTetheringEventCallback(c -> c.run() /* executor */, tetherEventCallback); tetherEventCallback.expectCallbackStarted(); - tetherEventCallback.expectOneOfOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); - final TetheringInterfaceRegexps tetherableRegexs = - tetherEventCallback.getTetheringInterfaceRegexps(); - final List wifiRegexs = tetherableRegexs.getTetherableWifiRegexs(); - if (wifiRegexs.size() == 0) return; + return tetherEventCallback; + } + private void unregisterTetheringEventCallback(final TestTetheringEventCallback callback) { + mTM.unregisterTetheringEventCallback(callback); + } + + private List getWifiTetherableInterfaceRegexps( + final TestTetheringEventCallback callback) { + return callback.getTetheringInterfaceRegexps().getTetherableWifiRegexs(); + } + + private boolean isWifiTetheringSupported(final TestTetheringEventCallback callback) { + return !getWifiTetherableInterfaceRegexps(callback).isEmpty(); + } + + private void startWifiTethering(final TestTetheringEventCallback callback) + throws InterruptedException { + final List wifiRegexs = getWifiTetherableInterfaceRegexps(callback); final boolean isIfaceAvailWhenNoTethering = - isIfaceMatch(wifiRegexs, tetherEventCallback.getTetherableInterfaces()); + isIfaceMatch(wifiRegexs, callback.getTetherableInterfaces()); - mTM.startTethering(new TetheringRequest.Builder(TETHERING_WIFI).build(), c -> c.run(), - new StartTetheringCallback()); + final StartTetheringCallback startTetheringCallback = new StartTetheringCallback(); + mTM.startTethering(new TetheringRequest.Builder(TETHERING_WIFI).build(), + c -> c.run() /* executor */, startTetheringCallback); + startTetheringCallback.verifyTetheringStarted(); // If interface is already available before starting tethering, the available callback may // not be sent after tethering enabled. if (!isIfaceAvailWhenNoTethering) { - tetherEventCallback.expectTetherableInterfacesChanged(wifiRegexs); + callback.expectTetherableInterfacesChanged(wifiRegexs); } - tetherEventCallback.expectTetheredInterfacesChanged(wifiRegexs); - tetherEventCallback.expectOneOfOffloadStatusChanged( + callback.expectTetheredInterfacesChanged(wifiRegexs); + + callback.expectOneOfOffloadStatusChanged( TETHER_HARDWARE_OFFLOAD_STARTED, TETHER_HARDWARE_OFFLOAD_FAILED); + } + private void stopWifiTethering(final TestTetheringEventCallback callback) { mTM.stopTethering(TETHERING_WIFI); + callback.expectTetheredInterfacesChanged(null); + callback.expectOneOfOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); + } - tetherEventCallback.expectTetheredInterfacesChanged(null); - tetherEventCallback.expectOneOfOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); - mTM.unregisterTetheringEventCallback(tetherEventCallback); + @Test + public void testRegisterTetheringEventCallback() throws Exception { + if (!mTM.isTetheringSupported()) return; + + final TestTetheringEventCallback tetherEventCallback = registerTetheringEventCallback(); + + if (!isWifiTetheringSupported(tetherEventCallback)) return; + + startWifiTethering(tetherEventCallback); + + stopWifiTethering(tetherEventCallback); + + unregisterTetheringEventCallback(tetherEventCallback); } @Test public void testGetTetherableInterfaceRegexps() { if (!mTM.isTetheringSupported()) return; - final TestTetheringEventCallback tetherEventCallback = new TestTetheringEventCallback(); - mTM.registerTetheringEventCallback(c -> c.run(), tetherEventCallback); - tetherEventCallback.expectCallbackStarted(); + final TestTetheringEventCallback tetherEventCallback = registerTetheringEventCallback(); final TetheringInterfaceRegexps tetherableRegexs = tetherEventCallback.getTetheringInterfaceRegexps(); @@ -486,7 +560,35 @@ public class TetheringManagerTest { wifiRegexs.forEach(s -> assertFalse(btRegexs.contains(s))); usbRegexs.forEach(s -> assertFalse(btRegexs.contains(s))); - mTM.unregisterTetheringEventCallback(tetherEventCallback); + unregisterTetheringEventCallback(tetherEventCallback); + } + + @Test + public void testStopAllTethering() throws Exception { + if (!mTM.isTetheringSupported()) return; + + final TestTetheringEventCallback tetherEventCallback = registerTetheringEventCallback(); + + if (!isWifiTetheringSupported(tetherEventCallback)) return; + + // TODO: start ethernet tethering here when TetheringManagerTest is moved to + // TetheringIntegrationTest. + + startWifiTethering(tetherEventCallback); + + mTM.stopAllTethering(); + tetherEventCallback.expectTetheredInterfacesChanged(null); + + unregisterTetheringEventCallback(tetherEventCallback); + } + + @Test + public void testEnableTetheringPermission() throws Exception { + dropShellPermissionIdentity(); + final StartTetheringCallback startTetheringCallback = new StartTetheringCallback(); + mTM.startTethering(new TetheringRequest.Builder(TETHERING_WIFI).build(), + c -> c.run() /* executor */, startTetheringCallback); + startTetheringCallback.expectTetheringFailed(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION); } private class EntitlementResultListener implements OnTetheringEntitlementResultListener { From 3ee47d42333849f25a0a5618f217156790ef8c36 Mon Sep 17 00:00:00 2001 From: Chiachang Wang Date: Mon, 20 Apr 2020 15:15:58 +0000 Subject: [PATCH 0898/1109] Update network object when wifi meterness is changed The new wifi disconnect behavior is introduced. When wifi network is changed from unmetered to metered, the wifi network will disconnect and reconnect. Update the test to verify the same SSID wifi is connected and also update the target network to verfiy the metered preference. Bug: 153400606 Test: atest CtsNetTestCases:android.net.cts.ConnectivityManagerTest\ #testGetMultipathPreference Change-Id: Ic298d3d85d8c6b77c8df7614a945f2c22dcdff38 Merged-In: Ic298d3d85d8c6b77c8df7614a945f2c22dcdff38 (cherry picked from commit 37d5d4387cce865d159e80e5101685b4c2a13731) --- .../net/src/android/net/cts/ConnectivityManagerTest.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index fa7e1381b3..3a52ee60a3 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -709,7 +709,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { @AppModeFull(reason = "Cannot get WifiManager in instant app mode") public void testGetMultipathPreference() throws Exception { final ContentResolver resolver = mContext.getContentResolver(); - final Network network = ensureWifiConnected(); + ensureWifiConnected(); final String ssid = unquoteSSID(mWifiManager.getConnectionInfo().getSSID()); final String oldMeteredSetting = getWifiMeteredStatus(ssid); final String oldMeteredMultipathPreference = Settings.Global.getString( @@ -721,6 +721,10 @@ public class ConnectivityManagerTest extends AndroidTestCase { Integer.toString(newMeteredPreference)); setWifiMeteredStatus(ssid, "true"); waitForActiveNetworkMetered(true); + // Wifi meterness changes from unmetered to metered will disconnect and reconnect since + // R. + final Network network = mCm.getActiveNetwork(); + assertEquals(ssid, unquoteSSID(mWifiManager.getConnectionInfo().getSSID())); assertEquals(mCm.getNetworkCapabilities(network).hasCapability( NET_CAPABILITY_NOT_METERED), false); assertMultipathPreferenceIsEventually(network, initialMeteredPreference, @@ -736,6 +740,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { oldMeteredPreference, newMeteredPreference); setWifiMeteredStatus(ssid, "false"); + // No disconnect from unmetered to metered. waitForActiveNetworkMetered(false); assertEquals(mCm.getNetworkCapabilities(network).hasCapability( NET_CAPABILITY_NOT_METERED), true); From 6f8e61226444178d653f151f3066946fb60cf30b Mon Sep 17 00:00:00 2001 From: Junyu Lai Date: Tue, 21 Apr 2020 03:46:08 +0000 Subject: [PATCH 0899/1109] Remove upper bound check of getTotal* APIs in TrafficStatsTest Currently, this cause flakiness since some background traffic was counted when performing tests, or the traffic generated by adb over network. While there is no good way to filter out all reasonable cases, disable the upper bound checks. Test: atest TrafficStatsTest Bug: 142978584 Change-Id: I22edc46039bf35e544d9ce8a9f3a00b713478e05 Merged-In: I22edc46039bf35e544d9ce8a9f3a00b713478e05 Merged-In: I8140310c9caeff6069d1f55590bf40f83bf211e4 (cherry picked from commit 8accc6aa11213a7a8287a2ec0f75f17a02173f99) --- .../src/android/net/cts/TrafficStatsTest.java | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java index 577e24ac29..37bdd44fbf 100755 --- a/tests/cts/net/src/android/net/cts/TrafficStatsTest.java +++ b/tests/cts/net/src/android/net/cts/TrafficStatsTest.java @@ -16,11 +16,9 @@ package android.net.cts; -import android.content.pm.PackageManager; import android.net.NetworkStats; import android.net.TrafficStats; import android.os.Process; -import android.os.SystemProperties; import android.platform.test.annotations.AppModeFull; import android.test.AndroidTestCase; import android.util.Log; @@ -267,28 +265,6 @@ public class TrafficStatsTest extends AndroidTestCase { assertTrue("ifrxp: " + ifaceRxPacketsBefore + " -> " + ifaceRxPacketsAfter, totalRxPacketsAfter >= totalRxPacketsBefore + ifaceRxDeltaPackets); - // If the adb TCP port is opened, this test may be run by adb over network. - // Huge amount of data traffic might go through the network and accounted into total packets - // stats. The upper bound check would be meaningless. - // TODO: Consider precisely calculate the traffic accounted due to adb over network and - // subtract it when checking upper bound instead of skip checking. - final PackageManager pm = mContext.getPackageManager(); - if (SystemProperties.getInt("persist.adb.tcp.port", -1) > -1 - || SystemProperties.getInt("service.adb.tcp.port", -1) > -1 - || !pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY)) { - Log.i(LOG_TAG, "adb is running over the network, skip the upper bound check"); - } else { - // Fudge by 132 packets of 1500 bytes not related to the test. - assertTrue("ttxp: " + totalTxPacketsBefore + " -> " + totalTxPacketsAfter, - totalTxPacketsAfter <= totalTxPacketsBefore + uidTxDeltaPackets + 132); - assertTrue("trxp: " + totalRxPacketsBefore + " -> " + totalRxPacketsAfter, - totalRxPacketsAfter <= totalRxPacketsBefore + uidRxDeltaPackets + 132); - assertTrue("ttxb: " + totalTxBytesBefore + " -> " + totalTxBytesAfter, - totalTxBytesAfter <= totalTxBytesBefore + uidTxDeltaBytes + 132 * 1500); - assertTrue("trxb: " + totalRxBytesBefore + " -> " + totalRxBytesAfter, - totalRxBytesAfter <= totalRxBytesBefore + uidRxDeltaBytes + 132 * 1500); - } - // Localhost traffic should *not* count against mobile stats, // There might be some other traffic, but nowhere near 1MB. assertInRange("mtxp", mobileTxPacketsAfter, mobileTxPacketsBefore, From a7f8f2d01ca33d18381ab906aa051f6264f9920e Mon Sep 17 00:00:00 2001 From: Remi NGUYEN VAN Date: Tue, 21 Apr 2020 15:09:16 +0900 Subject: [PATCH 0900/1109] Fix test initialization errors on Q ConnectivityDiagnosticsManagerTest, MultinetworkApiTest, NetworkAgentTest crashed before the runner could start them: - Ignore ConnectivityDiagnosticsManagerTest on Q: it tests an API that was introduced in R. - Build JNI libraries used by MultinetworkApiTest against the NDK to avoid errors loading the libraries on older platforms, when transitive dependencies have been added. - Do not attempt to override Handler#getLooper() (which is final) in NetworkAgentTest; it appears to have been overridden by accident by specifying "val looper" in the TestableNetworkAgent definition, which generates a getter. Test: atest CtsNetTestCasesLatestSdk:ConnectivityDiagnosticsManagerTest atest CtsNetTestCasesLatestSdk:MultinetworkApiTest atest CtsNetTestCasesLatestSdk:NetworkAgentTest Bug: 150918852 Change-Id: I262b54c6897ed755adaeb2b118c638320634f7a1 --- tests/cts/net/jni/Android.bp | 2 + tests/cts/net/jni/NativeDnsJni.c | 41 +++++++++++-------- tests/cts/net/jni/NativeMultinetworkJni.cpp | 35 ++++++++-------- .../ConnectivityDiagnosticsManagerTest.java | 9 ++-- .../src/android/net/cts/NetworkAgentTest.kt | 2 +- 5 files changed, 51 insertions(+), 38 deletions(-) diff --git a/tests/cts/net/jni/Android.bp b/tests/cts/net/jni/Android.bp index baed48dfae..3953aeb701 100644 --- a/tests/cts/net/jni/Android.bp +++ b/tests/cts/net/jni/Android.bp @@ -16,6 +16,7 @@ cc_library_shared { name: "libnativedns_jni", srcs: ["NativeDnsJni.c"], + sdk_version: "current", shared_libs: [ "libnativehelper_compat_libc++", @@ -35,6 +36,7 @@ cc_library_shared { name: "libnativemultinetwork_jni", srcs: ["NativeMultinetworkJni.cpp"], + sdk_version: "current", cflags: [ "-Wall", "-Werror", diff --git a/tests/cts/net/jni/NativeDnsJni.c b/tests/cts/net/jni/NativeDnsJni.c index 6d3d1c3250..4ec800e555 100644 --- a/tests/cts/net/jni/NativeDnsJni.c +++ b/tests/cts/net/jni/NativeDnsJni.c @@ -19,7 +19,12 @@ #include #include #include -#include + +#include + +#define LOG_TAG "NativeDns-JNI" +#define LOGD(fmt, ...) \ + __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, fmt, ##__VA_ARGS__) const char *GoogleDNSIpV4Address="8.8.8.8"; const char *GoogleDNSIpV4Address2="8.8.4.4"; @@ -33,7 +38,7 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas struct addrinfo *answer; int res = getaddrinfo(node, service, NULL, &answer); - ALOGD("getaddrinfo(www.google.com) gave res=%d (%s)", res, gai_strerror(res)); + LOGD("getaddrinfo(www.google.com) gave res=%d (%s)", res, gai_strerror(res)); if (res != 0) return JNI_FALSE; // check for v4 & v6 @@ -47,12 +52,12 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas inet_ntop(current->ai_family, &((struct sockaddr_in *)current->ai_addr)->sin_addr, buf, sizeof(buf)); foundv4 = 1; - ALOGD(" %s", buf); + LOGD(" %s", buf); } else if (current->ai_addr->sa_family == AF_INET6) { inet_ntop(current->ai_family, &((struct sockaddr_in6 *)current->ai_addr)->sin6_addr, buf, sizeof(buf)); foundv6 = 1; - ALOGD(" %s", buf); + LOGD(" %s", buf); } current = current->ai_next; } @@ -60,14 +65,14 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas freeaddrinfo(answer); answer = NULL; if (foundv4 != 1 && foundv6 != 1) { - ALOGD("getaddrinfo(www.google.com) didn't find either v4 or v6 address"); + LOGD("getaddrinfo(www.google.com) didn't find either v4 or v6 address"); return JNI_FALSE; } } node = "ipv6.google.com"; res = getaddrinfo(node, service, NULL, &answer); - ALOGD("getaddrinfo(ipv6.google.com) gave res=%d", res); + LOGD("getaddrinfo(ipv6.google.com) gave res=%d", res); if (res != 0) return JNI_FALSE; { @@ -79,12 +84,12 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas if (current->ai_addr->sa_family == AF_INET) { inet_ntop(current->ai_family, &((struct sockaddr_in *)current->ai_addr)->sin_addr, buf, sizeof(buf)); - ALOGD(" %s", buf); + LOGD(" %s", buf); foundv4 = 1; } else if (current->ai_addr->sa_family == AF_INET6) { inet_ntop(current->ai_family, &((struct sockaddr_in6 *)current->ai_addr)->sin6_addr, buf, sizeof(buf)); - ALOGD(" %s", buf); + LOGD(" %s", buf); foundv6 = 1; } current = current->ai_next; @@ -93,7 +98,7 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas freeaddrinfo(answer); answer = NULL; if (foundv4 == 1 || foundv6 != 1) { - ALOGD("getaddrinfo(ipv6.google.com) didn't find only v6"); + LOGD("getaddrinfo(ipv6.google.com) didn't find only v6"); return JNI_FALSE; } } @@ -116,12 +121,12 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas res = getnameinfo((const struct sockaddr*)&sa4, sizeof(sa4), buf, sizeof(buf), NULL, 0, flags); if (res != 0) { - ALOGD("getnameinfo(%s (GoogleDNS) ) gave error %d (%s)", GoogleDNSIpV4Address, res, + LOGD("getnameinfo(%s (GoogleDNS) ) gave error %d (%s)", GoogleDNSIpV4Address, res, gai_strerror(res)); return JNI_FALSE; } if (strstr(buf, "google.com") == NULL && strstr(buf, "dns.google") == NULL) { - ALOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com or dns.google: %s", + LOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com or dns.google: %s", GoogleDNSIpV4Address, buf); return JNI_FALSE; } @@ -129,12 +134,12 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas memset(buf, 0, sizeof(buf)); res = getnameinfo((const struct sockaddr*)&sa6, sizeof(sa6), buf, sizeof(buf), NULL, 0, flags); if (res != 0) { - ALOGD("getnameinfo(%s (GoogleDNS) ) gave error %d (%s)", GoogleDNSIpV6Address2, + LOGD("getnameinfo(%s (GoogleDNS) ) gave error %d (%s)", GoogleDNSIpV6Address2, res, gai_strerror(res)); return JNI_FALSE; } if (strstr(buf, "google.com") == NULL && strstr(buf, "dns.google") == NULL) { - ALOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com or dns.google: %s", + LOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com or dns.google: %s", GoogleDNSIpV6Address2, buf); return JNI_FALSE; } @@ -142,11 +147,11 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas // gethostbyname struct hostent *my_hostent = gethostbyname("www.youtube.com"); if (my_hostent == NULL) { - ALOGD("gethostbyname(www.youtube.com) gave null response"); + LOGD("gethostbyname(www.youtube.com) gave null response"); return JNI_FALSE; } if ((my_hostent->h_addr_list == NULL) || (*my_hostent->h_addr_list == NULL)) { - ALOGD("gethostbyname(www.youtube.com) gave 0 addresses"); + LOGD("gethostbyname(www.youtube.com) gave 0 addresses"); return JNI_FALSE; } { @@ -154,7 +159,7 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas while (*current != NULL) { char buf[256]; inet_ntop(my_hostent->h_addrtype, *current, buf, sizeof(buf)); - ALOGD("gethostbyname(www.youtube.com) gave %s", buf); + LOGD("gethostbyname(www.youtube.com) gave %s", buf); current++; } } @@ -164,11 +169,11 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas inet_pton(AF_INET6, GoogleDNSIpV6Address, addr6); my_hostent = gethostbyaddr(addr6, sizeof(addr6), AF_INET6); if (my_hostent == NULL) { - ALOGD("gethostbyaddr(%s (GoogleDNS) ) gave null response", GoogleDNSIpV6Address); + LOGD("gethostbyaddr(%s (GoogleDNS) ) gave null response", GoogleDNSIpV6Address); return JNI_FALSE; } - ALOGD("gethostbyaddr(%s (GoogleDNS) ) gave %s for name", GoogleDNSIpV6Address, + LOGD("gethostbyaddr(%s (GoogleDNS) ) gave %s for name", GoogleDNSIpV6Address, my_hostent->h_name ? my_hostent->h_name : "null"); if (my_hostent->h_name == NULL) return JNI_FALSE; diff --git a/tests/cts/net/jni/NativeMultinetworkJni.cpp b/tests/cts/net/jni/NativeMultinetworkJni.cpp index 2832c3d142..cd94709fd5 100644 --- a/tests/cts/net/jni/NativeMultinetworkJni.cpp +++ b/tests/cts/net/jni/NativeMultinetworkJni.cpp @@ -16,7 +16,6 @@ #define LOG_TAG "MultinetworkApiTest" -#include #include #include @@ -34,9 +33,13 @@ #include +#include #include #include +#define LOGD(fmt, ...) \ + __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, fmt, ##__VA_ARGS__) + #define EXPECT_GE(env, actual, expected, msg) \ do { \ if (actual < expected) { \ @@ -138,7 +141,7 @@ int expectAnswersNotValid(JNIEnv* env, int fd, int expectedErrno) { uint8_t buf[MAXPACKET] = {}; int res = getAsyncResponse(env, fd, TIMEOUT_MS, &rcode, buf, MAXPACKET); if (res != expectedErrno) { - ALOGD("res:%d, expectedErrno = %d", res, expectedErrno); + LOGD("res:%d, expectedErrno = %d", res, expectedErrno); return (res > 0) ? -EREMOTEIO : res; } return 0; @@ -326,7 +329,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runGetaddrinfoCheck( const int saved_errno = errno; freeaddrinfo(res); - ALOGD("android_getaddrinfofornetwork(%" PRIu64 ", %s) returned rval=%d errno=%d", + LOGD("android_getaddrinfofornetwork(%" PRIu64 ", %s) returned rval=%d errno=%d", handle, kHostname, rval, saved_errno); return rval == 0 ? 0 : -saved_errno; } @@ -339,7 +342,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runSetprocnetwork( errno = 0; int rval = android_setprocnetwork(handle); const int saved_errno = errno; - ALOGD("android_setprocnetwork(%" PRIu64 ") returned rval=%d errno=%d", + LOGD("android_setprocnetwork(%" PRIu64 ") returned rval=%d errno=%d", handle, rval, saved_errno); return rval == 0 ? 0 : -saved_errno; } @@ -352,14 +355,14 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runSetsocknetwork( errno = 0; int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); if (fd < 0) { - ALOGD("socket() failed, errno=%d", errno); + LOGD("socket() failed, errno=%d", errno); return -errno; } errno = 0; int rval = android_setsocknetwork(handle, fd); const int saved_errno = errno; - ALOGD("android_setprocnetwork(%" PRIu64 ", %d) returned rval=%d errno=%d", + LOGD("android_setprocnetwork(%" PRIu64 ", %d) returned rval=%d errno=%d", handle, fd, rval, saved_errno); close(fd); return rval == 0 ? 0 : -saved_errno; @@ -404,7 +407,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( static const char kPort[] = "443"; int rval = android_getaddrinfofornetwork(handle, kHostname, kPort, &kHints, &res); if (rval != 0) { - ALOGD("android_getaddrinfofornetwork(%llu, %s) returned rval=%d errno=%d", + LOGD("android_getaddrinfofornetwork(%llu, %s) returned rval=%d errno=%d", handle, kHostname, rval, errno); freeaddrinfo(res); return -errno; @@ -413,14 +416,14 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( // Rely upon getaddrinfo sorting the best destination to the front. int fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (fd < 0) { - ALOGD("socket(%d, %d, %d) failed, errno=%d", + LOGD("socket(%d, %d, %d) failed, errno=%d", res->ai_family, res->ai_socktype, res->ai_protocol, errno); freeaddrinfo(res); return -errno; } rval = android_setsocknetwork(handle, fd); - ALOGD("android_setprocnetwork(%llu, %d) returned rval=%d errno=%d", + LOGD("android_setprocnetwork(%llu, %d) returned rval=%d errno=%d", handle, fd, rval, errno); if (rval != 0) { close(fd); @@ -430,7 +433,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( char addrstr[kSockaddrStrLen+1]; sockaddr_ntop(res->ai_addr, res->ai_addrlen, addrstr, sizeof(addrstr)); - ALOGD("Attempting connect() to %s ...", addrstr); + LOGD("Attempting connect() to %s ...", addrstr); rval = connect(fd, res->ai_addr, res->ai_addrlen); if (rval != 0) { @@ -447,7 +450,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( return -errno; } sockaddr_ntop((const struct sockaddr *)&src_addr, sizeof(src_addr), addrstr, sizeof(addrstr)); - ALOGD("... from %s", addrstr); + LOGD("... from %s", addrstr); // Don't let reads or writes block indefinitely. const struct timeval timeo = { 2, 0 }; // 2 seconds @@ -479,7 +482,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( sent = send(fd, quic_packet, sizeof(quic_packet), 0); if (sent < (ssize_t)sizeof(quic_packet)) { errnum = errno; - ALOGD("send(QUIC packet) returned sent=%zd, errno=%d", sent, errnum); + LOGD("send(QUIC packet) returned sent=%zd, errno=%d", sent, errnum); close(fd); return -errnum; } @@ -489,14 +492,14 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( break; } else { errnum = errno; - ALOGD("[%d/%d] recv(QUIC response) returned rcvd=%zd, errno=%d", + LOGD("[%d/%d] recv(QUIC response) returned rcvd=%zd, errno=%d", i + 1, MAX_RETRIES, rcvd, errnum); } } if (rcvd < 9) { - ALOGD("QUIC UDP %s: sent=%zd but rcvd=%zd, errno=%d", kPort, sent, rcvd, errnum); + LOGD("QUIC UDP %s: sent=%zd but rcvd=%zd, errno=%d", kPort, sent, rcvd, errnum); if (rcvd <= 0) { - ALOGD("Does this network block UDP port %s?", kPort); + LOGD("Does this network block UDP port %s?", kPort); } close(fd); return -EPROTO; @@ -504,7 +507,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( int conn_id_cmp = memcmp(quic_packet + 1, response + 1, 8); if (conn_id_cmp != 0) { - ALOGD("sent and received connection IDs do not match"); + LOGD("sent and received connection IDs do not match"); close(fd); return -EPROTO; } diff --git a/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java index 0a80047fdf..9d357055d1 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java @@ -18,15 +18,17 @@ package android.net.cts; import static android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import android.content.Context; import android.net.ConnectivityDiagnosticsManager; import android.net.NetworkRequest; +import android.os.Build; import androidx.test.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; + +import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; +import com.android.testutils.DevSdkIgnoreRunner; import org.junit.Before; import org.junit.Test; @@ -34,7 +36,8 @@ import org.junit.runner.RunWith; import java.util.concurrent.Executor; -@RunWith(AndroidJUnit4.class) +@RunWith(DevSdkIgnoreRunner.class) +@IgnoreUpTo(Build.VERSION_CODES.Q) // ConnectivityDiagnosticsManager did not exist in Q public class ConnectivityDiagnosticsManagerTest { private static final Executor INLINE_EXECUTOR = x -> x.run(); private static final NetworkRequest DEFAULT_REQUEST = new NetworkRequest.Builder().build(); diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 89d3dff66c..03b961bc4b 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -180,7 +180,7 @@ class NetworkAgentTest { } private open class TestableNetworkAgent( - val looper: Looper, + looper: Looper, val nc: NetworkCapabilities, val lp: LinkProperties, conf: NetworkAgentConfig From e96bd02054d620bb37acea0f7fcd56ee7c2287c5 Mon Sep 17 00:00:00 2001 From: Remi NGUYEN VAN Date: Tue, 21 Apr 2020 12:42:37 +0000 Subject: [PATCH 0901/1109] Fix test initialization errors on Q ConnectivityDiagnosticsManagerTest, MultinetworkApiTest, NetworkAgentTest crashed before the runner could start them: - Ignore ConnectivityDiagnosticsManagerTest on Q: it tests an API that was introduced in R. - Build JNI libraries used by MultinetworkApiTest against the NDK to avoid errors loading the libraries on older platforms, when transitive dependencies have been added. - Do not attempt to override Handler#getLooper() (which is final) in NetworkAgentTest; it appears to have been overridden by accident by specifying "val looper" in the TestableNetworkAgent definition, which generates a getter. Test: atest CtsNetTestCasesLatestSdk:ConnectivityDiagnosticsManagerTest atest CtsNetTestCasesLatestSdk:MultinetworkApiTest atest CtsNetTestCasesLatestSdk:NetworkAgentTest Bug: 150918852 Merged-In: I262b54c6897ed755adaeb2b118c638320634f7a1 Change-Id: I262b54c6897ed755adaeb2b118c638320634f7a1 --- tests/cts/net/jni/Android.bp | 2 + tests/cts/net/jni/NativeDnsJni.c | 41 +++++++++++-------- tests/cts/net/jni/NativeMultinetworkJni.cpp | 35 ++++++++-------- .../ConnectivityDiagnosticsManagerTest.java | 9 ++-- .../src/android/net/cts/NetworkAgentTest.kt | 2 +- 5 files changed, 51 insertions(+), 38 deletions(-) diff --git a/tests/cts/net/jni/Android.bp b/tests/cts/net/jni/Android.bp index baed48dfae..3953aeb701 100644 --- a/tests/cts/net/jni/Android.bp +++ b/tests/cts/net/jni/Android.bp @@ -16,6 +16,7 @@ cc_library_shared { name: "libnativedns_jni", srcs: ["NativeDnsJni.c"], + sdk_version: "current", shared_libs: [ "libnativehelper_compat_libc++", @@ -35,6 +36,7 @@ cc_library_shared { name: "libnativemultinetwork_jni", srcs: ["NativeMultinetworkJni.cpp"], + sdk_version: "current", cflags: [ "-Wall", "-Werror", diff --git a/tests/cts/net/jni/NativeDnsJni.c b/tests/cts/net/jni/NativeDnsJni.c index 6d3d1c3250..4ec800e555 100644 --- a/tests/cts/net/jni/NativeDnsJni.c +++ b/tests/cts/net/jni/NativeDnsJni.c @@ -19,7 +19,12 @@ #include #include #include -#include + +#include + +#define LOG_TAG "NativeDns-JNI" +#define LOGD(fmt, ...) \ + __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, fmt, ##__VA_ARGS__) const char *GoogleDNSIpV4Address="8.8.8.8"; const char *GoogleDNSIpV4Address2="8.8.4.4"; @@ -33,7 +38,7 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas struct addrinfo *answer; int res = getaddrinfo(node, service, NULL, &answer); - ALOGD("getaddrinfo(www.google.com) gave res=%d (%s)", res, gai_strerror(res)); + LOGD("getaddrinfo(www.google.com) gave res=%d (%s)", res, gai_strerror(res)); if (res != 0) return JNI_FALSE; // check for v4 & v6 @@ -47,12 +52,12 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas inet_ntop(current->ai_family, &((struct sockaddr_in *)current->ai_addr)->sin_addr, buf, sizeof(buf)); foundv4 = 1; - ALOGD(" %s", buf); + LOGD(" %s", buf); } else if (current->ai_addr->sa_family == AF_INET6) { inet_ntop(current->ai_family, &((struct sockaddr_in6 *)current->ai_addr)->sin6_addr, buf, sizeof(buf)); foundv6 = 1; - ALOGD(" %s", buf); + LOGD(" %s", buf); } current = current->ai_next; } @@ -60,14 +65,14 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas freeaddrinfo(answer); answer = NULL; if (foundv4 != 1 && foundv6 != 1) { - ALOGD("getaddrinfo(www.google.com) didn't find either v4 or v6 address"); + LOGD("getaddrinfo(www.google.com) didn't find either v4 or v6 address"); return JNI_FALSE; } } node = "ipv6.google.com"; res = getaddrinfo(node, service, NULL, &answer); - ALOGD("getaddrinfo(ipv6.google.com) gave res=%d", res); + LOGD("getaddrinfo(ipv6.google.com) gave res=%d", res); if (res != 0) return JNI_FALSE; { @@ -79,12 +84,12 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas if (current->ai_addr->sa_family == AF_INET) { inet_ntop(current->ai_family, &((struct sockaddr_in *)current->ai_addr)->sin_addr, buf, sizeof(buf)); - ALOGD(" %s", buf); + LOGD(" %s", buf); foundv4 = 1; } else if (current->ai_addr->sa_family == AF_INET6) { inet_ntop(current->ai_family, &((struct sockaddr_in6 *)current->ai_addr)->sin6_addr, buf, sizeof(buf)); - ALOGD(" %s", buf); + LOGD(" %s", buf); foundv6 = 1; } current = current->ai_next; @@ -93,7 +98,7 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas freeaddrinfo(answer); answer = NULL; if (foundv4 == 1 || foundv6 != 1) { - ALOGD("getaddrinfo(ipv6.google.com) didn't find only v6"); + LOGD("getaddrinfo(ipv6.google.com) didn't find only v6"); return JNI_FALSE; } } @@ -116,12 +121,12 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas res = getnameinfo((const struct sockaddr*)&sa4, sizeof(sa4), buf, sizeof(buf), NULL, 0, flags); if (res != 0) { - ALOGD("getnameinfo(%s (GoogleDNS) ) gave error %d (%s)", GoogleDNSIpV4Address, res, + LOGD("getnameinfo(%s (GoogleDNS) ) gave error %d (%s)", GoogleDNSIpV4Address, res, gai_strerror(res)); return JNI_FALSE; } if (strstr(buf, "google.com") == NULL && strstr(buf, "dns.google") == NULL) { - ALOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com or dns.google: %s", + LOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com or dns.google: %s", GoogleDNSIpV4Address, buf); return JNI_FALSE; } @@ -129,12 +134,12 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas memset(buf, 0, sizeof(buf)); res = getnameinfo((const struct sockaddr*)&sa6, sizeof(sa6), buf, sizeof(buf), NULL, 0, flags); if (res != 0) { - ALOGD("getnameinfo(%s (GoogleDNS) ) gave error %d (%s)", GoogleDNSIpV6Address2, + LOGD("getnameinfo(%s (GoogleDNS) ) gave error %d (%s)", GoogleDNSIpV6Address2, res, gai_strerror(res)); return JNI_FALSE; } if (strstr(buf, "google.com") == NULL && strstr(buf, "dns.google") == NULL) { - ALOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com or dns.google: %s", + LOGD("getnameinfo(%s (GoogleDNS) ) didn't return google.com or dns.google: %s", GoogleDNSIpV6Address2, buf); return JNI_FALSE; } @@ -142,11 +147,11 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas // gethostbyname struct hostent *my_hostent = gethostbyname("www.youtube.com"); if (my_hostent == NULL) { - ALOGD("gethostbyname(www.youtube.com) gave null response"); + LOGD("gethostbyname(www.youtube.com) gave null response"); return JNI_FALSE; } if ((my_hostent->h_addr_list == NULL) || (*my_hostent->h_addr_list == NULL)) { - ALOGD("gethostbyname(www.youtube.com) gave 0 addresses"); + LOGD("gethostbyname(www.youtube.com) gave 0 addresses"); return JNI_FALSE; } { @@ -154,7 +159,7 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas while (*current != NULL) { char buf[256]; inet_ntop(my_hostent->h_addrtype, *current, buf, sizeof(buf)); - ALOGD("gethostbyname(www.youtube.com) gave %s", buf); + LOGD("gethostbyname(www.youtube.com) gave %s", buf); current++; } } @@ -164,11 +169,11 @@ JNIEXPORT jboolean Java_android_net_cts_DnsTest_testNativeDns(JNIEnv* env, jclas inet_pton(AF_INET6, GoogleDNSIpV6Address, addr6); my_hostent = gethostbyaddr(addr6, sizeof(addr6), AF_INET6); if (my_hostent == NULL) { - ALOGD("gethostbyaddr(%s (GoogleDNS) ) gave null response", GoogleDNSIpV6Address); + LOGD("gethostbyaddr(%s (GoogleDNS) ) gave null response", GoogleDNSIpV6Address); return JNI_FALSE; } - ALOGD("gethostbyaddr(%s (GoogleDNS) ) gave %s for name", GoogleDNSIpV6Address, + LOGD("gethostbyaddr(%s (GoogleDNS) ) gave %s for name", GoogleDNSIpV6Address, my_hostent->h_name ? my_hostent->h_name : "null"); if (my_hostent->h_name == NULL) return JNI_FALSE; diff --git a/tests/cts/net/jni/NativeMultinetworkJni.cpp b/tests/cts/net/jni/NativeMultinetworkJni.cpp index 2832c3d142..cd94709fd5 100644 --- a/tests/cts/net/jni/NativeMultinetworkJni.cpp +++ b/tests/cts/net/jni/NativeMultinetworkJni.cpp @@ -16,7 +16,6 @@ #define LOG_TAG "MultinetworkApiTest" -#include #include #include @@ -34,9 +33,13 @@ #include +#include #include #include +#define LOGD(fmt, ...) \ + __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, fmt, ##__VA_ARGS__) + #define EXPECT_GE(env, actual, expected, msg) \ do { \ if (actual < expected) { \ @@ -138,7 +141,7 @@ int expectAnswersNotValid(JNIEnv* env, int fd, int expectedErrno) { uint8_t buf[MAXPACKET] = {}; int res = getAsyncResponse(env, fd, TIMEOUT_MS, &rcode, buf, MAXPACKET); if (res != expectedErrno) { - ALOGD("res:%d, expectedErrno = %d", res, expectedErrno); + LOGD("res:%d, expectedErrno = %d", res, expectedErrno); return (res > 0) ? -EREMOTEIO : res; } return 0; @@ -326,7 +329,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runGetaddrinfoCheck( const int saved_errno = errno; freeaddrinfo(res); - ALOGD("android_getaddrinfofornetwork(%" PRIu64 ", %s) returned rval=%d errno=%d", + LOGD("android_getaddrinfofornetwork(%" PRIu64 ", %s) returned rval=%d errno=%d", handle, kHostname, rval, saved_errno); return rval == 0 ? 0 : -saved_errno; } @@ -339,7 +342,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runSetprocnetwork( errno = 0; int rval = android_setprocnetwork(handle); const int saved_errno = errno; - ALOGD("android_setprocnetwork(%" PRIu64 ") returned rval=%d errno=%d", + LOGD("android_setprocnetwork(%" PRIu64 ") returned rval=%d errno=%d", handle, rval, saved_errno); return rval == 0 ? 0 : -saved_errno; } @@ -352,14 +355,14 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runSetsocknetwork( errno = 0; int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); if (fd < 0) { - ALOGD("socket() failed, errno=%d", errno); + LOGD("socket() failed, errno=%d", errno); return -errno; } errno = 0; int rval = android_setsocknetwork(handle, fd); const int saved_errno = errno; - ALOGD("android_setprocnetwork(%" PRIu64 ", %d) returned rval=%d errno=%d", + LOGD("android_setprocnetwork(%" PRIu64 ", %d) returned rval=%d errno=%d", handle, fd, rval, saved_errno); close(fd); return rval == 0 ? 0 : -saved_errno; @@ -404,7 +407,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( static const char kPort[] = "443"; int rval = android_getaddrinfofornetwork(handle, kHostname, kPort, &kHints, &res); if (rval != 0) { - ALOGD("android_getaddrinfofornetwork(%llu, %s) returned rval=%d errno=%d", + LOGD("android_getaddrinfofornetwork(%llu, %s) returned rval=%d errno=%d", handle, kHostname, rval, errno); freeaddrinfo(res); return -errno; @@ -413,14 +416,14 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( // Rely upon getaddrinfo sorting the best destination to the front. int fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (fd < 0) { - ALOGD("socket(%d, %d, %d) failed, errno=%d", + LOGD("socket(%d, %d, %d) failed, errno=%d", res->ai_family, res->ai_socktype, res->ai_protocol, errno); freeaddrinfo(res); return -errno; } rval = android_setsocknetwork(handle, fd); - ALOGD("android_setprocnetwork(%llu, %d) returned rval=%d errno=%d", + LOGD("android_setprocnetwork(%llu, %d) returned rval=%d errno=%d", handle, fd, rval, errno); if (rval != 0) { close(fd); @@ -430,7 +433,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( char addrstr[kSockaddrStrLen+1]; sockaddr_ntop(res->ai_addr, res->ai_addrlen, addrstr, sizeof(addrstr)); - ALOGD("Attempting connect() to %s ...", addrstr); + LOGD("Attempting connect() to %s ...", addrstr); rval = connect(fd, res->ai_addr, res->ai_addrlen); if (rval != 0) { @@ -447,7 +450,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( return -errno; } sockaddr_ntop((const struct sockaddr *)&src_addr, sizeof(src_addr), addrstr, sizeof(addrstr)); - ALOGD("... from %s", addrstr); + LOGD("... from %s", addrstr); // Don't let reads or writes block indefinitely. const struct timeval timeo = { 2, 0 }; // 2 seconds @@ -479,7 +482,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( sent = send(fd, quic_packet, sizeof(quic_packet), 0); if (sent < (ssize_t)sizeof(quic_packet)) { errnum = errno; - ALOGD("send(QUIC packet) returned sent=%zd, errno=%d", sent, errnum); + LOGD("send(QUIC packet) returned sent=%zd, errno=%d", sent, errnum); close(fd); return -errnum; } @@ -489,14 +492,14 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( break; } else { errnum = errno; - ALOGD("[%d/%d] recv(QUIC response) returned rcvd=%zd, errno=%d", + LOGD("[%d/%d] recv(QUIC response) returned rcvd=%zd, errno=%d", i + 1, MAX_RETRIES, rcvd, errnum); } } if (rcvd < 9) { - ALOGD("QUIC UDP %s: sent=%zd but rcvd=%zd, errno=%d", kPort, sent, rcvd, errnum); + LOGD("QUIC UDP %s: sent=%zd but rcvd=%zd, errno=%d", kPort, sent, rcvd, errnum); if (rcvd <= 0) { - ALOGD("Does this network block UDP port %s?", kPort); + LOGD("Does this network block UDP port %s?", kPort); } close(fd); return -EPROTO; @@ -504,7 +507,7 @@ JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck( int conn_id_cmp = memcmp(quic_packet + 1, response + 1, 8); if (conn_id_cmp != 0) { - ALOGD("sent and received connection IDs do not match"); + LOGD("sent and received connection IDs do not match"); close(fd); return -EPROTO; } diff --git a/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java index 0a80047fdf..9d357055d1 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java @@ -18,15 +18,17 @@ package android.net.cts; import static android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import android.content.Context; import android.net.ConnectivityDiagnosticsManager; import android.net.NetworkRequest; +import android.os.Build; import androidx.test.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; + +import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; +import com.android.testutils.DevSdkIgnoreRunner; import org.junit.Before; import org.junit.Test; @@ -34,7 +36,8 @@ import org.junit.runner.RunWith; import java.util.concurrent.Executor; -@RunWith(AndroidJUnit4.class) +@RunWith(DevSdkIgnoreRunner.class) +@IgnoreUpTo(Build.VERSION_CODES.Q) // ConnectivityDiagnosticsManager did not exist in Q public class ConnectivityDiagnosticsManagerTest { private static final Executor INLINE_EXECUTOR = x -> x.run(); private static final NetworkRequest DEFAULT_REQUEST = new NetworkRequest.Builder().build(); diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt index 89d3dff66c..03b961bc4b 100644 --- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt @@ -180,7 +180,7 @@ class NetworkAgentTest { } private open class TestableNetworkAgent( - val looper: Looper, + looper: Looper, val nc: NetworkCapabilities, val lp: LinkProperties, conf: NetworkAgentConfig From e3711ae3178ec598430c834efd60f2c43417a5ef Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Tue, 25 Jun 2019 14:17:35 -0700 Subject: [PATCH 0902/1109] Pull service dumps to help debug test failures. + Convert tests to use Junit4 + Add annotations to specify required conditions for the test to run. Bug: 137859686 Test: atest hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java Test: atest hostsidetests/net/src/com/android/cts/net/HostsideNetworkCallbackTests.java Change-Id: I93317c201a0ea06732e29154ab7e140735381f59 Merged-In: I93317c201a0ea06732e29154ab7e140735381f59 --- tests/cts/hostside/AndroidTest.xml | 5 + tests/cts/hostside/app/Android.bp | 2 + tests/cts/hostside/app/AndroidManifest.xml | 3 +- .../net/hostside/AbstractAppIdleTestCase.java | 76 ++-- .../AbstractBatterySaverModeTestCase.java | 68 +--- .../hostside/AbstractDozeModeTestCase.java | 66 +--- ...ractRestrictBackgroundNetworkTestCase.java | 361 ++---------------- .../cts/net/hostside/AppIdleMeteredTest.java | 13 +- .../net/hostside/AppIdleNonMeteredTest.java | 7 +- .../hostside/BatterySaverModeMeteredTest.java | 13 +- .../BatterySaverModeNonMeteredTest.java | 9 +- .../cts/net/hostside/DataSaverModeTest.java | 66 ++-- .../cts/net/hostside/DozeModeMeteredTest.java | 13 +- .../net/hostside/DozeModeNonMeteredTest.java | 8 +- .../cts/net/hostside/DumpOnFailureRule.java | 91 +++++ .../MeterednessConfigurationRule.java | 60 +++ .../cts/net/hostside/MixedModesTest.java | 230 +++++------ .../cts/net/hostside/NetworkCallbackTest.java | 173 +++++---- .../net/hostside/NetworkPolicyTestUtils.java | 255 +++++++++++++ .../android/cts/net/hostside/Property.java | 70 ++++ .../cts/net/hostside/RequiredProperties.java | 31 ++ .../net/hostside/RequiredPropertiesRule.java | 90 +++++ .../cts/net/HostsideNetworkCallbackTests.java | 8 +- .../cts/net/HostsideNetworkTestCase.java | 3 +- 24 files changed, 939 insertions(+), 782 deletions(-) create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/Property.java create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredProperties.java create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java diff --git a/tests/cts/hostside/AndroidTest.xml b/tests/cts/hostside/AndroidTest.xml index dbff1794e9..5479c51a4c 100644 --- a/tests/cts/hostside/AndroidTest.xml +++ b/tests/cts/hostside/AndroidTest.xml @@ -31,4 +31,9 @@

    By default is empty - it's up to subclasses to override. - */ - protected void setUpMeteredNetwork() throws Exception { - } - - /** - * Resets the (non) metered network state. - * - *

    By default is empty - it's up to subclasses to override. - */ - protected void tearDownMeteredNetwork() throws Exception { + setBatterySaverMode(false); } + @Test public void testBackgroundNetworkAccess_enabled() throws Exception { - if (!isSupported()) return; - setBatterySaverMode(true); assertBackgroundNetworkAccess(false); @@ -118,9 +80,8 @@ abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgrou assertBackgroundNetworkAccess(false); } + @Test public void testBackgroundNetworkAccess_whitelisted() throws Exception { - if (!isSupported()) return; - setBatterySaverMode(true); assertBackgroundNetworkAccess(false); @@ -140,9 +101,8 @@ abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgrou assertBackgroundNetworkAccess(false); } + @Test public void testBackgroundNetworkAccess_disabled() throws Exception { - if (!isSupported()) return; - assertBackgroundNetworkAccess(true); assertsForegroundAlwaysHasNetworkAccess(); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java index f20f1d1c4d..6f32c563c1 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java @@ -16,20 +16,25 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.Property.DOZE_MODE; +import static com.android.cts.net.hostside.Property.NOT_LOW_RAM_DEVICE; + import android.os.SystemClock; -import android.util.Log; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; /** * Base class for metered and non-metered Doze Mode tests. */ +@RequiredProperties({DOZE_MODE}) abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetworkTestCase { - @Override - protected final void setUp() throws Exception { + @Before + public final void setUp() throws Exception { super.setUp(); - if (!isSupported()) return; - // Set initial state. removePowerSaveModeWhitelist(TEST_APP2_PKG); removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG); @@ -38,48 +43,15 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor registerBroadcastReceiver(); } - @Override - protected final void tearDown() throws Exception { + @After + public final void tearDown() throws Exception { super.tearDown(); - if (!isSupported()) return; - - try { - tearDownMeteredNetwork(); - } finally { - setDozeMode(false); - } - } - - @Override - protected boolean isSupported() throws Exception { - boolean supported = isDozeModeEnabled(); - if (!supported) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Doze Mode"); - } - return supported; - } - - /** - * Sets the initial (non) metered network state. - * - *

    By default is empty - it's up to subclasses to override. - */ - protected void setUpMeteredNetwork() throws Exception { - } - - /** - * Resets the (non) metered network state. - * - *

    By default is empty - it's up to subclasses to override. - */ - protected void tearDownMeteredNetwork() throws Exception { + setDozeMode(false); } + @Test public void testBackgroundNetworkAccess_enabled() throws Exception { - if (!isSupported()) return; - setDozeMode(true); assertBackgroundNetworkAccess(false); @@ -96,9 +68,8 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor assertBackgroundNetworkAccess(false); } + @Test public void testBackgroundNetworkAccess_whitelisted() throws Exception { - if (!isSupported()) return; - setDozeMode(true); assertBackgroundNetworkAccess(false); @@ -118,19 +89,18 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor assertBackgroundNetworkAccess(false); } + @Test public void testBackgroundNetworkAccess_disabled() throws Exception { - if (!isSupported()) return; - assertBackgroundNetworkAccess(true); assertsForegroundAlwaysHasNetworkAccess(); assertBackgroundNetworkAccess(true); } + @RequiredProperties({NOT_LOW_RAM_DEVICE}) + @Test public void testBackgroundNetworkAccess_enabledButWhitelistedOnNotificationAction() throws Exception { - if (!isSupported() || isLowRamDevice()) return; - setPendingIntentWhitelistDuration(NETWORK_TIMEOUT_MS); try { registerNotificationListenerService(); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 40d7e34fcc..57b7bb4f8d 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -17,14 +17,22 @@ package com.android.cts.net.hostside; import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; -import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; -import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; -import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; import static android.os.BatteryManager.BATTERY_PLUGGED_AC; import static android.os.BatteryManager.BATTERY_PLUGGED_USB; import static android.os.BatteryManager.BATTERY_PLUGGED_WIRELESS; -import static com.android.compatibility.common.util.SystemUtil.runShellCommand; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.executeShellCommand; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getConnectivityManager; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getContext; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getInstrumentation; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getWifiManager; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isDozeModeSupported; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.restrictBackgroundValueToString; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import android.app.ActivityManager; import android.app.Instrumentation; @@ -34,9 +42,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.pm.PackageManager; import android.net.ConnectivityManager; -import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; import android.net.wifi.WifiManager; @@ -44,24 +50,27 @@ import android.os.BatteryManager; import android.os.Binder; import android.os.Bundle; import android.os.SystemClock; -import android.os.SystemProperties; import android.provider.Settings; import android.service.notification.NotificationListenerService; -import android.test.InstrumentationTestCase; -import android.text.TextUtils; import android.util.Log; -import com.android.compatibility.common.util.BatteryUtils; +import org.junit.Rule; +import org.junit.rules.RuleChain; +import org.junit.runner.RunWith; import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + /** * Superclass for tests related to background network restrictions. */ -abstract class AbstractRestrictBackgroundNetworkTestCase extends InstrumentationTestCase { - protected static final String TAG = "RestrictBackgroundNetworkTests"; +@RunWith(AndroidJUnit4.class) +public abstract class AbstractRestrictBackgroundNetworkTestCase { + public static final String TAG = "RestrictBackgroundNetworkTests"; protected static final String TEST_PKG = "com.android.cts.net.hostside"; protected static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2"; @@ -98,8 +107,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation static final int NETWORK_TIMEOUT_MS = 15 * SECOND_IN_MS; private static int PROCESS_STATE_FOREGROUND_SERVICE; - private static final int PROCESS_STATE_TOP = 2; - private static final String KEY_NETWORK_STATE_OBSERVER = TEST_PKG + ".observer"; protected static final int TYPE_COMPONENT_ACTIVTIY = 0; @@ -126,22 +133,23 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected WifiManager mWfm; protected int mUid; private int mMyUid; - private String mMeteredWifi; private MyServiceClient mServiceClient; private String mDeviceIdleConstantsSetting; - private boolean mSupported; private boolean mIsLocationOn; - @Override + @Rule + public final RuleChain mRuleChain = RuleChain.outerRule(new DumpOnFailureRule()) + .around(new RequiredPropertiesRule()) + .around(new MeterednessConfigurationRule()); + protected void setUp() throws Exception { - super.setUp(); PROCESS_STATE_FOREGROUND_SERVICE = (Integer) ActivityManager.class .getDeclaredField("PROCESS_STATE_FOREGROUND_SERVICE").get(null); mInstrumentation = getInstrumentation(); - mContext = mInstrumentation.getContext(); - mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); - mWfm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); + mContext = getContext(); + mCm = getConnectivityManager(); + mWfm = getWifiManager(); mUid = getUid(TEST_APP2_PKG); mMyUid = getUid(mContext.getPackageName()); mServiceClient = new MyServiceClient(mContext); @@ -151,10 +159,9 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation if (!mIsLocationOn) { enableLocation(); } - mSupported = setUpActiveNetworkMeteringState(); setAppIdle(false); - Log.i(TAG, "Apps status on " + getName() + ":\n" + Log.i(TAG, "Apps status:\n" + "\ttest app: uid=" + mMyUid + ", state=" + getProcessStateByUid(mMyUid) + "\n" + "\tapp2: uid=" + mUid + ", state=" + getProcessStateByUid(mUid)); @@ -165,16 +172,13 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation final String currentConstants = executeShellCommand("settings get global app_idle_constants"); assertEquals(appIdleConstants, currentConstants); - } + } - @Override protected void tearDown() throws Exception { if (!mIsLocationOn) { disableLocation(); } mServiceClient.unbind(); - - super.tearDown(); } private void enableLocation() throws Exception { @@ -259,23 +263,8 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected void assertRestrictBackgroundStatus(int expectedStatus) throws Exception { final String status = mServiceClient.getRestrictBackgroundStatus(); assertNotNull("didn't get API status from app2", status); - final String actualStatus = toString(Integer.parseInt(status)); - assertEquals("wrong status", toString(expectedStatus), actualStatus); - } - - protected void assertMyRestrictBackgroundStatus(int expectedStatus) throws Exception { - final int actualStatus = mCm.getRestrictBackgroundStatus(); - assertEquals("Wrong status", toString(expectedStatus), toString(actualStatus)); - } - - protected boolean isMyRestrictBackgroundStatus(int expectedStatus) throws Exception { - final int actualStatus = mCm.getRestrictBackgroundStatus(); - if (expectedStatus != actualStatus) { - Log.d(TAG, "Expected: " + toString(expectedStatus) - + " but actual: " + toString(actualStatus)); - return false; - } - return true; + assertEquals(restrictBackgroundValueToString(expectedStatus), + restrictBackgroundValueToString(Integer.parseInt(status))); } protected void assertBackgroundNetworkAccess(boolean expectAllowed) throws Exception { @@ -297,28 +286,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation assertNetworkAccess(true /* expectAvailable */, false /* needScreenOn */); } - /** - * Whether this device suport this type of test. - * - *

    Should be overridden when necessary (but always calling - * {@code super.isSupported()} first), and explicitly used before each test - * Example: - * - *

    
    -     * public void testSomething() {
    -     *    if (!isSupported()) return;
    -     * 
    - * - * @return {@code true} by default. - */ - protected boolean isSupported() throws Exception { - return mSupported; - } - - protected boolean isBatterySaverSupported() { - return BatteryUtils.isBatterySaverSupported(); - } - /** * Asserts that an app always have access while on foreground or running a foreground service. * @@ -387,23 +354,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation fail("App2 is not on foreground service state after " + maxTries + " attempts: " + state ); } - /** - * As per CDD requirements, if the device doesn't support data saver mode then - * ConnectivityManager.getRestrictBackgroundStatus() will always return - * RESTRICT_BACKGROUND_STATUS_DISABLED. So, enable the data saver mode and check if - * ConnectivityManager.getRestrictBackgroundStatus() for an app in background returns - * RESTRICT_BACKGROUND_STATUS_DISABLED or not. - */ - protected boolean isDataSaverSupported() throws Exception { - assertMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); - try { - setRestrictBackground(true); - return !isMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); - } finally { - setRestrictBackground(false); - } - } - /** * Returns whether an app state should be considered "background" for restriction purposes. */ @@ -443,40 +393,10 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation // Exponential back-off. timeoutMs = Math.min(timeoutMs*2, NETWORK_TIMEOUT_MS); } - dumpOnFailure(); fail("Invalid state for expectAvailable=" + expectAvailable + " after " + maxTries + " attempts.\nLast error: " + error); } - private void dumpOnFailure() throws Exception { - dumpAllNetworkRules(); - Log.d(TAG, "Usagestats dump: " + getUsageStatsDump()); - executeShellCommand("settings get global app_idle_constants"); - } - - private void dumpAllNetworkRules() throws Exception { - final String networkManagementDump = runShellCommand(mInstrumentation, - "dumpsys network_management").trim(); - final String networkPolicyDump = runShellCommand(mInstrumentation, - "dumpsys netpolicy").trim(); - TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter('\n'); - splitter.setString(networkManagementDump); - String next; - Log.d(TAG, ">>> Begin network_management dump"); - while (splitter.hasNext()) { - next = splitter.next(); - Log.d(TAG, next); - } - Log.d(TAG, "<<< End network_management dump"); - splitter.setString(networkPolicyDump); - Log.d(TAG, ">>> Begin netpolicy dump"); - while (splitter.hasNext()) { - next = splitter.next(); - Log.d(TAG, next); - } - Log.d(TAG, "<<< End netpolicy dump"); - } - /** * Checks whether the network is available as expected. * @@ -528,22 +448,10 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation return errors.toString(); } - protected boolean isLowRamDevice() { - final ActivityManager am = (ActivityManager) mContext.getSystemService( - Context.ACTIVITY_SERVICE); - return am.isLowRamDevice(); - } - - protected String executeShellCommand(String command) throws Exception { - final String result = runShellCommand(mInstrumentation, command).trim(); - if (DEBUG) Log.d(TAG, "Command '" + command + "' returned '" + result + "'"); - return result; - } - /** * Runs a Shell command which is not expected to generate output. */ - protected void executeSilentShellCommand(String command) throws Exception { + protected void executeSilentShellCommand(String command) { final String result = executeShellCommand(command); assertTrue("Command '" + command + "' failed: " + result, result.trim().isEmpty()); } @@ -572,10 +480,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation }); } - protected void assertDelayedShellCommand(String command, ExpectResultChecker checker) - throws Exception { - assertDelayedShellCommand(command, 5, 1, checker); - } protected void assertDelayedShellCommand(String command, int maxTries, int napTimeSeconds, ExpectResultChecker checker) throws Exception { String result = ""; @@ -592,159 +496,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation + " attempts. Last result: '" + result + "'"); } - /** - * Sets the initial metering state for the active network. - * - *

    It's called on setup and by default does nothing - it's up to the - * subclasses to override. - * - * @return whether the tests in the subclass are supported on this device. - */ - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return true; - } - - /** - * Makes sure the active network is not metered. - * - *

    If the device does not supoprt un-metered networks (for example if it - * only has cellular data but not wi-fi), it should return {@code false}; - * otherwise, it should return {@code true} (or fail if the un-metered - * network could not be set). - * - * @return {@code true} if the network is now unmetered. - */ - protected boolean setUnmeteredNetwork() throws Exception { - final NetworkInfo info = mCm.getActiveNetworkInfo(); - assertNotNull("Could not get active network", info); - if (!mCm.isActiveNetworkMetered()) { - Log.d(TAG, "Active network is not metered: " + info); - } else if (info.getType() == ConnectivityManager.TYPE_WIFI) { - Log.i(TAG, "Setting active WI-FI network as not metered: " + info ); - setWifiMeteredStatus(false); - } else { - Log.d(TAG, "Active network cannot be set to un-metered: " + info); - return false; - } - assertActiveNetworkMetered(false); // Sanity check. - return true; - } - - /** - * Enables metering on the active network if supported. - * - *

    If the device does not support metered networks it should return - * {@code false}; otherwise, it should return {@code true} (or fail if the - * metered network could not be set). - * - * @return {@code true} if the network is now metered. - */ - protected boolean setMeteredNetwork() throws Exception { - final NetworkInfo info = mCm.getActiveNetworkInfo(); - final boolean metered = mCm.isActiveNetworkMetered(); - if (metered) { - Log.d(TAG, "Active network already metered: " + info); - return true; - } else if (info.getType() != ConnectivityManager.TYPE_WIFI) { - Log.w(TAG, "Active network does not support metering: " + info); - return false; - } else { - Log.w(TAG, "Active network not metered: " + info); - } - final String netId = setWifiMeteredStatus(true); - - // Set flag so status is reverted on resetMeteredNetwork(); - mMeteredWifi = netId; - // Sanity check. - assertWifiMeteredStatus(netId, true); - assertActiveNetworkMetered(true); - return true; - } - - /** - * Resets the device metering state to what it was before the test started. - * - *

    This reverts any metering changes made by {@code setMeteredNetwork}. - */ - protected void resetMeteredNetwork() throws Exception { - if (mMeteredWifi != null) { - Log.i(TAG, "resetMeteredNetwork(): SID '" + mMeteredWifi - + "' was set as metered by test case; resetting it"); - setWifiMeteredStatus(mMeteredWifi, false); - assertActiveNetworkMetered(false); // Sanity check. - } - } - - private void assertActiveNetworkMetered(boolean expected) throws Exception { - final int maxTries = 5; - NetworkInfo info = null; - for (int i = 1; i <= maxTries; i++) { - info = mCm.getActiveNetworkInfo(); - if (info == null) { - Log.v(TAG, "No active network info on attempt #" + i - + "; sleeping 1s before polling again"); - } else if (mCm.isActiveNetworkMetered() != expected) { - Log.v(TAG, "Wrong metered status for active network " + info + "; expected=" - + expected + "; sleeping 1s before polling again"); - } else { - break; - } - Thread.sleep(SECOND_IN_MS); - } - assertNotNull("No active network after " + maxTries + " attempts", info); - assertEquals("Wrong metered status for active network " + info, expected, - mCm.isActiveNetworkMetered()); - } - - private String setWifiMeteredStatus(boolean metered) throws Exception { - // We could call setWifiEnabled() here, but it might take sometime to be in a consistent - // state (for example, if one of the saved network is not properly authenticated), so it's - // better to let the hostside test take care of that. - assertTrue("wi-fi is disabled", mWfm.isWifiEnabled()); - // TODO: if it's not guaranteed the device has wi-fi, we need to change the tests - // to make the actual verification of restrictions optional. - final String ssid = mWfm.getConnectionInfo().getSSID(); - return setWifiMeteredStatus(ssid, metered); - } - - private String setWifiMeteredStatus(String ssid, boolean metered) throws Exception { - assertNotNull("null SSID", ssid); - final String netId = ssid.trim().replaceAll("\"", ""); // remove quotes, if any. - assertFalse("empty SSID", ssid.isEmpty()); - - Log.i(TAG, "Setting wi-fi network " + netId + " metered status to " + metered); - final String setCommand = "cmd netpolicy set metered-network " + netId + " " + metered; - assertDelayedShellCommand(setCommand, ""); - - return netId; - } - - private void assertWifiMeteredStatus(String netId, boolean status) throws Exception { - final String command = "cmd netpolicy list wifi-networks"; - final String expectedLine = netId + ";" + status; - assertDelayedShellCommand(command, new ExpectResultChecker() { - - @Override - public boolean isExpected(String result) { - return result.contains(expectedLine); - } - - @Override - public String getExpected() { - return "line containing " + expectedLine; - } - }); - } - - protected void setRestrictBackground(boolean enabled) throws Exception { - executeShellCommand("cmd netpolicy set restrict-background " + enabled); - final String output = executeShellCommand("cmd netpolicy get restrict-background "); - final String expectedSuffix = enabled ? "enabled" : "disabled"; - // TODO: use MoreAsserts? - assertTrue("output '" + output + "' should end with '" + expectedSuffix + "'", - output.endsWith(expectedSuffix)); - } - protected void addRestrictBackgroundWhitelist(int uid) throws Exception { executeShellCommand("cmd netpolicy add restrict-background-whitelist " + uid); assertRestrictBackgroundWhitelist(uid, true); @@ -924,7 +675,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected void setDozeMode(boolean enabled) throws Exception { // Sanity check, since tests should check beforehand.... - assertTrue("Device does not support Doze Mode", isDozeModeEnabled()); + assertTrue("Device does not support Doze Mode", isDozeModeSupported()); Log.i(TAG, "Setting Doze Mode to " + enabled); if (enabled) { @@ -944,43 +695,16 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation assertDelayedShellCommand("dumpsys deviceidle get deep", enabled ? "IDLE" : "ACTIVE"); } - protected boolean isDozeModeEnabled() throws Exception { - final String result = executeShellCommand("cmd deviceidle enabled deep").trim(); - return result.equals("1"); - } - protected void setAppIdle(boolean enabled) throws Exception { Log.i(TAG, "Setting app idle to " + enabled); executeSilentShellCommand("am set-inactive " + TEST_APP2_PKG + " " + enabled ); assertAppIdle(enabled); // Sanity check } - private String getUsageStatsDump() throws Exception { - final String output = runShellCommand(mInstrumentation, "dumpsys usagestats").trim(); - final StringBuilder sb = new StringBuilder(); - final TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter('\n'); - splitter.setString(output); - String str; - while (splitter.hasNext()) { - str = splitter.next(); - if (str.contains("package=") - && !str.contains(TEST_PKG) && !str.contains(TEST_APP2_PKG)) { - continue; - } - if (str.trim().startsWith("config=") || str.trim().startsWith("time=")) { - continue; - } - sb.append(str).append('\n'); - } - return sb.toString(); - } - protected void assertAppIdle(boolean enabled) throws Exception { try { assertDelayedShellCommand("am get-inactive " + TEST_APP2_PKG, 15, 2, "Idle=" + enabled); } catch (Throwable e) { - Log.d(TAG, "UsageStats dump:\n" + getUsageStatsDump()); - executeShellCommand("settings get global app_idle_constants"); throw e; } } @@ -1061,12 +785,10 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation // App didn't come to foreground when the activity is started, so try again. assertForegroundNetworkAccess(); } else { - dumpOnFailure(); fail("Network is not available for app2 (" + mUid + "): " + errors[0]); } } } else { - dumpOnFailure(); fail("Timed out waiting for network availability status from app2 (" + mUid + ")"); } } else { @@ -1150,19 +872,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation } } - private String toString(int status) { - switch (status) { - case RESTRICT_BACKGROUND_STATUS_DISABLED: - return "DISABLED"; - case RESTRICT_BACKGROUND_STATUS_WHITELISTED: - return "WHITELISTED"; - case RESTRICT_BACKGROUND_STATUS_ENABLED: - return "ENABLED"; - default: - return "UNKNOWN_STATUS_" + status; - } - } - private ProcessState getProcessStateByUid(int uid) throws Exception { return new ProcessState(executeShellCommand("cmd activity get-uid-state " + uid)); } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java index 622d99361f..f1858d65a5 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java @@ -16,15 +16,8 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; + +@RequiredProperties({METERED_NETWORK}) public class AppIdleMeteredTest extends AbstractAppIdleTestCase { - - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setMeteredNetwork(); - } - - @Override - protected void tearDownMeteredNetwork() throws Exception { - resetMeteredNetwork(); - } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java index bde71f9100..e737a6dabe 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java @@ -16,9 +16,8 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; + +@RequiredProperties({NON_METERED_NETWORK}) public class AppIdleNonMeteredTest extends AbstractAppIdleTestCase { - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setUnmeteredNetwork(); - } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java index 3071cfe3f1..c78ca2ec77 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java @@ -16,15 +16,8 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; + +@RequiredProperties({METERED_NETWORK}) public class BatterySaverModeMeteredTest extends AbstractBatterySaverModeTestCase { - - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setMeteredNetwork(); - } - - @Override - protected void tearDownMeteredNetwork() throws Exception { - resetMeteredNetwork(); - } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java index 6d3076fe0e..fb52a540d8 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java @@ -16,10 +16,9 @@ package com.android.cts.net.hostside; -public class BatterySaverModeNonMeteredTest extends AbstractBatterySaverModeTestCase { - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setUnmeteredNetwork(); - } +import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; + +@RequiredProperties({NON_METERED_NETWORK}) +public class BatterySaverModeNonMeteredTest extends AbstractBatterySaverModeTestCase { } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index cfe6a73a0f..aa2c914e02 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -20,24 +20,33 @@ import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLE import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; -import android.util.Log; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground; +import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; +import static com.android.cts.net.hostside.Property.NO_DATA_SAVER_MODE; + +import static org.junit.Assert.fail; import com.android.compatibility.common.util.CddTest; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import androidx.test.filters.LargeTest; + +@RequiredProperties({DATA_SAVER_MODE, METERED_NETWORK}) +@LargeTest public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase { private static final String[] REQUIRED_WHITELISTED_PACKAGES = { "com.android.providers.downloads" }; - private boolean mIsDataSaverSupported; - - @Override + @Before public void setUp() throws Exception { super.setUp(); - mIsDataSaverSupported = isDataSaverSupported(); - // Set initial state. setRestrictBackground(false); removeRestrictBackgroundWhitelist(mUid); @@ -47,36 +56,15 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertRestrictBackgroundChangedReceived(0); } - @Override - protected void tearDown() throws Exception { + @After + public void tearDown() throws Exception { super.tearDown(); - if (!isSupported()) return; - - try { - resetMeteredNetwork(); - } finally { - setRestrictBackground(false); - } - } - - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setMeteredNetwork(); - } - - @Override - protected boolean isSupported() throws Exception { - if (!mIsDataSaverSupported) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Data Saver Mode"); - } - return mIsDataSaverSupported && super.isSupported(); + setRestrictBackground(false); } + @Test public void testGetRestrictBackgroundStatus_disabled() throws Exception { - if (!isSupported()) return; - assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED); // Sanity check: make sure status is always disabled, never whitelisted @@ -88,9 +76,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED); } + @Test public void testGetRestrictBackgroundStatus_whitelisted() throws Exception { - if (!isSupported()) return; - setRestrictBackground(true); assertRestrictBackgroundChangedReceived(1); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); @@ -107,9 +94,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); } + @Test public void testGetRestrictBackgroundStatus_enabled() throws Exception { - if (!isSupported()) return; - setRestrictBackground(true); assertRestrictBackgroundChangedReceived(1); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); @@ -142,9 +128,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertBackgroundNetworkAccess(false); } + @Test public void testGetRestrictBackgroundStatus_blacklisted() throws Exception { - if (!isSupported()) return; - addRestrictBackgroundBlacklist(mUid); assertRestrictBackgroundChangedReceived(1); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); @@ -180,9 +165,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertsForegroundAlwaysHasNetworkAccess(); } + @Test public void testGetRestrictBackgroundStatus_requiredWhitelistedPackages() throws Exception { - if (!isSupported()) return; - final StringBuilder error = new StringBuilder(); for (String packageName : REQUIRED_WHITELISTED_PACKAGES) { int uid = -1; @@ -202,10 +186,10 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase } } + @RequiredProperties({NO_DATA_SAVER_MODE}) @CddTest(requirement="7.4.7/C-2-2") + @Test public void testBroadcastNotSentOnUnsupportedDevices() throws Exception { - if (isSupported()) return; - setRestrictBackground(true); assertRestrictBackgroundChangedReceived(0); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java index e4189af587..4306c991c2 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java @@ -16,15 +16,8 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; + +@RequiredProperties({METERED_NETWORK}) public class DozeModeMeteredTest extends AbstractDozeModeTestCase { - - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setMeteredNetwork(); - } - - @Override - protected void tearDownMeteredNetwork() throws Exception { - resetMeteredNetwork(); - } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java index edbbb9e1ce..1e89f158a3 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java @@ -16,10 +16,8 @@ package com.android.cts.net.hostside; -public class DozeModeNonMeteredTest extends AbstractDozeModeTestCase { +import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setUnmeteredNetwork(); - } +@RequiredProperties({NON_METERED_NETWORK}) +public class DozeModeNonMeteredTest extends AbstractDozeModeTestCase { } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java new file mode 100644 index 0000000000..cedd62a0bc --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TAG; +import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TEST_PKG; + +import android.os.Environment; +import android.os.FileUtils; +import android.os.ParcelFileDescriptor; +import android.util.Log; + +import com.android.compatibility.common.util.OnFailureRule; + +import org.junit.AssumptionViolatedException; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import androidx.test.platform.app.InstrumentationRegistry; + +public class DumpOnFailureRule extends OnFailureRule { + private File mDumpDir = new File(Environment.getExternalStorageDirectory(), + "CtsHostsideNetworkTests"); + + @Override + public void onTestFailure(Statement base, Description description, Throwable throwable) { + final String testName = description.getClassName() + "_" + description.getMethodName(); + + if (throwable instanceof AssumptionViolatedException) { + Log.d(TAG, "Skipping test " + testName + ": " + throwable); + return; + } + + prepareDumpRootDir(); + final File dumpFile = new File(mDumpDir, "dump-" + testName); + Log.i(TAG, "Dumping debug info for " + description + ": " + dumpFile.getPath()); + try (FileOutputStream out = new FileOutputStream(dumpFile)) { + for (String cmd : new String[] { + "dumpsys netpolicy", + "dumpsys network_management", + "dumpsys usagestats " + TEST_PKG, + "dumpsys usagestats appstandby", + }) { + dumpCommandOutput(out, cmd); + } + } catch (FileNotFoundException e) { + Log.e(TAG, "Error opening file: " + dumpFile, e); + } catch (IOException e) { + Log.e(TAG, "Error closing file: " + dumpFile, e); + } + } + + void dumpCommandOutput(FileOutputStream out, String cmd) { + final ParcelFileDescriptor pfd = InstrumentationRegistry.getInstrumentation() + .getUiAutomation().executeShellCommand(cmd); + try (FileInputStream in = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) { + out.write(("Output of '" + cmd + "':\n").getBytes(StandardCharsets.UTF_8)); + FileUtils.copy(in, out); + out.write("\n\n=================================================================\n\n" + .getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + Log.e(TAG, "Error dumping '" + cmd + "'", e); + } + } + + void prepareDumpRootDir() { + if (!mDumpDir.exists() && !mDumpDir.mkdir()) { + Log.e(TAG, "Error creating " + mDumpDir); + } + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java new file mode 100644 index 0000000000..8fadf9e295 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.resetMeteredNetwork; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setupMeteredNetwork; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; +import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; + +import android.util.ArraySet; +import android.util.Pair; + +import com.android.compatibility.common.util.BeforeAfterRule; + +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +public class MeterednessConfigurationRule extends BeforeAfterRule { + private Pair mSsidAndInitialMeteredness; + + @Override + public void onBefore(Statement base, Description description) throws Throwable { + final ArraySet requiredProperties + = RequiredPropertiesRule.getRequiredProperties(); + if (requiredProperties.contains(METERED_NETWORK)) { + configureNetworkMeteredness(true); + } else if (requiredProperties.contains(NON_METERED_NETWORK)) { + configureNetworkMeteredness(false); + } + } + + @Override + public void onAfter(Statement base, Description description) throws Throwable { + resetNetworkMeteredness(); + } + + public void configureNetworkMeteredness(boolean metered) throws Exception { + mSsidAndInitialMeteredness = setupMeteredNetwork(metered); + } + + public void resetNetworkMeteredness() throws Exception { + if (mSsidAndInitialMeteredness != null) { + resetMeteredNetwork(mSsidAndInitialMeteredness.first, + mSsidAndInitialMeteredness.second); + } + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java index b1a21867b3..c9edda6e0b 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java @@ -15,9 +15,21 @@ */ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground; +import static com.android.cts.net.hostside.Property.APP_STANDBY_MODE; +import static com.android.cts.net.hostside.Property.BATTERY_SAVER_MODE; +import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE; +import static com.android.cts.net.hostside.Property.DOZE_MODE; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; +import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; + import android.os.SystemClock; import android.util.Log; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + /** * Test cases for the more complex scenarios where multiple restrictions (like Battery Saver Mode * and Data Saver Mode) are applied simultaneously. @@ -29,12 +41,10 @@ import android.util.Log; public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { private static final String TAG = "MixedModesTest"; - @Override + @Before public void setUp() throws Exception { super.setUp(); - if (!isSupported()) return; - // Set initial state. removeRestrictBackgroundWhitelist(mUid); removeRestrictBackgroundBlacklist(mUid); @@ -44,12 +54,10 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { registerBroadcastReceiver(); } - @Override - protected void tearDown() throws Exception { + @After + public void tearDown() throws Exception { super.tearDown(); - if (!isSupported()) return; - try { setRestrictBackground(false); } finally { @@ -57,34 +65,15 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } - @Override - public boolean isSupported() throws Exception { - if (!isDozeModeEnabled()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Doze Mode"); - return false; - } - return true; - } - /** * Tests all DS ON and BS ON scenarios from network-policy-restrictions.md on metered networks. */ + @RequiredProperties({DATA_SAVER_MODE, BATTERY_SAVER_MODE, METERED_NETWORK}) + @Test public void testDataAndBatterySaverModes_meteredNetwork() throws Exception { - if (!isBatterySaverSupported()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Battery saver mode"); - return; - } - if (!isSupported()) return; - - Log.i(TAG, "testDataAndBatterySaverModes_meteredNetwork() tests"); - if (!setMeteredNetwork()) { - Log.w(TAG, "testDataAndBatterySaverModes_meteredNetwork() skipped because " - + "device cannot use a metered network"); - return; - } - + final MeterednessConfigurationRule meterednessConfiguration + = new MeterednessConfigurationRule(); + meterednessConfiguration.configureNetworkMeteredness(true); try { setRestrictBackground(true); setBatterySaverMode(true); @@ -137,7 +126,7 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { removeRestrictBackgroundBlacklist(mUid); removePowerSaveModeWhitelist(TEST_APP2_PKG); } finally { - resetMeteredNetwork(); + meterednessConfiguration.resetNetworkMeteredness(); } } @@ -145,86 +134,75 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { * Tests all DS ON and BS ON scenarios from network-policy-restrictions.md on non-metered * networks. */ + @RequiredProperties({DATA_SAVER_MODE, BATTERY_SAVER_MODE, NON_METERED_NETWORK}) + @Test public void testDataAndBatterySaverModes_nonMeteredNetwork() throws Exception { - if (!isBatterySaverSupported()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Battery saver mode"); - return; + final MeterednessConfigurationRule meterednessConfiguration + = new MeterednessConfigurationRule(); + meterednessConfiguration.configureNetworkMeteredness(false); + try { + setRestrictBackground(true); + setBatterySaverMode(true); + + Log.v(TAG, "Not whitelisted for any."); + assertBackgroundNetworkAccess(false); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + + Log.v(TAG, "Whitelisted for Data Saver but not for Battery Saver."); + addRestrictBackgroundWhitelist(mUid); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + removeRestrictBackgroundWhitelist(mUid); + + Log.v(TAG, "Whitelisted for Battery Saver but not for Data Saver."); + addPowerSaveModeWhitelist(TEST_APP2_PKG); + removeRestrictBackgroundWhitelist(mUid); + assertBackgroundNetworkAccess(true); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(true); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + + Log.v(TAG, "Whitelisted for both."); + addRestrictBackgroundWhitelist(mUid); + addPowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(true); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(true); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + removeRestrictBackgroundWhitelist(mUid); + + Log.v(TAG, "Blacklisted for Data Saver, not whitelisted for Battery Saver."); + addRestrictBackgroundBlacklist(mUid); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + removeRestrictBackgroundBlacklist(mUid); + + Log.v(TAG, "Blacklisted for Data Saver, whitelisted for Battery Saver."); + addRestrictBackgroundBlacklist(mUid); + addPowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(true); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(true); + removeRestrictBackgroundBlacklist(mUid); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + } finally { + meterednessConfiguration.resetNetworkMeteredness(); } - if (!isSupported()) return; - - if (!setUnmeteredNetwork()) { - Log.w(TAG, "testDataAndBatterySaverModes_nonMeteredNetwork() skipped because network" - + " is metered"); - return; - } - Log.i(TAG, "testDataAndBatterySaverModes_nonMeteredNetwork() tests"); - setRestrictBackground(true); - setBatterySaverMode(true); - - Log.v(TAG, "Not whitelisted for any."); - assertBackgroundNetworkAccess(false); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(false); - - Log.v(TAG, "Whitelisted for Data Saver but not for Battery Saver."); - addRestrictBackgroundWhitelist(mUid); - removePowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(false); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(false); - removeRestrictBackgroundWhitelist(mUid); - - Log.v(TAG, "Whitelisted for Battery Saver but not for Data Saver."); - addPowerSaveModeWhitelist(TEST_APP2_PKG); - removeRestrictBackgroundWhitelist(mUid); - assertBackgroundNetworkAccess(true); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(true); - removePowerSaveModeWhitelist(TEST_APP2_PKG); - - Log.v(TAG, "Whitelisted for both."); - addRestrictBackgroundWhitelist(mUid); - addPowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(true); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(true); - removePowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(false); - removeRestrictBackgroundWhitelist(mUid); - - Log.v(TAG, "Blacklisted for Data Saver, not whitelisted for Battery Saver."); - addRestrictBackgroundBlacklist(mUid); - removePowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(false); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(false); - removeRestrictBackgroundBlacklist(mUid); - - Log.v(TAG, "Blacklisted for Data Saver, whitelisted for Battery Saver."); - addRestrictBackgroundBlacklist(mUid); - addPowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(true); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(true); - removeRestrictBackgroundBlacklist(mUid); - removePowerSaveModeWhitelist(TEST_APP2_PKG); } /** * Tests that powersave whitelists works as expected when doze and battery saver modes * are enabled. */ + @RequiredProperties({DOZE_MODE, BATTERY_SAVER_MODE}) + @Test public void testDozeAndBatterySaverMode_powerSaveWhitelists() throws Exception { - if (!isBatterySaverSupported()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Battery saver mode"); - return; - } - if (!isSupported()) { - return; - } - setBatterySaverMode(true); setDozeMode(true); @@ -250,11 +228,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { * Tests that powersave whitelists works as expected when doze and appIdle modes * are enabled. */ + @RequiredProperties({DOZE_MODE, APP_STANDBY_MODE}) + @Test public void testDozeAndAppIdle_powerSaveWhitelists() throws Exception { - if (!isSupported()) { - return; - } - setDozeMode(true); setAppIdle(true); @@ -276,11 +252,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } + @RequiredProperties({APP_STANDBY_MODE, DOZE_MODE}) + @Test public void testAppIdleAndDoze_tempPowerSaveWhitelists() throws Exception { - if (!isSupported()) { - return; - } - setDozeMode(true); setAppIdle(true); @@ -299,16 +273,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } + @RequiredProperties({APP_STANDBY_MODE, BATTERY_SAVER_MODE}) + @Test public void testAppIdleAndBatterySaver_tempPowerSaveWhitelists() throws Exception { - if (!isBatterySaverSupported()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Battery saver mode"); - return; - } - if (!isSupported()) { - return; - } - setBatterySaverMode(true); setAppIdle(true); @@ -330,11 +297,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { /** * Tests that the app idle whitelist works as expected when doze and appIdle mode are enabled. */ + @RequiredProperties({DOZE_MODE, APP_STANDBY_MODE}) + @Test public void testDozeAndAppIdle_appIdleWhitelist() throws Exception { - if (!isSupported()) { - return; - } - setDozeMode(true); setAppIdle(true); @@ -353,11 +318,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } + @RequiredProperties({APP_STANDBY_MODE, DOZE_MODE}) + @Test public void testAppIdleAndDoze_tempPowerSaveAndAppIdleWhitelists() throws Exception { - if (!isSupported()) { - return; - } - setDozeMode(true); setAppIdle(true); @@ -380,16 +343,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } + @RequiredProperties({APP_STANDBY_MODE, BATTERY_SAVER_MODE}) + @Test public void testAppIdleAndBatterySaver_tempPowerSaveAndAppIdleWhitelists() throws Exception { - if (!isBatterySaverSupported()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Battery saver mode"); - return; - } - if (!isSupported()) { - return; - } - setBatterySaverMode(true); setAppIdle(true); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java index 24dde9d356..ed397b91fc 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java @@ -16,15 +16,26 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground; +import static com.android.cts.net.hostside.Property.BATTERY_SAVER_MODE; +import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + import android.net.Network; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + import java.util.Objects; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCase { - private boolean mIsDataSaverSupported; private Network mNetwork; private final TestNetworkCallback mTestNetworkCallback = new TestNetworkCallback(); @@ -132,108 +143,122 @@ public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCa } } - @Override + @Before public void setUp() throws Exception { super.setUp(); - mIsDataSaverSupported = isDataSaverSupported(); - mNetwork = mCm.getActiveNetwork(); - // Set initial state. - setBatterySaverMode(false); registerBroadcastReceiver(); - if (!mIsDataSaverSupported) return; - setRestrictBackground(false); removeRestrictBackgroundWhitelist(mUid); removeRestrictBackgroundBlacklist(mUid); assertRestrictBackgroundChangedReceived(0); } - @Override - protected void tearDown() throws Exception { + @After + public void tearDown() throws Exception { super.tearDown(); - if (!mIsDataSaverSupported) return; + setRestrictBackground(false); + setBatterySaverMode(false); + } + @RequiredProperties({DATA_SAVER_MODE}) + @Test + public void testOnBlockedStatusChanged_dataSaver() throws Exception { + // Initial state + setBatterySaverMode(false); + setRestrictBackground(false); + + final MeterednessConfigurationRule meterednessConfiguration + = new MeterednessConfigurationRule(); + meterednessConfiguration.configureNetworkMeteredness(true); try { - resetMeteredNetwork(); + // Register callback + registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); + mTestNetworkCallback.expectAvailableCallback(mNetwork); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Enable restrict background + setRestrictBackground(true); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); + + // Add to whitelist + addRestrictBackgroundWhitelist(mUid); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Remove from whitelist + removeRestrictBackgroundWhitelist(mUid); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); } finally { + meterednessConfiguration.resetNetworkMeteredness(); + } + + // Set to non-metered network + meterednessConfiguration.configureNetworkMeteredness(false); + try { + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Disable restrict background, should not trigger callback setRestrictBackground(false); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.assertNoCallback(); + } finally { + meterednessConfiguration.resetNetworkMeteredness(); } } - public void testOnBlockedStatusChanged_data_saver() throws Exception { - if (!mIsDataSaverSupported) return; - - // Prepare metered wifi - if (!setMeteredNetwork()) return; - - // Register callback - registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); - mTestNetworkCallback.expectAvailableCallback(mNetwork); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - - // Enable restrict background - setRestrictBackground(true); - assertBackgroundNetworkAccess(false); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); - - // Add to whitelist - addRestrictBackgroundWhitelist(mUid); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - - // Remove from whitelist - removeRestrictBackgroundWhitelist(mUid); - assertBackgroundNetworkAccess(false); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); - - // Set to non-metered network - setUnmeteredNetwork(); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - - // Disable restrict background, should not trigger callback + @RequiredProperties({BATTERY_SAVER_MODE}) + @Test + public void testOnBlockedStatusChanged_powerSaver() throws Exception { + // Set initial state. + setBatterySaverMode(false); setRestrictBackground(false); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.assertNoCallback(); - } + final MeterednessConfigurationRule meterednessConfiguration + = new MeterednessConfigurationRule(); + meterednessConfiguration.configureNetworkMeteredness(true); + try { + // Register callback + registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); + mTestNetworkCallback.expectAvailableCallback(mNetwork); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - public void testOnBlockedStatusChanged_power_saver() throws Exception { - // Prepare metered wifi - if (!setMeteredNetwork()) return; + // Enable Power Saver + setBatterySaverMode(true); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); - // Register callback - registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); - mTestNetworkCallback.expectAvailableCallback(mNetwork); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - - // Enable Power Saver - setBatterySaverMode(true); - assertBackgroundNetworkAccess(false); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); - - // Disable Power Saver - setBatterySaverMode(false); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + // Disable Power Saver + setBatterySaverMode(false); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + } finally { + meterednessConfiguration.resetNetworkMeteredness(); + } // Set to non-metered network - setUnmeteredNetwork(); - mTestNetworkCallback.assertNoCallback(); + meterednessConfiguration.configureNetworkMeteredness(false); + try { + mTestNetworkCallback.assertNoCallback(); - // Enable Power Saver - setBatterySaverMode(true); - assertBackgroundNetworkAccess(false); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); + // Enable Power Saver + setBatterySaverMode(true); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); - // Disable Power Saver - setBatterySaverMode(false); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + // Disable Power Saver + setBatterySaverMode(false); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + } finally { + meterednessConfiguration.resetNetworkMeteredness(); + } } // TODO: 1. test against VPN lockdown. diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java new file mode 100644 index 0000000000..ca2864c0b8 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; +import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; +import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; +import static android.net.NetworkCapabilities.TRANSPORT_WIFI; + +import static com.android.compatibility.common.util.SystemUtil.runShellCommand; +import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TAG; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import android.app.ActivityManager; +import android.app.Instrumentation; +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.ConnectivityManager.NetworkCallback; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.wifi.WifiManager; +import android.text.TextUtils; +import android.util.Log; +import android.util.Pair; + +import com.android.compatibility.common.util.AppStandbyUtils; +import com.android.compatibility.common.util.BatteryUtils; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import androidx.test.platform.app.InstrumentationRegistry; + +public class NetworkPolicyTestUtils { + + private static final int TIMEOUT_CHANGE_METEREDNESS_MS = 5000; + + private static ConnectivityManager mCm; + private static WifiManager mWm; + + private static Boolean mBatterySaverSupported; + private static Boolean mDataSaverSupported; + private static Boolean mDozeModeSupported; + private static Boolean mAppStandbySupported; + + private NetworkPolicyTestUtils() {} + + public static boolean isBatterySaverSupported() { + if (mBatterySaverSupported == null) { + mBatterySaverSupported = BatteryUtils.isBatterySaverSupported(); + } + return mBatterySaverSupported; + } + + /** + * As per CDD requirements, if the device doesn't support data saver mode then + * ConnectivityManager.getRestrictBackgroundStatus() will always return + * RESTRICT_BACKGROUND_STATUS_DISABLED. So, enable the data saver mode and check if + * ConnectivityManager.getRestrictBackgroundStatus() for an app in background returns + * RESTRICT_BACKGROUND_STATUS_DISABLED or not. + */ + public static boolean isDataSaverSupported() { + if (mDataSaverSupported == null) { + assertMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + try { + setRestrictBackground(true); + mDataSaverSupported = !isMyRestrictBackgroundStatus( + RESTRICT_BACKGROUND_STATUS_DISABLED); + } finally { + setRestrictBackground(false); + } + } + return mDataSaverSupported; + } + + public static boolean isDozeModeSupported() { + if (mDozeModeSupported == null) { + final String result = executeShellCommand("cmd deviceidle enabled deep"); + mDozeModeSupported = result.equals("1"); + } + return mDozeModeSupported; + } + + public static boolean isAppStandbySupported() { + if (mAppStandbySupported == null) { + mAppStandbySupported = AppStandbyUtils.isAppStandbyEnabled(); + } + return mAppStandbySupported; + } + + public static boolean isLowRamDevice() { + final ActivityManager am = (ActivityManager) getContext().getSystemService( + Context.ACTIVITY_SERVICE); + return am.isLowRamDevice(); + } + + public static boolean isActiveNetworkMetered(boolean metered) { + return getConnectivityManager().isActiveNetworkMetered() == metered; + } + + public static boolean canChangeActiveNetworkMeteredness() { + final Network activeNetwork = getConnectivityManager().getActiveNetwork(); + final NetworkCapabilities networkCapabilities + = getConnectivityManager().getNetworkCapabilities(activeNetwork); + return networkCapabilities.hasTransport(TRANSPORT_WIFI); + } + + public static Pair setupMeteredNetwork(boolean metered) throws Exception { + if (isActiveNetworkMetered(metered)) { + return null; + } + final String ssid = unquoteSSID(getWifiManager().getConnectionInfo().getSSID()); + setWifiMeteredStatus(ssid, metered); + return Pair.create(ssid, !metered); + } + + public static void resetMeteredNetwork(String ssid, boolean metered) throws Exception { + setWifiMeteredStatus(ssid, metered); + } + + public static void setWifiMeteredStatus(String ssid, boolean metered) throws Exception { + assertFalse("SSID should not be empty", TextUtils.isEmpty(ssid)); + final String cmd = "cmd netpolicy set metered-network " + ssid + " " + metered; + executeShellCommand(cmd); + assertWifiMeteredStatus(ssid, metered); + assertActiveNetworkMetered(metered); + } + + public static void assertWifiMeteredStatus(String ssid, boolean expectedMeteredStatus) { + final String result = executeShellCommand("cmd netpolicy list wifi-networks"); + final String expectedLine = ssid + ";" + expectedMeteredStatus; + assertTrue("Expected line: " + expectedLine + "; Actual result: " + result, + result.contains(expectedLine)); + } + + // Copied from cts/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java + public static void assertActiveNetworkMetered(boolean expectedMeteredStatus) throws Exception { + final CountDownLatch latch = new CountDownLatch(1); + final NetworkCallback networkCallback = new NetworkCallback() { + @Override + public void onCapabilitiesChanged(Network network, NetworkCapabilities nc) { + final boolean metered = !nc.hasCapability(NET_CAPABILITY_NOT_METERED); + if (metered == expectedMeteredStatus) { + latch.countDown(); + } + } + }; + // Registering a callback here guarantees onCapabilitiesChanged is called immediately + // with the current setting. Therefore, if the setting has already been changed, + // this method will return right away, and if not it will wait for the setting to change. + getConnectivityManager().registerDefaultNetworkCallback(networkCallback); + if (!latch.await(TIMEOUT_CHANGE_METEREDNESS_MS, TimeUnit.MILLISECONDS)) { + fail("Timed out waiting for active network metered status to change to " + + expectedMeteredStatus + " ; network = " + + getConnectivityManager().getActiveNetwork()); + } + getConnectivityManager().unregisterNetworkCallback(networkCallback); + } + + public static void setRestrictBackground(boolean enabled) { + executeShellCommand("cmd netpolicy set restrict-background " + enabled); + final String output = executeShellCommand("cmd netpolicy get restrict-background"); + final String expectedSuffix = enabled ? "enabled" : "disabled"; + assertTrue("output '" + output + "' should end with '" + expectedSuffix + "'", + output.endsWith(expectedSuffix)); + } + + public static boolean isMyRestrictBackgroundStatus(int expectedStatus) { + final int actualStatus = getConnectivityManager().getRestrictBackgroundStatus(); + if (expectedStatus != actualStatus) { + Log.d(TAG, "MyRestrictBackgroundStatus: " + + "Expected: " + restrictBackgroundValueToString(expectedStatus) + + "; Actual: " + restrictBackgroundValueToString(actualStatus)); + return false; + } + return true; + } + + // Copied from cts/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java + private static String unquoteSSID(String ssid) { + // SSID is returned surrounded by quotes if it can be decoded as UTF-8. + // Otherwise it's guaranteed not to start with a quote. + if (ssid.charAt(0) == '"') { + return ssid.substring(1, ssid.length() - 1); + } else { + return ssid; + } + } + + public static String restrictBackgroundValueToString(int status) { + switch (status) { + case RESTRICT_BACKGROUND_STATUS_DISABLED: + return "DISABLED"; + case RESTRICT_BACKGROUND_STATUS_WHITELISTED: + return "WHITELISTED"; + case RESTRICT_BACKGROUND_STATUS_ENABLED: + return "ENABLED"; + default: + return "UNKNOWN_STATUS_" + status; + } + } + + public static String executeShellCommand(String command) { + final String result = runShellCommand(command).trim(); + Log.d(TAG, "Output of '" + command + "': '" + result + "'"); + return result; + } + + public static void assertMyRestrictBackgroundStatus(int expectedStatus) { + final int actualStatus = getConnectivityManager().getRestrictBackgroundStatus(); + assertEquals(restrictBackgroundValueToString(expectedStatus), + restrictBackgroundValueToString(actualStatus)); + } + + public static ConnectivityManager getConnectivityManager() { + if (mCm == null) { + mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); + } + return mCm; + } + + public static WifiManager getWifiManager() { + if (mWm == null) { + mWm = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); + } + return mWm; + } + + public static Context getContext() { + return getInstrumentation().getContext(); + } + + public static Instrumentation getInstrumentation() { + return InstrumentationRegistry.getInstrumentation(); + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/Property.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/Property.java new file mode 100644 index 0000000000..18805f9613 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/Property.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.canChangeActiveNetworkMeteredness; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isActiveNetworkMetered; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isAppStandbySupported; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isBatterySaverSupported; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isDataSaverSupported; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isDozeModeSupported; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isLowRamDevice; + +public enum Property { + BATTERY_SAVER_MODE(1 << 0) { + public boolean isSupported() { return isBatterySaverSupported(); } + }, + + DATA_SAVER_MODE(1 << 1) { + public boolean isSupported() { return isDataSaverSupported(); } + }, + + NO_DATA_SAVER_MODE(~DATA_SAVER_MODE.getValue()) { + public boolean isSupported() { return !isDataSaverSupported(); } + }, + + DOZE_MODE(1 << 2) { + public boolean isSupported() { return isDozeModeSupported(); } + }, + + APP_STANDBY_MODE(1 << 3) { + public boolean isSupported() { return isAppStandbySupported(); } + }, + + NOT_LOW_RAM_DEVICE(1 << 4) { + public boolean isSupported() { return !isLowRamDevice(); } + }, + + METERED_NETWORK(1 << 5) { + public boolean isSupported() { + return isActiveNetworkMetered(true) || canChangeActiveNetworkMeteredness(); + } + }, + + NON_METERED_NETWORK(~METERED_NETWORK.getValue()) { + public boolean isSupported() { + return isActiveNetworkMetered(false) || canChangeActiveNetworkMeteredness(); + } + }; + + private int mValue; + + Property(int value) { mValue = value; } + + public int getValue() { return mValue; } + + abstract boolean isSupported(); +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredProperties.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredProperties.java new file mode 100644 index 0000000000..96838bba0a --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredProperties.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(RUNTIME) +@Target({METHOD, TYPE}) +@Inherited +public @interface RequiredProperties { + Property[] value(); +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java new file mode 100644 index 0000000000..1e333200db --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TAG; + +import android.text.TextUtils; +import android.util.ArraySet; +import android.util.Log; + +import com.android.compatibility.common.util.BeforeAfterRule; + +import org.junit.Assume; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import java.util.ArrayList; +import java.util.Collections; + +public class RequiredPropertiesRule extends BeforeAfterRule { + + private static ArraySet mRequiredProperties; + + @Override + public void onBefore(Statement base, Description description) { + mRequiredProperties = getAllRequiredProperties(description); + + final String testName = description.getClassName() + "#" + description.getMethodName(); + assertTestIsValid(testName, mRequiredProperties); + Log.i(TAG, "Running test " + testName + " with required properties: " + + propertiesToString(mRequiredProperties)); + } + + private ArraySet getAllRequiredProperties(Description description) { + final ArraySet allRequiredProperties = new ArraySet<>(); + RequiredProperties requiredProperties = description.getAnnotation(RequiredProperties.class); + if (requiredProperties != null) { + Collections.addAll(allRequiredProperties, requiredProperties.value()); + } + + for (Class clazz = description.getTestClass(); + clazz != null; clazz = clazz.getSuperclass()) { + requiredProperties = clazz.getDeclaredAnnotation(RequiredProperties.class); + if (requiredProperties == null) { + continue; + } + for (Property requiredProperty : requiredProperties.value()) { + if (!allRequiredProperties.contains(~requiredProperty.getValue())) { + allRequiredProperties.add(requiredProperty); + } + } + } + return allRequiredProperties; + } + + private void assertTestIsValid(String testName, ArraySet requiredProperies) { + if (requiredProperies == null) { + return; + } + final ArrayList unsupportedProperties = new ArrayList<>(); + for (Property property : requiredProperies) { + if (!property.isSupported()) { + unsupportedProperties.add(property); + } + } + Assume.assumeTrue("Unsupported properties: " + + propertiesToString(unsupportedProperties), unsupportedProperties.isEmpty()); + } + + public static ArraySet getRequiredProperties() { + return mRequiredProperties; + } + + private static String propertiesToString(Iterable properties) { + return "[" + TextUtils.join(",", properties) + "]"; + } +} diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java index 8d6c4acd7d..1312085478 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java @@ -29,14 +29,14 @@ public class HostsideNetworkCallbackTests extends HostsideNetworkTestCase { uninstallPackage(TEST_APP2_PKG, true); } - public void testOnBlockedStatusChanged_data_saver() throws Exception { + public void testOnBlockedStatusChanged_dataSaver() throws Exception { runDeviceTests(TEST_PKG, - TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_data_saver"); + TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_dataSaver"); } - public void testOnBlockedStatusChanged_power_saver() throws Exception { + public void testOnBlockedStatusChanged_powerSaver() throws Exception { runDeviceTests(TEST_PKG, - TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_power_saver"); + TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_powerSaver"); } } diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java index a2443b391a..ce203795f9 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java @@ -79,7 +79,8 @@ abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiRec protected void installPackage(String apk) throws FileNotFoundException, DeviceNotAvailableException { CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild); - assertNull(getDevice().installPackage(buildHelper.getTestFile(apk), false)); + assertNull(getDevice().installPackage(buildHelper.getTestFile(apk), + false /* reinstall */, true /* grantPermissions */)); } protected void uninstallPackage(String packageName, boolean shouldSucceed) From 9d364b6aeade9e883cf5720914abc66708609de7 Mon Sep 17 00:00:00 2001 From: evitayan Date: Thu, 2 Apr 2020 18:29:00 -0700 Subject: [PATCH 0903/1109] Add CTS for EapSessionConfig Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: I54dedff0555bdfcaae390ddde7b05d24dfabe9b0 --- .../net/eap/cts/EapSessionConfigTest.java | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 tests/cts/net/ipsec/src/android/net/eap/cts/EapSessionConfigTest.java diff --git a/tests/cts/net/ipsec/src/android/net/eap/cts/EapSessionConfigTest.java b/tests/cts/net/ipsec/src/android/net/eap/cts/EapSessionConfigTest.java new file mode 100644 index 0000000000..c24379dae0 --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/eap/cts/EapSessionConfigTest.java @@ -0,0 +1,98 @@ +/* + * 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.eap.cts; + +import static android.telephony.TelephonyManager.APPTYPE_USIM; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import android.net.eap.EapSessionConfig; +import android.net.eap.EapSessionConfig.EapAkaConfig; +import android.net.eap.EapSessionConfig.EapAkaPrimeConfig; +import android.net.eap.EapSessionConfig.EapMsChapV2Config; +import android.net.eap.EapSessionConfig.EapSimConfig; +import android.net.eap.EapSessionConfig.EapUiccConfig; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class EapSessionConfigTest { + // These constants are IANA-defined values and are copies of hidden constants in + // frameworks/opt/net/ike/src/java/com/android/internal/net/eap/message/EapData.java. + private static final int EAP_TYPE_SIM = 18; + private static final int EAP_TYPE_AKA = 23; + private static final int EAP_TYPE_MSCHAP_V2 = 26; + private static final int EAP_TYPE_AKA_PRIME = 50; + + private static final int SUB_ID = 1; + private static final byte[] EAP_IDENTITY = "test@android.net".getBytes(); + private static final String NETWORK_NAME = "android.net"; + private static final String EAP_MSCHAPV2_USERNAME = "username"; + private static final String EAP_MSCHAPV2_PASSWORD = "password"; + + @Test + public void testBuildWithAllEapMethods() { + EapSessionConfig result = + new EapSessionConfig.Builder() + .setEapIdentity(EAP_IDENTITY) + .setEapSimConfig(SUB_ID, APPTYPE_USIM) + .setEapAkaConfig(SUB_ID, APPTYPE_USIM) + .setEapAkaPrimeConfig( + SUB_ID, + APPTYPE_USIM, + NETWORK_NAME, + true /* allowMismatchedNetworkNames */) + .setEapMsChapV2Config(EAP_MSCHAPV2_USERNAME, EAP_MSCHAPV2_PASSWORD) + .build(); + + assertArrayEquals(EAP_IDENTITY, result.getEapIdentity()); + + EapSimConfig eapSimConfig = result.getEapSimConfig(); + assertNotNull(eapSimConfig); + assertEquals(EAP_TYPE_SIM, eapSimConfig.getMethodType()); + verifyEapUiccConfigCommon(eapSimConfig); + + EapAkaConfig eapAkaConfig = result.getEapAkaConfig(); + assertNotNull(eapAkaConfig); + assertEquals(EAP_TYPE_AKA, eapAkaConfig.getMethodType()); + verifyEapUiccConfigCommon(eapAkaConfig); + + EapAkaPrimeConfig eapAkaPrimeConfig = result.getEapAkaPrimeConfig(); + assertNotNull(eapAkaPrimeConfig); + assertEquals(EAP_TYPE_AKA_PRIME, eapAkaPrimeConfig.getMethodType()); + assertEquals(NETWORK_NAME, eapAkaPrimeConfig.getNetworkName()); + assertTrue(NETWORK_NAME, eapAkaPrimeConfig.allowsMismatchedNetworkNames()); + verifyEapUiccConfigCommon(eapAkaPrimeConfig); + + EapMsChapV2Config eapMsChapV2Config = result.getEapMsChapV2onfig(); + assertNotNull(eapMsChapV2Config); + assertEquals(EAP_TYPE_MSCHAP_V2, eapMsChapV2Config.getMethodType()); + assertEquals(EAP_MSCHAPV2_USERNAME, eapMsChapV2Config.getUsername()); + assertEquals(EAP_MSCHAPV2_PASSWORD, eapMsChapV2Config.getPassword()); + } + + private void verifyEapUiccConfigCommon(EapUiccConfig config) { + assertEquals(SUB_ID, config.getSubId()); + assertEquals(APPTYPE_USIM, config.getAppType()); + } +} From 6f203abeab18e0086f451ff65c19c1cec50bbe24 Mon Sep 17 00:00:00 2001 From: paulhu Date: Wed, 22 Apr 2020 10:25:11 +0800 Subject: [PATCH 0904/1109] Add TetheringCommonTests to CtsTetheringTest Bug: 153614365 Bug: 153613717 Test: atest CtsTetheringTest Change-Id: I26c06d522ef2935deb2b1abbd3c5b6be97a48a27 --- tests/cts/tethering/Android.bp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/cts/tethering/Android.bp b/tests/cts/tethering/Android.bp index 63de301d69..37894ec4dc 100644 --- a/tests/cts/tethering/Android.bp +++ b/tests/cts/tethering/Android.bp @@ -25,6 +25,7 @@ android_test { ], static_libs: [ + "TetheringCommonTests", "TetheringIntegrationTestsLib", "compatibility-device-util-axt", "ctstestrunner-axt", From 89099548f8ea46046095ccac1e82c2c88d1d0bee Mon Sep 17 00:00:00 2001 From: Tony Huang Date: Wed, 22 Apr 2020 04:31:43 +0000 Subject: [PATCH 0905/1109] Revert "Pull service dumps to help debug test failures." This reverts commit e3711ae3178ec598430c834efd60f2c43417a5ef. Reason for revert: Might cause build break on errorprone branch Change-Id: Iddece3edf4b1e96fafb8b36282f58410a2476025 --- tests/cts/hostside/AndroidTest.xml | 5 - tests/cts/hostside/app/Android.bp | 2 - tests/cts/hostside/app/AndroidManifest.xml | 3 +- .../net/hostside/AbstractAppIdleTestCase.java | 76 ++-- .../AbstractBatterySaverModeTestCase.java | 68 +++- .../hostside/AbstractDozeModeTestCase.java | 66 +++- ...ractRestrictBackgroundNetworkTestCase.java | 361 ++++++++++++++++-- .../cts/net/hostside/AppIdleMeteredTest.java | 13 +- .../net/hostside/AppIdleNonMeteredTest.java | 7 +- .../hostside/BatterySaverModeMeteredTest.java | 13 +- .../BatterySaverModeNonMeteredTest.java | 9 +- .../cts/net/hostside/DataSaverModeTest.java | 66 ++-- .../cts/net/hostside/DozeModeMeteredTest.java | 13 +- .../net/hostside/DozeModeNonMeteredTest.java | 8 +- .../cts/net/hostside/DumpOnFailureRule.java | 91 ----- .../MeterednessConfigurationRule.java | 60 --- .../cts/net/hostside/MixedModesTest.java | 230 ++++++----- .../cts/net/hostside/NetworkCallbackTest.java | 175 ++++----- .../net/hostside/NetworkPolicyTestUtils.java | 255 ------------- .../android/cts/net/hostside/Property.java | 70 ---- .../cts/net/hostside/RequiredProperties.java | 31 -- .../net/hostside/RequiredPropertiesRule.java | 90 ----- .../cts/net/HostsideNetworkCallbackTests.java | 8 +- .../cts/net/HostsideNetworkTestCase.java | 3 +- 24 files changed, 783 insertions(+), 940 deletions(-) delete mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java delete mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java delete mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java delete mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/Property.java delete mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredProperties.java delete mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java diff --git a/tests/cts/hostside/AndroidTest.xml b/tests/cts/hostside/AndroidTest.xml index 5479c51a4c..dbff1794e9 100644 --- a/tests/cts/hostside/AndroidTest.xml +++ b/tests/cts/hostside/AndroidTest.xml @@ -31,9 +31,4 @@

    By default is empty - it's up to subclasses to override. + */ + protected void setUpMeteredNetwork() throws Exception { + } + + /** + * Resets the (non) metered network state. + * + *

    By default is empty - it's up to subclasses to override. + */ + protected void tearDownMeteredNetwork() throws Exception { } - @Test public void testBackgroundNetworkAccess_enabled() throws Exception { + if (!isSupported()) return; + setBatterySaverMode(true); assertBackgroundNetworkAccess(false); @@ -80,8 +118,9 @@ abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgrou assertBackgroundNetworkAccess(false); } - @Test public void testBackgroundNetworkAccess_whitelisted() throws Exception { + if (!isSupported()) return; + setBatterySaverMode(true); assertBackgroundNetworkAccess(false); @@ -101,8 +140,9 @@ abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgrou assertBackgroundNetworkAccess(false); } - @Test public void testBackgroundNetworkAccess_disabled() throws Exception { + if (!isSupported()) return; + assertBackgroundNetworkAccess(true); assertsForegroundAlwaysHasNetworkAccess(); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java index 6f32c563c1..f20f1d1c4d 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java @@ -16,25 +16,20 @@ package com.android.cts.net.hostside; -import static com.android.cts.net.hostside.Property.DOZE_MODE; -import static com.android.cts.net.hostside.Property.NOT_LOW_RAM_DEVICE; - import android.os.SystemClock; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import android.util.Log; /** * Base class for metered and non-metered Doze Mode tests. */ -@RequiredProperties({DOZE_MODE}) abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetworkTestCase { - @Before - public final void setUp() throws Exception { + @Override + protected final void setUp() throws Exception { super.setUp(); + if (!isSupported()) return; + // Set initial state. removePowerSaveModeWhitelist(TEST_APP2_PKG); removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG); @@ -43,15 +38,48 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor registerBroadcastReceiver(); } - @After - public final void tearDown() throws Exception { + @Override + protected final void tearDown() throws Exception { super.tearDown(); - setDozeMode(false); + if (!isSupported()) return; + + try { + tearDownMeteredNetwork(); + } finally { + setDozeMode(false); + } + } + + @Override + protected boolean isSupported() throws Exception { + boolean supported = isDozeModeEnabled(); + if (!supported) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Doze Mode"); + } + return supported; + } + + /** + * Sets the initial (non) metered network state. + * + *

    By default is empty - it's up to subclasses to override. + */ + protected void setUpMeteredNetwork() throws Exception { + } + + /** + * Resets the (non) metered network state. + * + *

    By default is empty - it's up to subclasses to override. + */ + protected void tearDownMeteredNetwork() throws Exception { } - @Test public void testBackgroundNetworkAccess_enabled() throws Exception { + if (!isSupported()) return; + setDozeMode(true); assertBackgroundNetworkAccess(false); @@ -68,8 +96,9 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor assertBackgroundNetworkAccess(false); } - @Test public void testBackgroundNetworkAccess_whitelisted() throws Exception { + if (!isSupported()) return; + setDozeMode(true); assertBackgroundNetworkAccess(false); @@ -89,18 +118,19 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor assertBackgroundNetworkAccess(false); } - @Test public void testBackgroundNetworkAccess_disabled() throws Exception { + if (!isSupported()) return; + assertBackgroundNetworkAccess(true); assertsForegroundAlwaysHasNetworkAccess(); assertBackgroundNetworkAccess(true); } - @RequiredProperties({NOT_LOW_RAM_DEVICE}) - @Test public void testBackgroundNetworkAccess_enabledButWhitelistedOnNotificationAction() throws Exception { + if (!isSupported() || isLowRamDevice()) return; + setPendingIntentWhitelistDuration(NETWORK_TIMEOUT_MS); try { registerNotificationListenerService(); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 57b7bb4f8d..40d7e34fcc 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -17,22 +17,14 @@ package com.android.cts.net.hostside; import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; +import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; +import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; +import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; import static android.os.BatteryManager.BATTERY_PLUGGED_AC; import static android.os.BatteryManager.BATTERY_PLUGGED_USB; import static android.os.BatteryManager.BATTERY_PLUGGED_WIRELESS; -import static com.android.cts.net.hostside.NetworkPolicyTestUtils.executeShellCommand; -import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getConnectivityManager; -import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getContext; -import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getInstrumentation; -import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getWifiManager; -import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isDozeModeSupported; -import static com.android.cts.net.hostside.NetworkPolicyTestUtils.restrictBackgroundValueToString; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static com.android.compatibility.common.util.SystemUtil.runShellCommand; import android.app.ActivityManager; import android.app.Instrumentation; @@ -42,7 +34,9 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.PackageManager; import android.net.ConnectivityManager; +import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; import android.net.wifi.WifiManager; @@ -50,27 +44,24 @@ import android.os.BatteryManager; import android.os.Binder; import android.os.Bundle; import android.os.SystemClock; +import android.os.SystemProperties; import android.provider.Settings; import android.service.notification.NotificationListenerService; +import android.test.InstrumentationTestCase; +import android.text.TextUtils; import android.util.Log; -import org.junit.Rule; -import org.junit.rules.RuleChain; -import org.junit.runner.RunWith; +import com.android.compatibility.common.util.BatteryUtils; import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import androidx.test.platform.app.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; - /** * Superclass for tests related to background network restrictions. */ -@RunWith(AndroidJUnit4.class) -public abstract class AbstractRestrictBackgroundNetworkTestCase { - public static final String TAG = "RestrictBackgroundNetworkTests"; +abstract class AbstractRestrictBackgroundNetworkTestCase extends InstrumentationTestCase { + protected static final String TAG = "RestrictBackgroundNetworkTests"; protected static final String TEST_PKG = "com.android.cts.net.hostside"; protected static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2"; @@ -107,6 +98,8 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase { static final int NETWORK_TIMEOUT_MS = 15 * SECOND_IN_MS; private static int PROCESS_STATE_FOREGROUND_SERVICE; + private static final int PROCESS_STATE_TOP = 2; + private static final String KEY_NETWORK_STATE_OBSERVER = TEST_PKG + ".observer"; protected static final int TYPE_COMPONENT_ACTIVTIY = 0; @@ -133,23 +126,22 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase { protected WifiManager mWfm; protected int mUid; private int mMyUid; + private String mMeteredWifi; private MyServiceClient mServiceClient; private String mDeviceIdleConstantsSetting; + private boolean mSupported; private boolean mIsLocationOn; - @Rule - public final RuleChain mRuleChain = RuleChain.outerRule(new DumpOnFailureRule()) - .around(new RequiredPropertiesRule()) - .around(new MeterednessConfigurationRule()); - + @Override protected void setUp() throws Exception { + super.setUp(); PROCESS_STATE_FOREGROUND_SERVICE = (Integer) ActivityManager.class .getDeclaredField("PROCESS_STATE_FOREGROUND_SERVICE").get(null); mInstrumentation = getInstrumentation(); - mContext = getContext(); - mCm = getConnectivityManager(); - mWfm = getWifiManager(); + mContext = mInstrumentation.getContext(); + mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); + mWfm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); mUid = getUid(TEST_APP2_PKG); mMyUid = getUid(mContext.getPackageName()); mServiceClient = new MyServiceClient(mContext); @@ -159,9 +151,10 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase { if (!mIsLocationOn) { enableLocation(); } + mSupported = setUpActiveNetworkMeteringState(); setAppIdle(false); - Log.i(TAG, "Apps status:\n" + Log.i(TAG, "Apps status on " + getName() + ":\n" + "\ttest app: uid=" + mMyUid + ", state=" + getProcessStateByUid(mMyUid) + "\n" + "\tapp2: uid=" + mUid + ", state=" + getProcessStateByUid(mUid)); @@ -172,13 +165,16 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase { final String currentConstants = executeShellCommand("settings get global app_idle_constants"); assertEquals(appIdleConstants, currentConstants); - } + } + @Override protected void tearDown() throws Exception { if (!mIsLocationOn) { disableLocation(); } mServiceClient.unbind(); + + super.tearDown(); } private void enableLocation() throws Exception { @@ -263,8 +259,23 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase { protected void assertRestrictBackgroundStatus(int expectedStatus) throws Exception { final String status = mServiceClient.getRestrictBackgroundStatus(); assertNotNull("didn't get API status from app2", status); - assertEquals(restrictBackgroundValueToString(expectedStatus), - restrictBackgroundValueToString(Integer.parseInt(status))); + final String actualStatus = toString(Integer.parseInt(status)); + assertEquals("wrong status", toString(expectedStatus), actualStatus); + } + + protected void assertMyRestrictBackgroundStatus(int expectedStatus) throws Exception { + final int actualStatus = mCm.getRestrictBackgroundStatus(); + assertEquals("Wrong status", toString(expectedStatus), toString(actualStatus)); + } + + protected boolean isMyRestrictBackgroundStatus(int expectedStatus) throws Exception { + final int actualStatus = mCm.getRestrictBackgroundStatus(); + if (expectedStatus != actualStatus) { + Log.d(TAG, "Expected: " + toString(expectedStatus) + + " but actual: " + toString(actualStatus)); + return false; + } + return true; } protected void assertBackgroundNetworkAccess(boolean expectAllowed) throws Exception { @@ -286,6 +297,28 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase { assertNetworkAccess(true /* expectAvailable */, false /* needScreenOn */); } + /** + * Whether this device suport this type of test. + * + *

    Should be overridden when necessary (but always calling + * {@code super.isSupported()} first), and explicitly used before each test + * Example: + * + *

    
    +     * public void testSomething() {
    +     *    if (!isSupported()) return;
    +     * 
    + * + * @return {@code true} by default. + */ + protected boolean isSupported() throws Exception { + return mSupported; + } + + protected boolean isBatterySaverSupported() { + return BatteryUtils.isBatterySaverSupported(); + } + /** * Asserts that an app always have access while on foreground or running a foreground service. * @@ -354,6 +387,23 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase { fail("App2 is not on foreground service state after " + maxTries + " attempts: " + state ); } + /** + * As per CDD requirements, if the device doesn't support data saver mode then + * ConnectivityManager.getRestrictBackgroundStatus() will always return + * RESTRICT_BACKGROUND_STATUS_DISABLED. So, enable the data saver mode and check if + * ConnectivityManager.getRestrictBackgroundStatus() for an app in background returns + * RESTRICT_BACKGROUND_STATUS_DISABLED or not. + */ + protected boolean isDataSaverSupported() throws Exception { + assertMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + try { + setRestrictBackground(true); + return !isMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + } finally { + setRestrictBackground(false); + } + } + /** * Returns whether an app state should be considered "background" for restriction purposes. */ @@ -393,10 +443,40 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase { // Exponential back-off. timeoutMs = Math.min(timeoutMs*2, NETWORK_TIMEOUT_MS); } + dumpOnFailure(); fail("Invalid state for expectAvailable=" + expectAvailable + " after " + maxTries + " attempts.\nLast error: " + error); } + private void dumpOnFailure() throws Exception { + dumpAllNetworkRules(); + Log.d(TAG, "Usagestats dump: " + getUsageStatsDump()); + executeShellCommand("settings get global app_idle_constants"); + } + + private void dumpAllNetworkRules() throws Exception { + final String networkManagementDump = runShellCommand(mInstrumentation, + "dumpsys network_management").trim(); + final String networkPolicyDump = runShellCommand(mInstrumentation, + "dumpsys netpolicy").trim(); + TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter('\n'); + splitter.setString(networkManagementDump); + String next; + Log.d(TAG, ">>> Begin network_management dump"); + while (splitter.hasNext()) { + next = splitter.next(); + Log.d(TAG, next); + } + Log.d(TAG, "<<< End network_management dump"); + splitter.setString(networkPolicyDump); + Log.d(TAG, ">>> Begin netpolicy dump"); + while (splitter.hasNext()) { + next = splitter.next(); + Log.d(TAG, next); + } + Log.d(TAG, "<<< End netpolicy dump"); + } + /** * Checks whether the network is available as expected. * @@ -448,10 +528,22 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase { return errors.toString(); } + protected boolean isLowRamDevice() { + final ActivityManager am = (ActivityManager) mContext.getSystemService( + Context.ACTIVITY_SERVICE); + return am.isLowRamDevice(); + } + + protected String executeShellCommand(String command) throws Exception { + final String result = runShellCommand(mInstrumentation, command).trim(); + if (DEBUG) Log.d(TAG, "Command '" + command + "' returned '" + result + "'"); + return result; + } + /** * Runs a Shell command which is not expected to generate output. */ - protected void executeSilentShellCommand(String command) { + protected void executeSilentShellCommand(String command) throws Exception { final String result = executeShellCommand(command); assertTrue("Command '" + command + "' failed: " + result, result.trim().isEmpty()); } @@ -480,6 +572,10 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase { }); } + protected void assertDelayedShellCommand(String command, ExpectResultChecker checker) + throws Exception { + assertDelayedShellCommand(command, 5, 1, checker); + } protected void assertDelayedShellCommand(String command, int maxTries, int napTimeSeconds, ExpectResultChecker checker) throws Exception { String result = ""; @@ -496,6 +592,159 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase { + " attempts. Last result: '" + result + "'"); } + /** + * Sets the initial metering state for the active network. + * + *

    It's called on setup and by default does nothing - it's up to the + * subclasses to override. + * + * @return whether the tests in the subclass are supported on this device. + */ + protected boolean setUpActiveNetworkMeteringState() throws Exception { + return true; + } + + /** + * Makes sure the active network is not metered. + * + *

    If the device does not supoprt un-metered networks (for example if it + * only has cellular data but not wi-fi), it should return {@code false}; + * otherwise, it should return {@code true} (or fail if the un-metered + * network could not be set). + * + * @return {@code true} if the network is now unmetered. + */ + protected boolean setUnmeteredNetwork() throws Exception { + final NetworkInfo info = mCm.getActiveNetworkInfo(); + assertNotNull("Could not get active network", info); + if (!mCm.isActiveNetworkMetered()) { + Log.d(TAG, "Active network is not metered: " + info); + } else if (info.getType() == ConnectivityManager.TYPE_WIFI) { + Log.i(TAG, "Setting active WI-FI network as not metered: " + info ); + setWifiMeteredStatus(false); + } else { + Log.d(TAG, "Active network cannot be set to un-metered: " + info); + return false; + } + assertActiveNetworkMetered(false); // Sanity check. + return true; + } + + /** + * Enables metering on the active network if supported. + * + *

    If the device does not support metered networks it should return + * {@code false}; otherwise, it should return {@code true} (or fail if the + * metered network could not be set). + * + * @return {@code true} if the network is now metered. + */ + protected boolean setMeteredNetwork() throws Exception { + final NetworkInfo info = mCm.getActiveNetworkInfo(); + final boolean metered = mCm.isActiveNetworkMetered(); + if (metered) { + Log.d(TAG, "Active network already metered: " + info); + return true; + } else if (info.getType() != ConnectivityManager.TYPE_WIFI) { + Log.w(TAG, "Active network does not support metering: " + info); + return false; + } else { + Log.w(TAG, "Active network not metered: " + info); + } + final String netId = setWifiMeteredStatus(true); + + // Set flag so status is reverted on resetMeteredNetwork(); + mMeteredWifi = netId; + // Sanity check. + assertWifiMeteredStatus(netId, true); + assertActiveNetworkMetered(true); + return true; + } + + /** + * Resets the device metering state to what it was before the test started. + * + *

    This reverts any metering changes made by {@code setMeteredNetwork}. + */ + protected void resetMeteredNetwork() throws Exception { + if (mMeteredWifi != null) { + Log.i(TAG, "resetMeteredNetwork(): SID '" + mMeteredWifi + + "' was set as metered by test case; resetting it"); + setWifiMeteredStatus(mMeteredWifi, false); + assertActiveNetworkMetered(false); // Sanity check. + } + } + + private void assertActiveNetworkMetered(boolean expected) throws Exception { + final int maxTries = 5; + NetworkInfo info = null; + for (int i = 1; i <= maxTries; i++) { + info = mCm.getActiveNetworkInfo(); + if (info == null) { + Log.v(TAG, "No active network info on attempt #" + i + + "; sleeping 1s before polling again"); + } else if (mCm.isActiveNetworkMetered() != expected) { + Log.v(TAG, "Wrong metered status for active network " + info + "; expected=" + + expected + "; sleeping 1s before polling again"); + } else { + break; + } + Thread.sleep(SECOND_IN_MS); + } + assertNotNull("No active network after " + maxTries + " attempts", info); + assertEquals("Wrong metered status for active network " + info, expected, + mCm.isActiveNetworkMetered()); + } + + private String setWifiMeteredStatus(boolean metered) throws Exception { + // We could call setWifiEnabled() here, but it might take sometime to be in a consistent + // state (for example, if one of the saved network is not properly authenticated), so it's + // better to let the hostside test take care of that. + assertTrue("wi-fi is disabled", mWfm.isWifiEnabled()); + // TODO: if it's not guaranteed the device has wi-fi, we need to change the tests + // to make the actual verification of restrictions optional. + final String ssid = mWfm.getConnectionInfo().getSSID(); + return setWifiMeteredStatus(ssid, metered); + } + + private String setWifiMeteredStatus(String ssid, boolean metered) throws Exception { + assertNotNull("null SSID", ssid); + final String netId = ssid.trim().replaceAll("\"", ""); // remove quotes, if any. + assertFalse("empty SSID", ssid.isEmpty()); + + Log.i(TAG, "Setting wi-fi network " + netId + " metered status to " + metered); + final String setCommand = "cmd netpolicy set metered-network " + netId + " " + metered; + assertDelayedShellCommand(setCommand, ""); + + return netId; + } + + private void assertWifiMeteredStatus(String netId, boolean status) throws Exception { + final String command = "cmd netpolicy list wifi-networks"; + final String expectedLine = netId + ";" + status; + assertDelayedShellCommand(command, new ExpectResultChecker() { + + @Override + public boolean isExpected(String result) { + return result.contains(expectedLine); + } + + @Override + public String getExpected() { + return "line containing " + expectedLine; + } + }); + } + + protected void setRestrictBackground(boolean enabled) throws Exception { + executeShellCommand("cmd netpolicy set restrict-background " + enabled); + final String output = executeShellCommand("cmd netpolicy get restrict-background "); + final String expectedSuffix = enabled ? "enabled" : "disabled"; + // TODO: use MoreAsserts? + assertTrue("output '" + output + "' should end with '" + expectedSuffix + "'", + output.endsWith(expectedSuffix)); + } + protected void addRestrictBackgroundWhitelist(int uid) throws Exception { executeShellCommand("cmd netpolicy add restrict-background-whitelist " + uid); assertRestrictBackgroundWhitelist(uid, true); @@ -675,7 +924,7 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase { protected void setDozeMode(boolean enabled) throws Exception { // Sanity check, since tests should check beforehand.... - assertTrue("Device does not support Doze Mode", isDozeModeSupported()); + assertTrue("Device does not support Doze Mode", isDozeModeEnabled()); Log.i(TAG, "Setting Doze Mode to " + enabled); if (enabled) { @@ -695,16 +944,43 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase { assertDelayedShellCommand("dumpsys deviceidle get deep", enabled ? "IDLE" : "ACTIVE"); } + protected boolean isDozeModeEnabled() throws Exception { + final String result = executeShellCommand("cmd deviceidle enabled deep").trim(); + return result.equals("1"); + } + protected void setAppIdle(boolean enabled) throws Exception { Log.i(TAG, "Setting app idle to " + enabled); executeSilentShellCommand("am set-inactive " + TEST_APP2_PKG + " " + enabled ); assertAppIdle(enabled); // Sanity check } + private String getUsageStatsDump() throws Exception { + final String output = runShellCommand(mInstrumentation, "dumpsys usagestats").trim(); + final StringBuilder sb = new StringBuilder(); + final TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter('\n'); + splitter.setString(output); + String str; + while (splitter.hasNext()) { + str = splitter.next(); + if (str.contains("package=") + && !str.contains(TEST_PKG) && !str.contains(TEST_APP2_PKG)) { + continue; + } + if (str.trim().startsWith("config=") || str.trim().startsWith("time=")) { + continue; + } + sb.append(str).append('\n'); + } + return sb.toString(); + } + protected void assertAppIdle(boolean enabled) throws Exception { try { assertDelayedShellCommand("am get-inactive " + TEST_APP2_PKG, 15, 2, "Idle=" + enabled); } catch (Throwable e) { + Log.d(TAG, "UsageStats dump:\n" + getUsageStatsDump()); + executeShellCommand("settings get global app_idle_constants"); throw e; } } @@ -785,10 +1061,12 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase { // App didn't come to foreground when the activity is started, so try again. assertForegroundNetworkAccess(); } else { + dumpOnFailure(); fail("Network is not available for app2 (" + mUid + "): " + errors[0]); } } } else { + dumpOnFailure(); fail("Timed out waiting for network availability status from app2 (" + mUid + ")"); } } else { @@ -872,6 +1150,19 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase { } } + private String toString(int status) { + switch (status) { + case RESTRICT_BACKGROUND_STATUS_DISABLED: + return "DISABLED"; + case RESTRICT_BACKGROUND_STATUS_WHITELISTED: + return "WHITELISTED"; + case RESTRICT_BACKGROUND_STATUS_ENABLED: + return "ENABLED"; + default: + return "UNKNOWN_STATUS_" + status; + } + } + private ProcessState getProcessStateByUid(int uid) throws Exception { return new ProcessState(executeShellCommand("cmd activity get-uid-state " + uid)); } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java index f1858d65a5..622d99361f 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java @@ -16,8 +16,15 @@ package com.android.cts.net.hostside; -import static com.android.cts.net.hostside.Property.METERED_NETWORK; - -@RequiredProperties({METERED_NETWORK}) public class AppIdleMeteredTest extends AbstractAppIdleTestCase { + + @Override + protected boolean setUpActiveNetworkMeteringState() throws Exception { + return setMeteredNetwork(); + } + + @Override + protected void tearDownMeteredNetwork() throws Exception { + resetMeteredNetwork(); + } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java index e737a6dabe..bde71f9100 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java @@ -16,8 +16,9 @@ package com.android.cts.net.hostside; -import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; - -@RequiredProperties({NON_METERED_NETWORK}) public class AppIdleNonMeteredTest extends AbstractAppIdleTestCase { + @Override + protected boolean setUpActiveNetworkMeteringState() throws Exception { + return setUnmeteredNetwork(); + } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java index c78ca2ec77..3071cfe3f1 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java @@ -16,8 +16,15 @@ package com.android.cts.net.hostside; -import static com.android.cts.net.hostside.Property.METERED_NETWORK; - -@RequiredProperties({METERED_NETWORK}) public class BatterySaverModeMeteredTest extends AbstractBatterySaverModeTestCase { + + @Override + protected boolean setUpActiveNetworkMeteringState() throws Exception { + return setMeteredNetwork(); + } + + @Override + protected void tearDownMeteredNetwork() throws Exception { + resetMeteredNetwork(); + } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java index fb52a540d8..6d3076fe0e 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java @@ -16,9 +16,10 @@ package com.android.cts.net.hostside; - -import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; - -@RequiredProperties({NON_METERED_NETWORK}) public class BatterySaverModeNonMeteredTest extends AbstractBatterySaverModeTestCase { + + @Override + protected boolean setUpActiveNetworkMeteringState() throws Exception { + return setUnmeteredNetwork(); + } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index aa2c914e02..cfe6a73a0f 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -20,33 +20,24 @@ import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLE import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; -import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground; -import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE; -import static com.android.cts.net.hostside.Property.METERED_NETWORK; -import static com.android.cts.net.hostside.Property.NO_DATA_SAVER_MODE; - -import static org.junit.Assert.fail; +import android.util.Log; import com.android.compatibility.common.util.CddTest; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import androidx.test.filters.LargeTest; - -@RequiredProperties({DATA_SAVER_MODE, METERED_NETWORK}) -@LargeTest public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase { private static final String[] REQUIRED_WHITELISTED_PACKAGES = { "com.android.providers.downloads" }; - @Before + private boolean mIsDataSaverSupported; + + @Override public void setUp() throws Exception { super.setUp(); + mIsDataSaverSupported = isDataSaverSupported(); + // Set initial state. setRestrictBackground(false); removeRestrictBackgroundWhitelist(mUid); @@ -56,15 +47,36 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertRestrictBackgroundChangedReceived(0); } - @After - public void tearDown() throws Exception { + @Override + protected void tearDown() throws Exception { super.tearDown(); - setRestrictBackground(false); + if (!isSupported()) return; + + try { + resetMeteredNetwork(); + } finally { + setRestrictBackground(false); + } + } + + @Override + protected boolean setUpActiveNetworkMeteringState() throws Exception { + return setMeteredNetwork(); + } + + @Override + protected boolean isSupported() throws Exception { + if (!mIsDataSaverSupported) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Data Saver Mode"); + } + return mIsDataSaverSupported && super.isSupported(); } - @Test public void testGetRestrictBackgroundStatus_disabled() throws Exception { + if (!isSupported()) return; + assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED); // Sanity check: make sure status is always disabled, never whitelisted @@ -76,8 +88,9 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED); } - @Test public void testGetRestrictBackgroundStatus_whitelisted() throws Exception { + if (!isSupported()) return; + setRestrictBackground(true); assertRestrictBackgroundChangedReceived(1); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); @@ -94,8 +107,9 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); } - @Test public void testGetRestrictBackgroundStatus_enabled() throws Exception { + if (!isSupported()) return; + setRestrictBackground(true); assertRestrictBackgroundChangedReceived(1); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); @@ -128,8 +142,9 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertBackgroundNetworkAccess(false); } - @Test public void testGetRestrictBackgroundStatus_blacklisted() throws Exception { + if (!isSupported()) return; + addRestrictBackgroundBlacklist(mUid); assertRestrictBackgroundChangedReceived(1); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); @@ -165,8 +180,9 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertsForegroundAlwaysHasNetworkAccess(); } - @Test public void testGetRestrictBackgroundStatus_requiredWhitelistedPackages() throws Exception { + if (!isSupported()) return; + final StringBuilder error = new StringBuilder(); for (String packageName : REQUIRED_WHITELISTED_PACKAGES) { int uid = -1; @@ -186,10 +202,10 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase } } - @RequiredProperties({NO_DATA_SAVER_MODE}) @CddTest(requirement="7.4.7/C-2-2") - @Test public void testBroadcastNotSentOnUnsupportedDevices() throws Exception { + if (isSupported()) return; + setRestrictBackground(true); assertRestrictBackgroundChangedReceived(0); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java index 4306c991c2..e4189af587 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java @@ -16,8 +16,15 @@ package com.android.cts.net.hostside; -import static com.android.cts.net.hostside.Property.METERED_NETWORK; - -@RequiredProperties({METERED_NETWORK}) public class DozeModeMeteredTest extends AbstractDozeModeTestCase { + + @Override + protected boolean setUpActiveNetworkMeteringState() throws Exception { + return setMeteredNetwork(); + } + + @Override + protected void tearDownMeteredNetwork() throws Exception { + resetMeteredNetwork(); + } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java index 1e89f158a3..edbbb9e1ce 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java @@ -16,8 +16,10 @@ package com.android.cts.net.hostside; -import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; - -@RequiredProperties({NON_METERED_NETWORK}) public class DozeModeNonMeteredTest extends AbstractDozeModeTestCase { + + @Override + protected boolean setUpActiveNetworkMeteringState() throws Exception { + return setUnmeteredNetwork(); + } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java deleted file mode 100644 index cedd62a0bc..0000000000 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2019 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.cts.net.hostside; - -import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TAG; -import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TEST_PKG; - -import android.os.Environment; -import android.os.FileUtils; -import android.os.ParcelFileDescriptor; -import android.util.Log; - -import com.android.compatibility.common.util.OnFailureRule; - -import org.junit.AssumptionViolatedException; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -import androidx.test.platform.app.InstrumentationRegistry; - -public class DumpOnFailureRule extends OnFailureRule { - private File mDumpDir = new File(Environment.getExternalStorageDirectory(), - "CtsHostsideNetworkTests"); - - @Override - public void onTestFailure(Statement base, Description description, Throwable throwable) { - final String testName = description.getClassName() + "_" + description.getMethodName(); - - if (throwable instanceof AssumptionViolatedException) { - Log.d(TAG, "Skipping test " + testName + ": " + throwable); - return; - } - - prepareDumpRootDir(); - final File dumpFile = new File(mDumpDir, "dump-" + testName); - Log.i(TAG, "Dumping debug info for " + description + ": " + dumpFile.getPath()); - try (FileOutputStream out = new FileOutputStream(dumpFile)) { - for (String cmd : new String[] { - "dumpsys netpolicy", - "dumpsys network_management", - "dumpsys usagestats " + TEST_PKG, - "dumpsys usagestats appstandby", - }) { - dumpCommandOutput(out, cmd); - } - } catch (FileNotFoundException e) { - Log.e(TAG, "Error opening file: " + dumpFile, e); - } catch (IOException e) { - Log.e(TAG, "Error closing file: " + dumpFile, e); - } - } - - void dumpCommandOutput(FileOutputStream out, String cmd) { - final ParcelFileDescriptor pfd = InstrumentationRegistry.getInstrumentation() - .getUiAutomation().executeShellCommand(cmd); - try (FileInputStream in = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) { - out.write(("Output of '" + cmd + "':\n").getBytes(StandardCharsets.UTF_8)); - FileUtils.copy(in, out); - out.write("\n\n=================================================================\n\n" - .getBytes(StandardCharsets.UTF_8)); - } catch (IOException e) { - Log.e(TAG, "Error dumping '" + cmd + "'", e); - } - } - - void prepareDumpRootDir() { - if (!mDumpDir.exists() && !mDumpDir.mkdir()) { - Log.e(TAG, "Error creating " + mDumpDir); - } - } -} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java deleted file mode 100644 index 8fadf9e295..0000000000 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2019 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.cts.net.hostside; - -import static com.android.cts.net.hostside.NetworkPolicyTestUtils.resetMeteredNetwork; -import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setupMeteredNetwork; -import static com.android.cts.net.hostside.Property.METERED_NETWORK; -import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; - -import android.util.ArraySet; -import android.util.Pair; - -import com.android.compatibility.common.util.BeforeAfterRule; - -import org.junit.runner.Description; -import org.junit.runners.model.Statement; - -public class MeterednessConfigurationRule extends BeforeAfterRule { - private Pair mSsidAndInitialMeteredness; - - @Override - public void onBefore(Statement base, Description description) throws Throwable { - final ArraySet requiredProperties - = RequiredPropertiesRule.getRequiredProperties(); - if (requiredProperties.contains(METERED_NETWORK)) { - configureNetworkMeteredness(true); - } else if (requiredProperties.contains(NON_METERED_NETWORK)) { - configureNetworkMeteredness(false); - } - } - - @Override - public void onAfter(Statement base, Description description) throws Throwable { - resetNetworkMeteredness(); - } - - public void configureNetworkMeteredness(boolean metered) throws Exception { - mSsidAndInitialMeteredness = setupMeteredNetwork(metered); - } - - public void resetNetworkMeteredness() throws Exception { - if (mSsidAndInitialMeteredness != null) { - resetMeteredNetwork(mSsidAndInitialMeteredness.first, - mSsidAndInitialMeteredness.second); - } - } -} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java index c9edda6e0b..b1a21867b3 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java @@ -15,21 +15,9 @@ */ package com.android.cts.net.hostside; -import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground; -import static com.android.cts.net.hostside.Property.APP_STANDBY_MODE; -import static com.android.cts.net.hostside.Property.BATTERY_SAVER_MODE; -import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE; -import static com.android.cts.net.hostside.Property.DOZE_MODE; -import static com.android.cts.net.hostside.Property.METERED_NETWORK; -import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; - import android.os.SystemClock; import android.util.Log; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - /** * Test cases for the more complex scenarios where multiple restrictions (like Battery Saver Mode * and Data Saver Mode) are applied simultaneously. @@ -41,10 +29,12 @@ import org.junit.Test; public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { private static final String TAG = "MixedModesTest"; - @Before + @Override public void setUp() throws Exception { super.setUp(); + if (!isSupported()) return; + // Set initial state. removeRestrictBackgroundWhitelist(mUid); removeRestrictBackgroundBlacklist(mUid); @@ -54,10 +44,12 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { registerBroadcastReceiver(); } - @After - public void tearDown() throws Exception { + @Override + protected void tearDown() throws Exception { super.tearDown(); + if (!isSupported()) return; + try { setRestrictBackground(false); } finally { @@ -65,15 +57,34 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } + @Override + public boolean isSupported() throws Exception { + if (!isDozeModeEnabled()) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Doze Mode"); + return false; + } + return true; + } + /** * Tests all DS ON and BS ON scenarios from network-policy-restrictions.md on metered networks. */ - @RequiredProperties({DATA_SAVER_MODE, BATTERY_SAVER_MODE, METERED_NETWORK}) - @Test public void testDataAndBatterySaverModes_meteredNetwork() throws Exception { - final MeterednessConfigurationRule meterednessConfiguration - = new MeterednessConfigurationRule(); - meterednessConfiguration.configureNetworkMeteredness(true); + if (!isBatterySaverSupported()) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Battery saver mode"); + return; + } + if (!isSupported()) return; + + Log.i(TAG, "testDataAndBatterySaverModes_meteredNetwork() tests"); + if (!setMeteredNetwork()) { + Log.w(TAG, "testDataAndBatterySaverModes_meteredNetwork() skipped because " + + "device cannot use a metered network"); + return; + } + try { setRestrictBackground(true); setBatterySaverMode(true); @@ -126,7 +137,7 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { removeRestrictBackgroundBlacklist(mUid); removePowerSaveModeWhitelist(TEST_APP2_PKG); } finally { - meterednessConfiguration.resetNetworkMeteredness(); + resetMeteredNetwork(); } } @@ -134,75 +145,86 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { * Tests all DS ON and BS ON scenarios from network-policy-restrictions.md on non-metered * networks. */ - @RequiredProperties({DATA_SAVER_MODE, BATTERY_SAVER_MODE, NON_METERED_NETWORK}) - @Test public void testDataAndBatterySaverModes_nonMeteredNetwork() throws Exception { - final MeterednessConfigurationRule meterednessConfiguration - = new MeterednessConfigurationRule(); - meterednessConfiguration.configureNetworkMeteredness(false); - try { - setRestrictBackground(true); - setBatterySaverMode(true); - - Log.v(TAG, "Not whitelisted for any."); - assertBackgroundNetworkAccess(false); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(false); - - Log.v(TAG, "Whitelisted for Data Saver but not for Battery Saver."); - addRestrictBackgroundWhitelist(mUid); - removePowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(false); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(false); - removeRestrictBackgroundWhitelist(mUid); - - Log.v(TAG, "Whitelisted for Battery Saver but not for Data Saver."); - addPowerSaveModeWhitelist(TEST_APP2_PKG); - removeRestrictBackgroundWhitelist(mUid); - assertBackgroundNetworkAccess(true); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(true); - removePowerSaveModeWhitelist(TEST_APP2_PKG); - - Log.v(TAG, "Whitelisted for both."); - addRestrictBackgroundWhitelist(mUid); - addPowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(true); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(true); - removePowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(false); - removeRestrictBackgroundWhitelist(mUid); - - Log.v(TAG, "Blacklisted for Data Saver, not whitelisted for Battery Saver."); - addRestrictBackgroundBlacklist(mUid); - removePowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(false); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(false); - removeRestrictBackgroundBlacklist(mUid); - - Log.v(TAG, "Blacklisted for Data Saver, whitelisted for Battery Saver."); - addRestrictBackgroundBlacklist(mUid); - addPowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(true); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(true); - removeRestrictBackgroundBlacklist(mUid); - removePowerSaveModeWhitelist(TEST_APP2_PKG); - } finally { - meterednessConfiguration.resetNetworkMeteredness(); + if (!isBatterySaverSupported()) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Battery saver mode"); + return; } + if (!isSupported()) return; + + if (!setUnmeteredNetwork()) { + Log.w(TAG, "testDataAndBatterySaverModes_nonMeteredNetwork() skipped because network" + + " is metered"); + return; + } + Log.i(TAG, "testDataAndBatterySaverModes_nonMeteredNetwork() tests"); + setRestrictBackground(true); + setBatterySaverMode(true); + + Log.v(TAG, "Not whitelisted for any."); + assertBackgroundNetworkAccess(false); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + + Log.v(TAG, "Whitelisted for Data Saver but not for Battery Saver."); + addRestrictBackgroundWhitelist(mUid); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + removeRestrictBackgroundWhitelist(mUid); + + Log.v(TAG, "Whitelisted for Battery Saver but not for Data Saver."); + addPowerSaveModeWhitelist(TEST_APP2_PKG); + removeRestrictBackgroundWhitelist(mUid); + assertBackgroundNetworkAccess(true); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(true); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + + Log.v(TAG, "Whitelisted for both."); + addRestrictBackgroundWhitelist(mUid); + addPowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(true); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(true); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + removeRestrictBackgroundWhitelist(mUid); + + Log.v(TAG, "Blacklisted for Data Saver, not whitelisted for Battery Saver."); + addRestrictBackgroundBlacklist(mUid); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + removeRestrictBackgroundBlacklist(mUid); + + Log.v(TAG, "Blacklisted for Data Saver, whitelisted for Battery Saver."); + addRestrictBackgroundBlacklist(mUid); + addPowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(true); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(true); + removeRestrictBackgroundBlacklist(mUid); + removePowerSaveModeWhitelist(TEST_APP2_PKG); } /** * Tests that powersave whitelists works as expected when doze and battery saver modes * are enabled. */ - @RequiredProperties({DOZE_MODE, BATTERY_SAVER_MODE}) - @Test public void testDozeAndBatterySaverMode_powerSaveWhitelists() throws Exception { + if (!isBatterySaverSupported()) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Battery saver mode"); + return; + } + if (!isSupported()) { + return; + } + setBatterySaverMode(true); setDozeMode(true); @@ -228,9 +250,11 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { * Tests that powersave whitelists works as expected when doze and appIdle modes * are enabled. */ - @RequiredProperties({DOZE_MODE, APP_STANDBY_MODE}) - @Test public void testDozeAndAppIdle_powerSaveWhitelists() throws Exception { + if (!isSupported()) { + return; + } + setDozeMode(true); setAppIdle(true); @@ -252,9 +276,11 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } - @RequiredProperties({APP_STANDBY_MODE, DOZE_MODE}) - @Test public void testAppIdleAndDoze_tempPowerSaveWhitelists() throws Exception { + if (!isSupported()) { + return; + } + setDozeMode(true); setAppIdle(true); @@ -273,9 +299,16 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } - @RequiredProperties({APP_STANDBY_MODE, BATTERY_SAVER_MODE}) - @Test public void testAppIdleAndBatterySaver_tempPowerSaveWhitelists() throws Exception { + if (!isBatterySaverSupported()) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Battery saver mode"); + return; + } + if (!isSupported()) { + return; + } + setBatterySaverMode(true); setAppIdle(true); @@ -297,9 +330,11 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { /** * Tests that the app idle whitelist works as expected when doze and appIdle mode are enabled. */ - @RequiredProperties({DOZE_MODE, APP_STANDBY_MODE}) - @Test public void testDozeAndAppIdle_appIdleWhitelist() throws Exception { + if (!isSupported()) { + return; + } + setDozeMode(true); setAppIdle(true); @@ -318,9 +353,11 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } - @RequiredProperties({APP_STANDBY_MODE, DOZE_MODE}) - @Test public void testAppIdleAndDoze_tempPowerSaveAndAppIdleWhitelists() throws Exception { + if (!isSupported()) { + return; + } + setDozeMode(true); setAppIdle(true); @@ -343,9 +380,16 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } - @RequiredProperties({APP_STANDBY_MODE, BATTERY_SAVER_MODE}) - @Test public void testAppIdleAndBatterySaver_tempPowerSaveAndAppIdleWhitelists() throws Exception { + if (!isBatterySaverSupported()) { + Log.i(TAG, "Skipping " + getClass() + "." + getName() + + "() because device does not support Battery saver mode"); + return; + } + if (!isSupported()) { + return; + } + setBatterySaverMode(true); setAppIdle(true); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java index ed397b91fc..24dde9d356 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java @@ -16,26 +16,15 @@ package com.android.cts.net.hostside; -import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground; -import static com.android.cts.net.hostside.Property.BATTERY_SAVER_MODE; -import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.fail; - import android.net.Network; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - import java.util.Objects; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCase { + private boolean mIsDataSaverSupported; private Network mNetwork; private final TestNetworkCallback mTestNetworkCallback = new TestNetworkCallback(); @@ -143,122 +132,108 @@ public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCa } } - @Before + @Override public void setUp() throws Exception { super.setUp(); + mIsDataSaverSupported = isDataSaverSupported(); + mNetwork = mCm.getActiveNetwork(); + // Set initial state. + setBatterySaverMode(false); registerBroadcastReceiver(); + if (!mIsDataSaverSupported) return; + setRestrictBackground(false); removeRestrictBackgroundWhitelist(mUid); removeRestrictBackgroundBlacklist(mUid); assertRestrictBackgroundChangedReceived(0); } - @After - public void tearDown() throws Exception { + @Override + protected void tearDown() throws Exception { super.tearDown(); - setRestrictBackground(false); - setBatterySaverMode(false); - } + if (!mIsDataSaverSupported) return; - @RequiredProperties({DATA_SAVER_MODE}) - @Test - public void testOnBlockedStatusChanged_dataSaver() throws Exception { - // Initial state - setBatterySaverMode(false); - setRestrictBackground(false); - - final MeterednessConfigurationRule meterednessConfiguration - = new MeterednessConfigurationRule(); - meterednessConfiguration.configureNetworkMeteredness(true); try { - // Register callback - registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); - mTestNetworkCallback.expectAvailableCallback(mNetwork); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - - // Enable restrict background - setRestrictBackground(true); - assertBackgroundNetworkAccess(false); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); - - // Add to whitelist - addRestrictBackgroundWhitelist(mUid); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - - // Remove from whitelist - removeRestrictBackgroundWhitelist(mUid); - assertBackgroundNetworkAccess(false); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); + resetMeteredNetwork(); } finally { - meterednessConfiguration.resetNetworkMeteredness(); - } - - // Set to non-metered network - meterednessConfiguration.configureNetworkMeteredness(false); - try { - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - - // Disable restrict background, should not trigger callback setRestrictBackground(false); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.assertNoCallback(); - } finally { - meterednessConfiguration.resetNetworkMeteredness(); } } - @RequiredProperties({BATTERY_SAVER_MODE}) - @Test - public void testOnBlockedStatusChanged_powerSaver() throws Exception { - // Set initial state. - setBatterySaverMode(false); - setRestrictBackground(false); + public void testOnBlockedStatusChanged_data_saver() throws Exception { + if (!mIsDataSaverSupported) return; - final MeterednessConfigurationRule meterednessConfiguration - = new MeterednessConfigurationRule(); - meterednessConfiguration.configureNetworkMeteredness(true); - try { - // Register callback - registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); - mTestNetworkCallback.expectAvailableCallback(mNetwork); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + // Prepare metered wifi + if (!setMeteredNetwork()) return; - // Enable Power Saver - setBatterySaverMode(true); - assertBackgroundNetworkAccess(false); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); + // Register callback + registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); + mTestNetworkCallback.expectAvailableCallback(mNetwork); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - // Disable Power Saver - setBatterySaverMode(false); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - } finally { - meterednessConfiguration.resetNetworkMeteredness(); - } + // Enable restrict background + setRestrictBackground(true); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); + + // Add to whitelist + addRestrictBackgroundWhitelist(mUid); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Remove from whitelist + removeRestrictBackgroundWhitelist(mUid); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); // Set to non-metered network - meterednessConfiguration.configureNetworkMeteredness(false); - try { - mTestNetworkCallback.assertNoCallback(); + setUnmeteredNetwork(); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - // Enable Power Saver - setBatterySaverMode(true); - assertBackgroundNetworkAccess(false); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); + // Disable restrict background, should not trigger callback + setRestrictBackground(false); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.assertNoCallback(); + } - // Disable Power Saver - setBatterySaverMode(false); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - } finally { - meterednessConfiguration.resetNetworkMeteredness(); - } + + public void testOnBlockedStatusChanged_power_saver() throws Exception { + // Prepare metered wifi + if (!setMeteredNetwork()) return; + + // Register callback + registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); + mTestNetworkCallback.expectAvailableCallback(mNetwork); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Enable Power Saver + setBatterySaverMode(true); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); + + // Disable Power Saver + setBatterySaverMode(false); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Set to non-metered network + setUnmeteredNetwork(); + mTestNetworkCallback.assertNoCallback(); + + // Enable Power Saver + setBatterySaverMode(true); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); + + // Disable Power Saver + setBatterySaverMode(false); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); } // TODO: 1. test against VPN lockdown. diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java deleted file mode 100644 index ca2864c0b8..0000000000 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (C) 2019 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.cts.net.hostside; - -import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; -import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; -import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; -import static android.net.NetworkCapabilities.TRANSPORT_WIFI; - -import static com.android.compatibility.common.util.SystemUtil.runShellCommand; -import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TAG; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import android.app.ActivityManager; -import android.app.Instrumentation; -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.ConnectivityManager.NetworkCallback; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.wifi.WifiManager; -import android.text.TextUtils; -import android.util.Log; -import android.util.Pair; - -import com.android.compatibility.common.util.AppStandbyUtils; -import com.android.compatibility.common.util.BatteryUtils; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -import androidx.test.platform.app.InstrumentationRegistry; - -public class NetworkPolicyTestUtils { - - private static final int TIMEOUT_CHANGE_METEREDNESS_MS = 5000; - - private static ConnectivityManager mCm; - private static WifiManager mWm; - - private static Boolean mBatterySaverSupported; - private static Boolean mDataSaverSupported; - private static Boolean mDozeModeSupported; - private static Boolean mAppStandbySupported; - - private NetworkPolicyTestUtils() {} - - public static boolean isBatterySaverSupported() { - if (mBatterySaverSupported == null) { - mBatterySaverSupported = BatteryUtils.isBatterySaverSupported(); - } - return mBatterySaverSupported; - } - - /** - * As per CDD requirements, if the device doesn't support data saver mode then - * ConnectivityManager.getRestrictBackgroundStatus() will always return - * RESTRICT_BACKGROUND_STATUS_DISABLED. So, enable the data saver mode and check if - * ConnectivityManager.getRestrictBackgroundStatus() for an app in background returns - * RESTRICT_BACKGROUND_STATUS_DISABLED or not. - */ - public static boolean isDataSaverSupported() { - if (mDataSaverSupported == null) { - assertMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); - try { - setRestrictBackground(true); - mDataSaverSupported = !isMyRestrictBackgroundStatus( - RESTRICT_BACKGROUND_STATUS_DISABLED); - } finally { - setRestrictBackground(false); - } - } - return mDataSaverSupported; - } - - public static boolean isDozeModeSupported() { - if (mDozeModeSupported == null) { - final String result = executeShellCommand("cmd deviceidle enabled deep"); - mDozeModeSupported = result.equals("1"); - } - return mDozeModeSupported; - } - - public static boolean isAppStandbySupported() { - if (mAppStandbySupported == null) { - mAppStandbySupported = AppStandbyUtils.isAppStandbyEnabled(); - } - return mAppStandbySupported; - } - - public static boolean isLowRamDevice() { - final ActivityManager am = (ActivityManager) getContext().getSystemService( - Context.ACTIVITY_SERVICE); - return am.isLowRamDevice(); - } - - public static boolean isActiveNetworkMetered(boolean metered) { - return getConnectivityManager().isActiveNetworkMetered() == metered; - } - - public static boolean canChangeActiveNetworkMeteredness() { - final Network activeNetwork = getConnectivityManager().getActiveNetwork(); - final NetworkCapabilities networkCapabilities - = getConnectivityManager().getNetworkCapabilities(activeNetwork); - return networkCapabilities.hasTransport(TRANSPORT_WIFI); - } - - public static Pair setupMeteredNetwork(boolean metered) throws Exception { - if (isActiveNetworkMetered(metered)) { - return null; - } - final String ssid = unquoteSSID(getWifiManager().getConnectionInfo().getSSID()); - setWifiMeteredStatus(ssid, metered); - return Pair.create(ssid, !metered); - } - - public static void resetMeteredNetwork(String ssid, boolean metered) throws Exception { - setWifiMeteredStatus(ssid, metered); - } - - public static void setWifiMeteredStatus(String ssid, boolean metered) throws Exception { - assertFalse("SSID should not be empty", TextUtils.isEmpty(ssid)); - final String cmd = "cmd netpolicy set metered-network " + ssid + " " + metered; - executeShellCommand(cmd); - assertWifiMeteredStatus(ssid, metered); - assertActiveNetworkMetered(metered); - } - - public static void assertWifiMeteredStatus(String ssid, boolean expectedMeteredStatus) { - final String result = executeShellCommand("cmd netpolicy list wifi-networks"); - final String expectedLine = ssid + ";" + expectedMeteredStatus; - assertTrue("Expected line: " + expectedLine + "; Actual result: " + result, - result.contains(expectedLine)); - } - - // Copied from cts/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java - public static void assertActiveNetworkMetered(boolean expectedMeteredStatus) throws Exception { - final CountDownLatch latch = new CountDownLatch(1); - final NetworkCallback networkCallback = new NetworkCallback() { - @Override - public void onCapabilitiesChanged(Network network, NetworkCapabilities nc) { - final boolean metered = !nc.hasCapability(NET_CAPABILITY_NOT_METERED); - if (metered == expectedMeteredStatus) { - latch.countDown(); - } - } - }; - // Registering a callback here guarantees onCapabilitiesChanged is called immediately - // with the current setting. Therefore, if the setting has already been changed, - // this method will return right away, and if not it will wait for the setting to change. - getConnectivityManager().registerDefaultNetworkCallback(networkCallback); - if (!latch.await(TIMEOUT_CHANGE_METEREDNESS_MS, TimeUnit.MILLISECONDS)) { - fail("Timed out waiting for active network metered status to change to " - + expectedMeteredStatus + " ; network = " - + getConnectivityManager().getActiveNetwork()); - } - getConnectivityManager().unregisterNetworkCallback(networkCallback); - } - - public static void setRestrictBackground(boolean enabled) { - executeShellCommand("cmd netpolicy set restrict-background " + enabled); - final String output = executeShellCommand("cmd netpolicy get restrict-background"); - final String expectedSuffix = enabled ? "enabled" : "disabled"; - assertTrue("output '" + output + "' should end with '" + expectedSuffix + "'", - output.endsWith(expectedSuffix)); - } - - public static boolean isMyRestrictBackgroundStatus(int expectedStatus) { - final int actualStatus = getConnectivityManager().getRestrictBackgroundStatus(); - if (expectedStatus != actualStatus) { - Log.d(TAG, "MyRestrictBackgroundStatus: " - + "Expected: " + restrictBackgroundValueToString(expectedStatus) - + "; Actual: " + restrictBackgroundValueToString(actualStatus)); - return false; - } - return true; - } - - // Copied from cts/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java - private static String unquoteSSID(String ssid) { - // SSID is returned surrounded by quotes if it can be decoded as UTF-8. - // Otherwise it's guaranteed not to start with a quote. - if (ssid.charAt(0) == '"') { - return ssid.substring(1, ssid.length() - 1); - } else { - return ssid; - } - } - - public static String restrictBackgroundValueToString(int status) { - switch (status) { - case RESTRICT_BACKGROUND_STATUS_DISABLED: - return "DISABLED"; - case RESTRICT_BACKGROUND_STATUS_WHITELISTED: - return "WHITELISTED"; - case RESTRICT_BACKGROUND_STATUS_ENABLED: - return "ENABLED"; - default: - return "UNKNOWN_STATUS_" + status; - } - } - - public static String executeShellCommand(String command) { - final String result = runShellCommand(command).trim(); - Log.d(TAG, "Output of '" + command + "': '" + result + "'"); - return result; - } - - public static void assertMyRestrictBackgroundStatus(int expectedStatus) { - final int actualStatus = getConnectivityManager().getRestrictBackgroundStatus(); - assertEquals(restrictBackgroundValueToString(expectedStatus), - restrictBackgroundValueToString(actualStatus)); - } - - public static ConnectivityManager getConnectivityManager() { - if (mCm == null) { - mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); - } - return mCm; - } - - public static WifiManager getWifiManager() { - if (mWm == null) { - mWm = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); - } - return mWm; - } - - public static Context getContext() { - return getInstrumentation().getContext(); - } - - public static Instrumentation getInstrumentation() { - return InstrumentationRegistry.getInstrumentation(); - } -} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/Property.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/Property.java deleted file mode 100644 index 18805f9613..0000000000 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/Property.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2019 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.cts.net.hostside; - -import static com.android.cts.net.hostside.NetworkPolicyTestUtils.canChangeActiveNetworkMeteredness; -import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isActiveNetworkMetered; -import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isAppStandbySupported; -import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isBatterySaverSupported; -import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isDataSaverSupported; -import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isDozeModeSupported; -import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isLowRamDevice; - -public enum Property { - BATTERY_SAVER_MODE(1 << 0) { - public boolean isSupported() { return isBatterySaverSupported(); } - }, - - DATA_SAVER_MODE(1 << 1) { - public boolean isSupported() { return isDataSaverSupported(); } - }, - - NO_DATA_SAVER_MODE(~DATA_SAVER_MODE.getValue()) { - public boolean isSupported() { return !isDataSaverSupported(); } - }, - - DOZE_MODE(1 << 2) { - public boolean isSupported() { return isDozeModeSupported(); } - }, - - APP_STANDBY_MODE(1 << 3) { - public boolean isSupported() { return isAppStandbySupported(); } - }, - - NOT_LOW_RAM_DEVICE(1 << 4) { - public boolean isSupported() { return !isLowRamDevice(); } - }, - - METERED_NETWORK(1 << 5) { - public boolean isSupported() { - return isActiveNetworkMetered(true) || canChangeActiveNetworkMeteredness(); - } - }, - - NON_METERED_NETWORK(~METERED_NETWORK.getValue()) { - public boolean isSupported() { - return isActiveNetworkMetered(false) || canChangeActiveNetworkMeteredness(); - } - }; - - private int mValue; - - Property(int value) { mValue = value; } - - public int getValue() { return mValue; } - - abstract boolean isSupported(); -} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredProperties.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredProperties.java deleted file mode 100644 index 96838bba0a..0000000000 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredProperties.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2019 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.cts.net.hostside; - -import static java.lang.annotation.ElementType.METHOD; -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -@Retention(RUNTIME) -@Target({METHOD, TYPE}) -@Inherited -public @interface RequiredProperties { - Property[] value(); -} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java deleted file mode 100644 index 1e333200db..0000000000 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2019 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.cts.net.hostside; - -import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TAG; - -import android.text.TextUtils; -import android.util.ArraySet; -import android.util.Log; - -import com.android.compatibility.common.util.BeforeAfterRule; - -import org.junit.Assume; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; - -import java.util.ArrayList; -import java.util.Collections; - -public class RequiredPropertiesRule extends BeforeAfterRule { - - private static ArraySet mRequiredProperties; - - @Override - public void onBefore(Statement base, Description description) { - mRequiredProperties = getAllRequiredProperties(description); - - final String testName = description.getClassName() + "#" + description.getMethodName(); - assertTestIsValid(testName, mRequiredProperties); - Log.i(TAG, "Running test " + testName + " with required properties: " - + propertiesToString(mRequiredProperties)); - } - - private ArraySet getAllRequiredProperties(Description description) { - final ArraySet allRequiredProperties = new ArraySet<>(); - RequiredProperties requiredProperties = description.getAnnotation(RequiredProperties.class); - if (requiredProperties != null) { - Collections.addAll(allRequiredProperties, requiredProperties.value()); - } - - for (Class clazz = description.getTestClass(); - clazz != null; clazz = clazz.getSuperclass()) { - requiredProperties = clazz.getDeclaredAnnotation(RequiredProperties.class); - if (requiredProperties == null) { - continue; - } - for (Property requiredProperty : requiredProperties.value()) { - if (!allRequiredProperties.contains(~requiredProperty.getValue())) { - allRequiredProperties.add(requiredProperty); - } - } - } - return allRequiredProperties; - } - - private void assertTestIsValid(String testName, ArraySet requiredProperies) { - if (requiredProperies == null) { - return; - } - final ArrayList unsupportedProperties = new ArrayList<>(); - for (Property property : requiredProperies) { - if (!property.isSupported()) { - unsupportedProperties.add(property); - } - } - Assume.assumeTrue("Unsupported properties: " - + propertiesToString(unsupportedProperties), unsupportedProperties.isEmpty()); - } - - public static ArraySet getRequiredProperties() { - return mRequiredProperties; - } - - private static String propertiesToString(Iterable properties) { - return "[" + TextUtils.join(",", properties) + "]"; - } -} diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java index 1312085478..8d6c4acd7d 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java @@ -29,14 +29,14 @@ public class HostsideNetworkCallbackTests extends HostsideNetworkTestCase { uninstallPackage(TEST_APP2_PKG, true); } - public void testOnBlockedStatusChanged_dataSaver() throws Exception { + public void testOnBlockedStatusChanged_data_saver() throws Exception { runDeviceTests(TEST_PKG, - TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_dataSaver"); + TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_data_saver"); } - public void testOnBlockedStatusChanged_powerSaver() throws Exception { + public void testOnBlockedStatusChanged_power_saver() throws Exception { runDeviceTests(TEST_PKG, - TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_powerSaver"); + TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_power_saver"); } } diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java index ce203795f9..a2443b391a 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java @@ -79,8 +79,7 @@ abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiRec protected void installPackage(String apk) throws FileNotFoundException, DeviceNotAvailableException { CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild); - assertNull(getDevice().installPackage(buildHelper.getTestFile(apk), - false /* reinstall */, true /* grantPermissions */)); + assertNull(getDevice().installPackage(buildHelper.getTestFile(apk), false)); } protected void uninstallPackage(String packageName, boolean shouldSucceed) From 6aac2067f63989e22cb95488da8a5ef7ac806737 Mon Sep 17 00:00:00 2001 From: Chiachang Wang Date: Wed, 22 Apr 2020 11:01:25 +0800 Subject: [PATCH 0906/1109] Check target transport type for meterness change When test case updates the wifi network from unmetered to metered, test case will wait for wifi network reconnect. However, if other metered networks are also connected at the same time, test case may mis-take the network as the target network. Thus, add transport type check to ensure the transport type of the network is the expected one. Bug: 153400606 Test: atest CtsNetTestCasesLatestSdk:\ android.net.cts.ConnectivityManagerTest#\ testGetMultipathPreference Change-Id: I75dab1a00bbe1a1c75b548a6ce4ae3eacd325d92 --- .../src/android/net/cts/ConnectivityManagerTest.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 3a52ee60a3..1ee08ffa7a 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -639,11 +639,14 @@ public class ConnectivityManagerTest extends AndroidTestCase { } } - private void waitForActiveNetworkMetered(boolean requestedMeteredness) throws Exception { + private void waitForActiveNetworkMetered(int targetTransportType, boolean requestedMeteredness) + throws Exception { final CountDownLatch latch = new CountDownLatch(1); final NetworkCallback networkCallback = new NetworkCallback() { @Override public void onCapabilitiesChanged(Network network, NetworkCapabilities nc) { + if (!nc.hasTransport(targetTransportType)) return; + final boolean metered = !nc.hasCapability(NET_CAPABILITY_NOT_METERED); if (metered == requestedMeteredness) { latch.countDown(); @@ -720,10 +723,10 @@ public class ConnectivityManagerTest extends AndroidTestCase { Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE, Integer.toString(newMeteredPreference)); setWifiMeteredStatus(ssid, "true"); - waitForActiveNetworkMetered(true); + waitForActiveNetworkMetered(TRANSPORT_WIFI, true); // Wifi meterness changes from unmetered to metered will disconnect and reconnect since // R. - final Network network = mCm.getActiveNetwork(); + final Network network = ensureWifiConnected(); assertEquals(ssid, unquoteSSID(mWifiManager.getConnectionInfo().getSSID())); assertEquals(mCm.getNetworkCapabilities(network).hasCapability( NET_CAPABILITY_NOT_METERED), false); @@ -741,7 +744,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { setWifiMeteredStatus(ssid, "false"); // No disconnect from unmetered to metered. - waitForActiveNetworkMetered(false); + waitForActiveNetworkMetered(TRANSPORT_WIFI, false); assertEquals(mCm.getNetworkCapabilities(network).hasCapability( NET_CAPABILITY_NOT_METERED), true); assertMultipathPreferenceIsEventually(network, newMeteredPreference, From 1136e51d551fe34b3675e40790c77d86bfbcfbbd Mon Sep 17 00:00:00 2001 From: Chiachang Wang Date: Wed, 22 Apr 2020 07:45:16 +0000 Subject: [PATCH 0907/1109] Check target transport type for meterness change When test case updates the wifi network from unmetered to metered, test case will wait for wifi network reconnect. However, if other metered networks are also connected at the same time, test case may mis-take the network as the target network. Thus, add transport type check to ensure the transport type of the network is the expected one. Bug: 153400606 Test: atest CtsNetTestCasesLatestSdk:\ android.net.cts.ConnectivityManagerTest#\ testGetMultipathPreference Change-Id: I75dab1a00bbe1a1c75b548a6ce4ae3eacd325d92 Merged-In: I75dab1a00bbe1a1c75b548a6ce4ae3eacd325d92 (cherry picked from commit 495971d7b6abc65e6d506072038f499682f59f4d) --- .../src/android/net/cts/ConnectivityManagerTest.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 3a52ee60a3..1ee08ffa7a 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -639,11 +639,14 @@ public class ConnectivityManagerTest extends AndroidTestCase { } } - private void waitForActiveNetworkMetered(boolean requestedMeteredness) throws Exception { + private void waitForActiveNetworkMetered(int targetTransportType, boolean requestedMeteredness) + throws Exception { final CountDownLatch latch = new CountDownLatch(1); final NetworkCallback networkCallback = new NetworkCallback() { @Override public void onCapabilitiesChanged(Network network, NetworkCapabilities nc) { + if (!nc.hasTransport(targetTransportType)) return; + final boolean metered = !nc.hasCapability(NET_CAPABILITY_NOT_METERED); if (metered == requestedMeteredness) { latch.countDown(); @@ -720,10 +723,10 @@ public class ConnectivityManagerTest extends AndroidTestCase { Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE, Integer.toString(newMeteredPreference)); setWifiMeteredStatus(ssid, "true"); - waitForActiveNetworkMetered(true); + waitForActiveNetworkMetered(TRANSPORT_WIFI, true); // Wifi meterness changes from unmetered to metered will disconnect and reconnect since // R. - final Network network = mCm.getActiveNetwork(); + final Network network = ensureWifiConnected(); assertEquals(ssid, unquoteSSID(mWifiManager.getConnectionInfo().getSSID())); assertEquals(mCm.getNetworkCapabilities(network).hasCapability( NET_CAPABILITY_NOT_METERED), false); @@ -741,7 +744,7 @@ public class ConnectivityManagerTest extends AndroidTestCase { setWifiMeteredStatus(ssid, "false"); // No disconnect from unmetered to metered. - waitForActiveNetworkMetered(false); + waitForActiveNetworkMetered(TRANSPORT_WIFI, false); assertEquals(mCm.getNetworkCapabilities(network).hasCapability( NET_CAPABILITY_NOT_METERED), true); assertMultipathPreferenceIsEventually(network, newMeteredPreference, From 6f63ef0e470914e87edfa379f93c83c4afab2f76 Mon Sep 17 00:00:00 2001 From: Chiachang Wang Date: Wed, 22 Apr 2020 22:15:09 +0800 Subject: [PATCH 0908/1109] Update logic for checking NetworkSpecifier We cannot test using WifiNetworkSpecifier, because the matching behaviour for null WifiNetworkSpecifier changed between Q and R. Replace WifiNetworkSpecifier with MatchAllNetworkSpecifier and TelephonyNetworkSpecifier that behave the same in both Q and R to verify. Bug: 154451660 Test: atest CtsNetTestCasesLatestSdk:android.net.cts.NetworkRequestTest on aosp and internal build Change-Id: I14e2a5e629051e243f3b892b608cb1c6195cd8ed --- .../android/net/cts/NetworkRequestTest.java | 63 ++++++++++++------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java index 6a1d9de6f6..5e92b410f5 100644 --- a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java +++ b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java @@ -29,9 +29,11 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import android.net.MacAddress; +import android.net.MatchAllNetworkSpecifier; import android.net.NetworkCapabilities; import android.net.NetworkRequest; import android.net.NetworkSpecifier; +import android.net.TelephonyNetworkSpecifier; import android.net.wifi.WifiNetworkSpecifier; import android.os.Build; import android.os.Process; @@ -127,39 +129,54 @@ public class NetworkRequestTest { @Test @IgnoreUpTo(Build.VERSION_CODES.Q) public void testCanBeSatisfiedBy() { - final WifiNetworkSpecifier specifier1 = new WifiNetworkSpecifier.Builder() - .setSsidPattern(new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL)) - .setBssidPattern(ARBITRARY_ADDRESS, ARBITRARY_ADDRESS) + final TelephonyNetworkSpecifier specifier1 = new TelephonyNetworkSpecifier.Builder() + .setSubscriptionId(1234 /* subId */) .build(); - final WifiNetworkSpecifier specifier2 = new WifiNetworkSpecifier.Builder() - .setSsidPattern(new PatternMatcher(OTHER_SSID, PatternMatcher.PATTERN_LITERAL)) - .setBssidPattern(ARBITRARY_ADDRESS, ARBITRARY_ADDRESS) + final TelephonyNetworkSpecifier specifier2 = new TelephonyNetworkSpecifier.Builder() + .setSubscriptionId(5678 /* subId */) .build(); final NetworkCapabilities cap = new NetworkCapabilities() - .addTransportType(TRANSPORT_WIFI) - .addCapability(NET_CAPABILITY_INTERNET); - final NetworkCapabilities capWithSp = - new NetworkCapabilities(cap).setNetworkSpecifier(specifier1); - final NetworkCapabilities cellCap = new NetworkCapabilities() .addTransportType(TRANSPORT_CELLULAR) .addCapability(NET_CAPABILITY_MMS) .addCapability(NET_CAPABILITY_INTERNET); - final NetworkRequest request = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_WIFI) + final NetworkCapabilities capDualTransport = new NetworkCapabilities(cap) + .addTransportType(TRANSPORT_VPN); + final NetworkCapabilities capWithSpecifier1 = + new NetworkCapabilities(cap).setNetworkSpecifier(specifier1); + final NetworkCapabilities capDiffTransportWithSpecifier1 = new NetworkCapabilities() + .addCapability(NET_CAPABILITY_INTERNET) + .addTransportType(TRANSPORT_VPN) + .setNetworkSpecifier(specifier1); + + final NetworkRequest requestWithSpecifier1 = new NetworkRequest.Builder() + .addTransportType(TRANSPORT_CELLULAR) .addCapability(NET_CAPABILITY_INTERNET) .setNetworkSpecifier(specifier1) .build(); - assertFalse(request.canBeSatisfiedBy(null)); - assertFalse(request.canBeSatisfiedBy(new NetworkCapabilities())); - assertTrue(request.canBeSatisfiedBy(cap)); - assertTrue(request.canBeSatisfiedBy( - new NetworkCapabilities(cap).addTransportType(TRANSPORT_VPN))); - assertTrue(request.canBeSatisfiedBy(capWithSp)); - assertFalse(request.canBeSatisfiedBy( + assertFalse(requestWithSpecifier1.canBeSatisfiedBy(null)); + assertFalse(requestWithSpecifier1.canBeSatisfiedBy(new NetworkCapabilities())); + assertTrue(requestWithSpecifier1.canBeSatisfiedBy(new NetworkCapabilities(cap) + .setNetworkSpecifier(new MatchAllNetworkSpecifier()))); + assertTrue(requestWithSpecifier1.canBeSatisfiedBy(cap)); + assertTrue(requestWithSpecifier1.canBeSatisfiedBy(capWithSpecifier1)); + assertTrue(requestWithSpecifier1.canBeSatisfiedBy(capDualTransport)); + assertFalse(requestWithSpecifier1.canBeSatisfiedBy( new NetworkCapabilities(cap).setNetworkSpecifier(specifier2))); - assertFalse(request.canBeSatisfiedBy(cellCap)); - assertEquals(request.canBeSatisfiedBy(capWithSp), - new NetworkCapabilities(capWithSp).satisfiedByNetworkCapabilities(capWithSp)); + + final NetworkRequest request = new NetworkRequest.Builder() + .addTransportType(TRANSPORT_CELLULAR) + .addCapability(NET_CAPABILITY_INTERNET) + .build(); + assertTrue(request.canBeSatisfiedBy(cap)); + assertTrue(request.canBeSatisfiedBy(capWithSpecifier1)); + assertTrue(request.canBeSatisfiedBy( + new NetworkCapabilities(cap).setNetworkSpecifier(specifier2))); + assertFalse(request.canBeSatisfiedBy(capDiffTransportWithSpecifier1)); + assertTrue(request.canBeSatisfiedBy(capDualTransport)); + + assertEquals(requestWithSpecifier1.canBeSatisfiedBy(capWithSpecifier1), + new NetworkCapabilities(capWithSpecifier1) + .satisfiedByNetworkCapabilities(capWithSpecifier1)); } @Test @IgnoreUpTo(Build.VERSION_CODES.Q) From 1206400ccf0616667a65e2c9c1e67f50d3b6e430 Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Wed, 22 Apr 2020 12:25:23 -0700 Subject: [PATCH 0909/1109] Reland "Pull service dumps to help debug test failures." + Convert tests to use Junit4 + Add annotations to specify required conditions for the test to run. This reverts commit 89099548f8ea46046095ccac1e82c2c88d1d0bee. Bug: 137859686 Change-Id: I7bb2a7e4b2dca3696761e7c030f3380b9226b676 Merged-In: I93317c201a0ea06732e29154ab7e140735381f59 --- tests/cts/hostside/AndroidTest.xml | 5 + tests/cts/hostside/app/Android.bp | 2 + tests/cts/hostside/app/AndroidManifest.xml | 3 +- .../net/hostside/AbstractAppIdleTestCase.java | 76 ++-- .../AbstractBatterySaverModeTestCase.java | 68 +--- .../hostside/AbstractDozeModeTestCase.java | 66 +--- ...ractRestrictBackgroundNetworkTestCase.java | 361 ++---------------- .../cts/net/hostside/AppIdleMeteredTest.java | 13 +- .../net/hostside/AppIdleNonMeteredTest.java | 7 +- .../hostside/BatterySaverModeMeteredTest.java | 13 +- .../BatterySaverModeNonMeteredTest.java | 9 +- .../cts/net/hostside/DataSaverModeTest.java | 66 ++-- .../cts/net/hostside/DozeModeMeteredTest.java | 13 +- .../net/hostside/DozeModeNonMeteredTest.java | 8 +- .../cts/net/hostside/DumpOnFailureRule.java | 91 +++++ .../MeterednessConfigurationRule.java | 60 +++ .../cts/net/hostside/MixedModesTest.java | 230 +++++------ .../cts/net/hostside/NetworkCallbackTest.java | 173 +++++---- .../net/hostside/NetworkPolicyTestUtils.java | 255 +++++++++++++ .../android/cts/net/hostside/Property.java | 70 ++++ .../cts/net/hostside/RequiredProperties.java | 31 ++ .../net/hostside/RequiredPropertiesRule.java | 90 +++++ .../cts/net/HostsideNetworkCallbackTests.java | 8 +- .../cts/net/HostsideNetworkTestCase.java | 3 +- 24 files changed, 939 insertions(+), 782 deletions(-) create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/Property.java create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredProperties.java create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java diff --git a/tests/cts/hostside/AndroidTest.xml b/tests/cts/hostside/AndroidTest.xml index dbff1794e9..5479c51a4c 100644 --- a/tests/cts/hostside/AndroidTest.xml +++ b/tests/cts/hostside/AndroidTest.xml @@ -31,4 +31,9 @@

    By default is empty - it's up to subclasses to override. - */ - protected void setUpMeteredNetwork() throws Exception { - } - - /** - * Resets the (non) metered network state. - * - *

    By default is empty - it's up to subclasses to override. - */ - protected void tearDownMeteredNetwork() throws Exception { + setBatterySaverMode(false); } + @Test public void testBackgroundNetworkAccess_enabled() throws Exception { - if (!isSupported()) return; - setBatterySaverMode(true); assertBackgroundNetworkAccess(false); @@ -118,9 +80,8 @@ abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgrou assertBackgroundNetworkAccess(false); } + @Test public void testBackgroundNetworkAccess_whitelisted() throws Exception { - if (!isSupported()) return; - setBatterySaverMode(true); assertBackgroundNetworkAccess(false); @@ -140,9 +101,8 @@ abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgrou assertBackgroundNetworkAccess(false); } + @Test public void testBackgroundNetworkAccess_disabled() throws Exception { - if (!isSupported()) return; - assertBackgroundNetworkAccess(true); assertsForegroundAlwaysHasNetworkAccess(); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java index f20f1d1c4d..6f32c563c1 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java @@ -16,20 +16,25 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.Property.DOZE_MODE; +import static com.android.cts.net.hostside.Property.NOT_LOW_RAM_DEVICE; + import android.os.SystemClock; -import android.util.Log; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; /** * Base class for metered and non-metered Doze Mode tests. */ +@RequiredProperties({DOZE_MODE}) abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetworkTestCase { - @Override - protected final void setUp() throws Exception { + @Before + public final void setUp() throws Exception { super.setUp(); - if (!isSupported()) return; - // Set initial state. removePowerSaveModeWhitelist(TEST_APP2_PKG); removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG); @@ -38,48 +43,15 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor registerBroadcastReceiver(); } - @Override - protected final void tearDown() throws Exception { + @After + public final void tearDown() throws Exception { super.tearDown(); - if (!isSupported()) return; - - try { - tearDownMeteredNetwork(); - } finally { - setDozeMode(false); - } - } - - @Override - protected boolean isSupported() throws Exception { - boolean supported = isDozeModeEnabled(); - if (!supported) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Doze Mode"); - } - return supported; - } - - /** - * Sets the initial (non) metered network state. - * - *

    By default is empty - it's up to subclasses to override. - */ - protected void setUpMeteredNetwork() throws Exception { - } - - /** - * Resets the (non) metered network state. - * - *

    By default is empty - it's up to subclasses to override. - */ - protected void tearDownMeteredNetwork() throws Exception { + setDozeMode(false); } + @Test public void testBackgroundNetworkAccess_enabled() throws Exception { - if (!isSupported()) return; - setDozeMode(true); assertBackgroundNetworkAccess(false); @@ -96,9 +68,8 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor assertBackgroundNetworkAccess(false); } + @Test public void testBackgroundNetworkAccess_whitelisted() throws Exception { - if (!isSupported()) return; - setDozeMode(true); assertBackgroundNetworkAccess(false); @@ -118,19 +89,18 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor assertBackgroundNetworkAccess(false); } + @Test public void testBackgroundNetworkAccess_disabled() throws Exception { - if (!isSupported()) return; - assertBackgroundNetworkAccess(true); assertsForegroundAlwaysHasNetworkAccess(); assertBackgroundNetworkAccess(true); } + @RequiredProperties({NOT_LOW_RAM_DEVICE}) + @Test public void testBackgroundNetworkAccess_enabledButWhitelistedOnNotificationAction() throws Exception { - if (!isSupported() || isLowRamDevice()) return; - setPendingIntentWhitelistDuration(NETWORK_TIMEOUT_MS); try { registerNotificationListenerService(); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 40d7e34fcc..57b7bb4f8d 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -17,14 +17,22 @@ package com.android.cts.net.hostside; import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; -import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; -import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; -import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; import static android.os.BatteryManager.BATTERY_PLUGGED_AC; import static android.os.BatteryManager.BATTERY_PLUGGED_USB; import static android.os.BatteryManager.BATTERY_PLUGGED_WIRELESS; -import static com.android.compatibility.common.util.SystemUtil.runShellCommand; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.executeShellCommand; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getConnectivityManager; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getContext; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getInstrumentation; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getWifiManager; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isDozeModeSupported; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.restrictBackgroundValueToString; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import android.app.ActivityManager; import android.app.Instrumentation; @@ -34,9 +42,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.pm.PackageManager; import android.net.ConnectivityManager; -import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; import android.net.wifi.WifiManager; @@ -44,24 +50,27 @@ import android.os.BatteryManager; import android.os.Binder; import android.os.Bundle; import android.os.SystemClock; -import android.os.SystemProperties; import android.provider.Settings; import android.service.notification.NotificationListenerService; -import android.test.InstrumentationTestCase; -import android.text.TextUtils; import android.util.Log; -import com.android.compatibility.common.util.BatteryUtils; +import org.junit.Rule; +import org.junit.rules.RuleChain; +import org.junit.runner.RunWith; import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + /** * Superclass for tests related to background network restrictions. */ -abstract class AbstractRestrictBackgroundNetworkTestCase extends InstrumentationTestCase { - protected static final String TAG = "RestrictBackgroundNetworkTests"; +@RunWith(AndroidJUnit4.class) +public abstract class AbstractRestrictBackgroundNetworkTestCase { + public static final String TAG = "RestrictBackgroundNetworkTests"; protected static final String TEST_PKG = "com.android.cts.net.hostside"; protected static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2"; @@ -98,8 +107,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation static final int NETWORK_TIMEOUT_MS = 15 * SECOND_IN_MS; private static int PROCESS_STATE_FOREGROUND_SERVICE; - private static final int PROCESS_STATE_TOP = 2; - private static final String KEY_NETWORK_STATE_OBSERVER = TEST_PKG + ".observer"; protected static final int TYPE_COMPONENT_ACTIVTIY = 0; @@ -126,22 +133,23 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected WifiManager mWfm; protected int mUid; private int mMyUid; - private String mMeteredWifi; private MyServiceClient mServiceClient; private String mDeviceIdleConstantsSetting; - private boolean mSupported; private boolean mIsLocationOn; - @Override + @Rule + public final RuleChain mRuleChain = RuleChain.outerRule(new DumpOnFailureRule()) + .around(new RequiredPropertiesRule()) + .around(new MeterednessConfigurationRule()); + protected void setUp() throws Exception { - super.setUp(); PROCESS_STATE_FOREGROUND_SERVICE = (Integer) ActivityManager.class .getDeclaredField("PROCESS_STATE_FOREGROUND_SERVICE").get(null); mInstrumentation = getInstrumentation(); - mContext = mInstrumentation.getContext(); - mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); - mWfm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); + mContext = getContext(); + mCm = getConnectivityManager(); + mWfm = getWifiManager(); mUid = getUid(TEST_APP2_PKG); mMyUid = getUid(mContext.getPackageName()); mServiceClient = new MyServiceClient(mContext); @@ -151,10 +159,9 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation if (!mIsLocationOn) { enableLocation(); } - mSupported = setUpActiveNetworkMeteringState(); setAppIdle(false); - Log.i(TAG, "Apps status on " + getName() + ":\n" + Log.i(TAG, "Apps status:\n" + "\ttest app: uid=" + mMyUid + ", state=" + getProcessStateByUid(mMyUid) + "\n" + "\tapp2: uid=" + mUid + ", state=" + getProcessStateByUid(mUid)); @@ -165,16 +172,13 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation final String currentConstants = executeShellCommand("settings get global app_idle_constants"); assertEquals(appIdleConstants, currentConstants); - } + } - @Override protected void tearDown() throws Exception { if (!mIsLocationOn) { disableLocation(); } mServiceClient.unbind(); - - super.tearDown(); } private void enableLocation() throws Exception { @@ -259,23 +263,8 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected void assertRestrictBackgroundStatus(int expectedStatus) throws Exception { final String status = mServiceClient.getRestrictBackgroundStatus(); assertNotNull("didn't get API status from app2", status); - final String actualStatus = toString(Integer.parseInt(status)); - assertEquals("wrong status", toString(expectedStatus), actualStatus); - } - - protected void assertMyRestrictBackgroundStatus(int expectedStatus) throws Exception { - final int actualStatus = mCm.getRestrictBackgroundStatus(); - assertEquals("Wrong status", toString(expectedStatus), toString(actualStatus)); - } - - protected boolean isMyRestrictBackgroundStatus(int expectedStatus) throws Exception { - final int actualStatus = mCm.getRestrictBackgroundStatus(); - if (expectedStatus != actualStatus) { - Log.d(TAG, "Expected: " + toString(expectedStatus) - + " but actual: " + toString(actualStatus)); - return false; - } - return true; + assertEquals(restrictBackgroundValueToString(expectedStatus), + restrictBackgroundValueToString(Integer.parseInt(status))); } protected void assertBackgroundNetworkAccess(boolean expectAllowed) throws Exception { @@ -297,28 +286,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation assertNetworkAccess(true /* expectAvailable */, false /* needScreenOn */); } - /** - * Whether this device suport this type of test. - * - *

    Should be overridden when necessary (but always calling - * {@code super.isSupported()} first), and explicitly used before each test - * Example: - * - *

    
    -     * public void testSomething() {
    -     *    if (!isSupported()) return;
    -     * 
    - * - * @return {@code true} by default. - */ - protected boolean isSupported() throws Exception { - return mSupported; - } - - protected boolean isBatterySaverSupported() { - return BatteryUtils.isBatterySaverSupported(); - } - /** * Asserts that an app always have access while on foreground or running a foreground service. * @@ -387,23 +354,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation fail("App2 is not on foreground service state after " + maxTries + " attempts: " + state ); } - /** - * As per CDD requirements, if the device doesn't support data saver mode then - * ConnectivityManager.getRestrictBackgroundStatus() will always return - * RESTRICT_BACKGROUND_STATUS_DISABLED. So, enable the data saver mode and check if - * ConnectivityManager.getRestrictBackgroundStatus() for an app in background returns - * RESTRICT_BACKGROUND_STATUS_DISABLED or not. - */ - protected boolean isDataSaverSupported() throws Exception { - assertMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); - try { - setRestrictBackground(true); - return !isMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); - } finally { - setRestrictBackground(false); - } - } - /** * Returns whether an app state should be considered "background" for restriction purposes. */ @@ -443,40 +393,10 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation // Exponential back-off. timeoutMs = Math.min(timeoutMs*2, NETWORK_TIMEOUT_MS); } - dumpOnFailure(); fail("Invalid state for expectAvailable=" + expectAvailable + " after " + maxTries + " attempts.\nLast error: " + error); } - private void dumpOnFailure() throws Exception { - dumpAllNetworkRules(); - Log.d(TAG, "Usagestats dump: " + getUsageStatsDump()); - executeShellCommand("settings get global app_idle_constants"); - } - - private void dumpAllNetworkRules() throws Exception { - final String networkManagementDump = runShellCommand(mInstrumentation, - "dumpsys network_management").trim(); - final String networkPolicyDump = runShellCommand(mInstrumentation, - "dumpsys netpolicy").trim(); - TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter('\n'); - splitter.setString(networkManagementDump); - String next; - Log.d(TAG, ">>> Begin network_management dump"); - while (splitter.hasNext()) { - next = splitter.next(); - Log.d(TAG, next); - } - Log.d(TAG, "<<< End network_management dump"); - splitter.setString(networkPolicyDump); - Log.d(TAG, ">>> Begin netpolicy dump"); - while (splitter.hasNext()) { - next = splitter.next(); - Log.d(TAG, next); - } - Log.d(TAG, "<<< End netpolicy dump"); - } - /** * Checks whether the network is available as expected. * @@ -528,22 +448,10 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation return errors.toString(); } - protected boolean isLowRamDevice() { - final ActivityManager am = (ActivityManager) mContext.getSystemService( - Context.ACTIVITY_SERVICE); - return am.isLowRamDevice(); - } - - protected String executeShellCommand(String command) throws Exception { - final String result = runShellCommand(mInstrumentation, command).trim(); - if (DEBUG) Log.d(TAG, "Command '" + command + "' returned '" + result + "'"); - return result; - } - /** * Runs a Shell command which is not expected to generate output. */ - protected void executeSilentShellCommand(String command) throws Exception { + protected void executeSilentShellCommand(String command) { final String result = executeShellCommand(command); assertTrue("Command '" + command + "' failed: " + result, result.trim().isEmpty()); } @@ -572,10 +480,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation }); } - protected void assertDelayedShellCommand(String command, ExpectResultChecker checker) - throws Exception { - assertDelayedShellCommand(command, 5, 1, checker); - } protected void assertDelayedShellCommand(String command, int maxTries, int napTimeSeconds, ExpectResultChecker checker) throws Exception { String result = ""; @@ -592,159 +496,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation + " attempts. Last result: '" + result + "'"); } - /** - * Sets the initial metering state for the active network. - * - *

    It's called on setup and by default does nothing - it's up to the - * subclasses to override. - * - * @return whether the tests in the subclass are supported on this device. - */ - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return true; - } - - /** - * Makes sure the active network is not metered. - * - *

    If the device does not supoprt un-metered networks (for example if it - * only has cellular data but not wi-fi), it should return {@code false}; - * otherwise, it should return {@code true} (or fail if the un-metered - * network could not be set). - * - * @return {@code true} if the network is now unmetered. - */ - protected boolean setUnmeteredNetwork() throws Exception { - final NetworkInfo info = mCm.getActiveNetworkInfo(); - assertNotNull("Could not get active network", info); - if (!mCm.isActiveNetworkMetered()) { - Log.d(TAG, "Active network is not metered: " + info); - } else if (info.getType() == ConnectivityManager.TYPE_WIFI) { - Log.i(TAG, "Setting active WI-FI network as not metered: " + info ); - setWifiMeteredStatus(false); - } else { - Log.d(TAG, "Active network cannot be set to un-metered: " + info); - return false; - } - assertActiveNetworkMetered(false); // Sanity check. - return true; - } - - /** - * Enables metering on the active network if supported. - * - *

    If the device does not support metered networks it should return - * {@code false}; otherwise, it should return {@code true} (or fail if the - * metered network could not be set). - * - * @return {@code true} if the network is now metered. - */ - protected boolean setMeteredNetwork() throws Exception { - final NetworkInfo info = mCm.getActiveNetworkInfo(); - final boolean metered = mCm.isActiveNetworkMetered(); - if (metered) { - Log.d(TAG, "Active network already metered: " + info); - return true; - } else if (info.getType() != ConnectivityManager.TYPE_WIFI) { - Log.w(TAG, "Active network does not support metering: " + info); - return false; - } else { - Log.w(TAG, "Active network not metered: " + info); - } - final String netId = setWifiMeteredStatus(true); - - // Set flag so status is reverted on resetMeteredNetwork(); - mMeteredWifi = netId; - // Sanity check. - assertWifiMeteredStatus(netId, true); - assertActiveNetworkMetered(true); - return true; - } - - /** - * Resets the device metering state to what it was before the test started. - * - *

    This reverts any metering changes made by {@code setMeteredNetwork}. - */ - protected void resetMeteredNetwork() throws Exception { - if (mMeteredWifi != null) { - Log.i(TAG, "resetMeteredNetwork(): SID '" + mMeteredWifi - + "' was set as metered by test case; resetting it"); - setWifiMeteredStatus(mMeteredWifi, false); - assertActiveNetworkMetered(false); // Sanity check. - } - } - - private void assertActiveNetworkMetered(boolean expected) throws Exception { - final int maxTries = 5; - NetworkInfo info = null; - for (int i = 1; i <= maxTries; i++) { - info = mCm.getActiveNetworkInfo(); - if (info == null) { - Log.v(TAG, "No active network info on attempt #" + i - + "; sleeping 1s before polling again"); - } else if (mCm.isActiveNetworkMetered() != expected) { - Log.v(TAG, "Wrong metered status for active network " + info + "; expected=" - + expected + "; sleeping 1s before polling again"); - } else { - break; - } - Thread.sleep(SECOND_IN_MS); - } - assertNotNull("No active network after " + maxTries + " attempts", info); - assertEquals("Wrong metered status for active network " + info, expected, - mCm.isActiveNetworkMetered()); - } - - private String setWifiMeteredStatus(boolean metered) throws Exception { - // We could call setWifiEnabled() here, but it might take sometime to be in a consistent - // state (for example, if one of the saved network is not properly authenticated), so it's - // better to let the hostside test take care of that. - assertTrue("wi-fi is disabled", mWfm.isWifiEnabled()); - // TODO: if it's not guaranteed the device has wi-fi, we need to change the tests - // to make the actual verification of restrictions optional. - final String ssid = mWfm.getConnectionInfo().getSSID(); - return setWifiMeteredStatus(ssid, metered); - } - - private String setWifiMeteredStatus(String ssid, boolean metered) throws Exception { - assertNotNull("null SSID", ssid); - final String netId = ssid.trim().replaceAll("\"", ""); // remove quotes, if any. - assertFalse("empty SSID", ssid.isEmpty()); - - Log.i(TAG, "Setting wi-fi network " + netId + " metered status to " + metered); - final String setCommand = "cmd netpolicy set metered-network " + netId + " " + metered; - assertDelayedShellCommand(setCommand, ""); - - return netId; - } - - private void assertWifiMeteredStatus(String netId, boolean status) throws Exception { - final String command = "cmd netpolicy list wifi-networks"; - final String expectedLine = netId + ";" + status; - assertDelayedShellCommand(command, new ExpectResultChecker() { - - @Override - public boolean isExpected(String result) { - return result.contains(expectedLine); - } - - @Override - public String getExpected() { - return "line containing " + expectedLine; - } - }); - } - - protected void setRestrictBackground(boolean enabled) throws Exception { - executeShellCommand("cmd netpolicy set restrict-background " + enabled); - final String output = executeShellCommand("cmd netpolicy get restrict-background "); - final String expectedSuffix = enabled ? "enabled" : "disabled"; - // TODO: use MoreAsserts? - assertTrue("output '" + output + "' should end with '" + expectedSuffix + "'", - output.endsWith(expectedSuffix)); - } - protected void addRestrictBackgroundWhitelist(int uid) throws Exception { executeShellCommand("cmd netpolicy add restrict-background-whitelist " + uid); assertRestrictBackgroundWhitelist(uid, true); @@ -924,7 +675,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected void setDozeMode(boolean enabled) throws Exception { // Sanity check, since tests should check beforehand.... - assertTrue("Device does not support Doze Mode", isDozeModeEnabled()); + assertTrue("Device does not support Doze Mode", isDozeModeSupported()); Log.i(TAG, "Setting Doze Mode to " + enabled); if (enabled) { @@ -944,43 +695,16 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation assertDelayedShellCommand("dumpsys deviceidle get deep", enabled ? "IDLE" : "ACTIVE"); } - protected boolean isDozeModeEnabled() throws Exception { - final String result = executeShellCommand("cmd deviceidle enabled deep").trim(); - return result.equals("1"); - } - protected void setAppIdle(boolean enabled) throws Exception { Log.i(TAG, "Setting app idle to " + enabled); executeSilentShellCommand("am set-inactive " + TEST_APP2_PKG + " " + enabled ); assertAppIdle(enabled); // Sanity check } - private String getUsageStatsDump() throws Exception { - final String output = runShellCommand(mInstrumentation, "dumpsys usagestats").trim(); - final StringBuilder sb = new StringBuilder(); - final TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter('\n'); - splitter.setString(output); - String str; - while (splitter.hasNext()) { - str = splitter.next(); - if (str.contains("package=") - && !str.contains(TEST_PKG) && !str.contains(TEST_APP2_PKG)) { - continue; - } - if (str.trim().startsWith("config=") || str.trim().startsWith("time=")) { - continue; - } - sb.append(str).append('\n'); - } - return sb.toString(); - } - protected void assertAppIdle(boolean enabled) throws Exception { try { assertDelayedShellCommand("am get-inactive " + TEST_APP2_PKG, 15, 2, "Idle=" + enabled); } catch (Throwable e) { - Log.d(TAG, "UsageStats dump:\n" + getUsageStatsDump()); - executeShellCommand("settings get global app_idle_constants"); throw e; } } @@ -1061,12 +785,10 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation // App didn't come to foreground when the activity is started, so try again. assertForegroundNetworkAccess(); } else { - dumpOnFailure(); fail("Network is not available for app2 (" + mUid + "): " + errors[0]); } } } else { - dumpOnFailure(); fail("Timed out waiting for network availability status from app2 (" + mUid + ")"); } } else { @@ -1150,19 +872,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation } } - private String toString(int status) { - switch (status) { - case RESTRICT_BACKGROUND_STATUS_DISABLED: - return "DISABLED"; - case RESTRICT_BACKGROUND_STATUS_WHITELISTED: - return "WHITELISTED"; - case RESTRICT_BACKGROUND_STATUS_ENABLED: - return "ENABLED"; - default: - return "UNKNOWN_STATUS_" + status; - } - } - private ProcessState getProcessStateByUid(int uid) throws Exception { return new ProcessState(executeShellCommand("cmd activity get-uid-state " + uid)); } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java index 622d99361f..f1858d65a5 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java @@ -16,15 +16,8 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; + +@RequiredProperties({METERED_NETWORK}) public class AppIdleMeteredTest extends AbstractAppIdleTestCase { - - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setMeteredNetwork(); - } - - @Override - protected void tearDownMeteredNetwork() throws Exception { - resetMeteredNetwork(); - } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java index bde71f9100..e737a6dabe 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java @@ -16,9 +16,8 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; + +@RequiredProperties({NON_METERED_NETWORK}) public class AppIdleNonMeteredTest extends AbstractAppIdleTestCase { - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setUnmeteredNetwork(); - } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java index 3071cfe3f1..c78ca2ec77 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java @@ -16,15 +16,8 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; + +@RequiredProperties({METERED_NETWORK}) public class BatterySaverModeMeteredTest extends AbstractBatterySaverModeTestCase { - - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setMeteredNetwork(); - } - - @Override - protected void tearDownMeteredNetwork() throws Exception { - resetMeteredNetwork(); - } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java index 6d3076fe0e..fb52a540d8 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java @@ -16,10 +16,9 @@ package com.android.cts.net.hostside; -public class BatterySaverModeNonMeteredTest extends AbstractBatterySaverModeTestCase { - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setUnmeteredNetwork(); - } +import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; + +@RequiredProperties({NON_METERED_NETWORK}) +public class BatterySaverModeNonMeteredTest extends AbstractBatterySaverModeTestCase { } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index cfe6a73a0f..aa2c914e02 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -20,24 +20,33 @@ import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLE import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; -import android.util.Log; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground; +import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; +import static com.android.cts.net.hostside.Property.NO_DATA_SAVER_MODE; + +import static org.junit.Assert.fail; import com.android.compatibility.common.util.CddTest; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import androidx.test.filters.LargeTest; + +@RequiredProperties({DATA_SAVER_MODE, METERED_NETWORK}) +@LargeTest public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase { private static final String[] REQUIRED_WHITELISTED_PACKAGES = { "com.android.providers.downloads" }; - private boolean mIsDataSaverSupported; - - @Override + @Before public void setUp() throws Exception { super.setUp(); - mIsDataSaverSupported = isDataSaverSupported(); - // Set initial state. setRestrictBackground(false); removeRestrictBackgroundWhitelist(mUid); @@ -47,36 +56,15 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertRestrictBackgroundChangedReceived(0); } - @Override - protected void tearDown() throws Exception { + @After + public void tearDown() throws Exception { super.tearDown(); - if (!isSupported()) return; - - try { - resetMeteredNetwork(); - } finally { - setRestrictBackground(false); - } - } - - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setMeteredNetwork(); - } - - @Override - protected boolean isSupported() throws Exception { - if (!mIsDataSaverSupported) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Data Saver Mode"); - } - return mIsDataSaverSupported && super.isSupported(); + setRestrictBackground(false); } + @Test public void testGetRestrictBackgroundStatus_disabled() throws Exception { - if (!isSupported()) return; - assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED); // Sanity check: make sure status is always disabled, never whitelisted @@ -88,9 +76,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED); } + @Test public void testGetRestrictBackgroundStatus_whitelisted() throws Exception { - if (!isSupported()) return; - setRestrictBackground(true); assertRestrictBackgroundChangedReceived(1); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); @@ -107,9 +94,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); } + @Test public void testGetRestrictBackgroundStatus_enabled() throws Exception { - if (!isSupported()) return; - setRestrictBackground(true); assertRestrictBackgroundChangedReceived(1); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); @@ -142,9 +128,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertBackgroundNetworkAccess(false); } + @Test public void testGetRestrictBackgroundStatus_blacklisted() throws Exception { - if (!isSupported()) return; - addRestrictBackgroundBlacklist(mUid); assertRestrictBackgroundChangedReceived(1); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); @@ -180,9 +165,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertsForegroundAlwaysHasNetworkAccess(); } + @Test public void testGetRestrictBackgroundStatus_requiredWhitelistedPackages() throws Exception { - if (!isSupported()) return; - final StringBuilder error = new StringBuilder(); for (String packageName : REQUIRED_WHITELISTED_PACKAGES) { int uid = -1; @@ -202,10 +186,10 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase } } + @RequiredProperties({NO_DATA_SAVER_MODE}) @CddTest(requirement="7.4.7/C-2-2") + @Test public void testBroadcastNotSentOnUnsupportedDevices() throws Exception { - if (isSupported()) return; - setRestrictBackground(true); assertRestrictBackgroundChangedReceived(0); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java index e4189af587..4306c991c2 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java @@ -16,15 +16,8 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; + +@RequiredProperties({METERED_NETWORK}) public class DozeModeMeteredTest extends AbstractDozeModeTestCase { - - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setMeteredNetwork(); - } - - @Override - protected void tearDownMeteredNetwork() throws Exception { - resetMeteredNetwork(); - } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java index edbbb9e1ce..1e89f158a3 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java @@ -16,10 +16,8 @@ package com.android.cts.net.hostside; -public class DozeModeNonMeteredTest extends AbstractDozeModeTestCase { +import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setUnmeteredNetwork(); - } +@RequiredProperties({NON_METERED_NETWORK}) +public class DozeModeNonMeteredTest extends AbstractDozeModeTestCase { } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java new file mode 100644 index 0000000000..cedd62a0bc --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TAG; +import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TEST_PKG; + +import android.os.Environment; +import android.os.FileUtils; +import android.os.ParcelFileDescriptor; +import android.util.Log; + +import com.android.compatibility.common.util.OnFailureRule; + +import org.junit.AssumptionViolatedException; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import androidx.test.platform.app.InstrumentationRegistry; + +public class DumpOnFailureRule extends OnFailureRule { + private File mDumpDir = new File(Environment.getExternalStorageDirectory(), + "CtsHostsideNetworkTests"); + + @Override + public void onTestFailure(Statement base, Description description, Throwable throwable) { + final String testName = description.getClassName() + "_" + description.getMethodName(); + + if (throwable instanceof AssumptionViolatedException) { + Log.d(TAG, "Skipping test " + testName + ": " + throwable); + return; + } + + prepareDumpRootDir(); + final File dumpFile = new File(mDumpDir, "dump-" + testName); + Log.i(TAG, "Dumping debug info for " + description + ": " + dumpFile.getPath()); + try (FileOutputStream out = new FileOutputStream(dumpFile)) { + for (String cmd : new String[] { + "dumpsys netpolicy", + "dumpsys network_management", + "dumpsys usagestats " + TEST_PKG, + "dumpsys usagestats appstandby", + }) { + dumpCommandOutput(out, cmd); + } + } catch (FileNotFoundException e) { + Log.e(TAG, "Error opening file: " + dumpFile, e); + } catch (IOException e) { + Log.e(TAG, "Error closing file: " + dumpFile, e); + } + } + + void dumpCommandOutput(FileOutputStream out, String cmd) { + final ParcelFileDescriptor pfd = InstrumentationRegistry.getInstrumentation() + .getUiAutomation().executeShellCommand(cmd); + try (FileInputStream in = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) { + out.write(("Output of '" + cmd + "':\n").getBytes(StandardCharsets.UTF_8)); + FileUtils.copy(in, out); + out.write("\n\n=================================================================\n\n" + .getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + Log.e(TAG, "Error dumping '" + cmd + "'", e); + } + } + + void prepareDumpRootDir() { + if (!mDumpDir.exists() && !mDumpDir.mkdir()) { + Log.e(TAG, "Error creating " + mDumpDir); + } + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java new file mode 100644 index 0000000000..8fadf9e295 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.resetMeteredNetwork; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setupMeteredNetwork; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; +import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; + +import android.util.ArraySet; +import android.util.Pair; + +import com.android.compatibility.common.util.BeforeAfterRule; + +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +public class MeterednessConfigurationRule extends BeforeAfterRule { + private Pair mSsidAndInitialMeteredness; + + @Override + public void onBefore(Statement base, Description description) throws Throwable { + final ArraySet requiredProperties + = RequiredPropertiesRule.getRequiredProperties(); + if (requiredProperties.contains(METERED_NETWORK)) { + configureNetworkMeteredness(true); + } else if (requiredProperties.contains(NON_METERED_NETWORK)) { + configureNetworkMeteredness(false); + } + } + + @Override + public void onAfter(Statement base, Description description) throws Throwable { + resetNetworkMeteredness(); + } + + public void configureNetworkMeteredness(boolean metered) throws Exception { + mSsidAndInitialMeteredness = setupMeteredNetwork(metered); + } + + public void resetNetworkMeteredness() throws Exception { + if (mSsidAndInitialMeteredness != null) { + resetMeteredNetwork(mSsidAndInitialMeteredness.first, + mSsidAndInitialMeteredness.second); + } + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java index b1a21867b3..c9edda6e0b 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java @@ -15,9 +15,21 @@ */ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground; +import static com.android.cts.net.hostside.Property.APP_STANDBY_MODE; +import static com.android.cts.net.hostside.Property.BATTERY_SAVER_MODE; +import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE; +import static com.android.cts.net.hostside.Property.DOZE_MODE; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; +import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; + import android.os.SystemClock; import android.util.Log; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + /** * Test cases for the more complex scenarios where multiple restrictions (like Battery Saver Mode * and Data Saver Mode) are applied simultaneously. @@ -29,12 +41,10 @@ import android.util.Log; public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { private static final String TAG = "MixedModesTest"; - @Override + @Before public void setUp() throws Exception { super.setUp(); - if (!isSupported()) return; - // Set initial state. removeRestrictBackgroundWhitelist(mUid); removeRestrictBackgroundBlacklist(mUid); @@ -44,12 +54,10 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { registerBroadcastReceiver(); } - @Override - protected void tearDown() throws Exception { + @After + public void tearDown() throws Exception { super.tearDown(); - if (!isSupported()) return; - try { setRestrictBackground(false); } finally { @@ -57,34 +65,15 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } - @Override - public boolean isSupported() throws Exception { - if (!isDozeModeEnabled()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Doze Mode"); - return false; - } - return true; - } - /** * Tests all DS ON and BS ON scenarios from network-policy-restrictions.md on metered networks. */ + @RequiredProperties({DATA_SAVER_MODE, BATTERY_SAVER_MODE, METERED_NETWORK}) + @Test public void testDataAndBatterySaverModes_meteredNetwork() throws Exception { - if (!isBatterySaverSupported()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Battery saver mode"); - return; - } - if (!isSupported()) return; - - Log.i(TAG, "testDataAndBatterySaverModes_meteredNetwork() tests"); - if (!setMeteredNetwork()) { - Log.w(TAG, "testDataAndBatterySaverModes_meteredNetwork() skipped because " - + "device cannot use a metered network"); - return; - } - + final MeterednessConfigurationRule meterednessConfiguration + = new MeterednessConfigurationRule(); + meterednessConfiguration.configureNetworkMeteredness(true); try { setRestrictBackground(true); setBatterySaverMode(true); @@ -137,7 +126,7 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { removeRestrictBackgroundBlacklist(mUid); removePowerSaveModeWhitelist(TEST_APP2_PKG); } finally { - resetMeteredNetwork(); + meterednessConfiguration.resetNetworkMeteredness(); } } @@ -145,86 +134,75 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { * Tests all DS ON and BS ON scenarios from network-policy-restrictions.md on non-metered * networks. */ + @RequiredProperties({DATA_SAVER_MODE, BATTERY_SAVER_MODE, NON_METERED_NETWORK}) + @Test public void testDataAndBatterySaverModes_nonMeteredNetwork() throws Exception { - if (!isBatterySaverSupported()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Battery saver mode"); - return; + final MeterednessConfigurationRule meterednessConfiguration + = new MeterednessConfigurationRule(); + meterednessConfiguration.configureNetworkMeteredness(false); + try { + setRestrictBackground(true); + setBatterySaverMode(true); + + Log.v(TAG, "Not whitelisted for any."); + assertBackgroundNetworkAccess(false); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + + Log.v(TAG, "Whitelisted for Data Saver but not for Battery Saver."); + addRestrictBackgroundWhitelist(mUid); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + removeRestrictBackgroundWhitelist(mUid); + + Log.v(TAG, "Whitelisted for Battery Saver but not for Data Saver."); + addPowerSaveModeWhitelist(TEST_APP2_PKG); + removeRestrictBackgroundWhitelist(mUid); + assertBackgroundNetworkAccess(true); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(true); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + + Log.v(TAG, "Whitelisted for both."); + addRestrictBackgroundWhitelist(mUid); + addPowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(true); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(true); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + removeRestrictBackgroundWhitelist(mUid); + + Log.v(TAG, "Blacklisted for Data Saver, not whitelisted for Battery Saver."); + addRestrictBackgroundBlacklist(mUid); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + removeRestrictBackgroundBlacklist(mUid); + + Log.v(TAG, "Blacklisted for Data Saver, whitelisted for Battery Saver."); + addRestrictBackgroundBlacklist(mUid); + addPowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(true); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(true); + removeRestrictBackgroundBlacklist(mUid); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + } finally { + meterednessConfiguration.resetNetworkMeteredness(); } - if (!isSupported()) return; - - if (!setUnmeteredNetwork()) { - Log.w(TAG, "testDataAndBatterySaverModes_nonMeteredNetwork() skipped because network" - + " is metered"); - return; - } - Log.i(TAG, "testDataAndBatterySaverModes_nonMeteredNetwork() tests"); - setRestrictBackground(true); - setBatterySaverMode(true); - - Log.v(TAG, "Not whitelisted for any."); - assertBackgroundNetworkAccess(false); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(false); - - Log.v(TAG, "Whitelisted for Data Saver but not for Battery Saver."); - addRestrictBackgroundWhitelist(mUid); - removePowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(false); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(false); - removeRestrictBackgroundWhitelist(mUid); - - Log.v(TAG, "Whitelisted for Battery Saver but not for Data Saver."); - addPowerSaveModeWhitelist(TEST_APP2_PKG); - removeRestrictBackgroundWhitelist(mUid); - assertBackgroundNetworkAccess(true); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(true); - removePowerSaveModeWhitelist(TEST_APP2_PKG); - - Log.v(TAG, "Whitelisted for both."); - addRestrictBackgroundWhitelist(mUid); - addPowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(true); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(true); - removePowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(false); - removeRestrictBackgroundWhitelist(mUid); - - Log.v(TAG, "Blacklisted for Data Saver, not whitelisted for Battery Saver."); - addRestrictBackgroundBlacklist(mUid); - removePowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(false); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(false); - removeRestrictBackgroundBlacklist(mUid); - - Log.v(TAG, "Blacklisted for Data Saver, whitelisted for Battery Saver."); - addRestrictBackgroundBlacklist(mUid); - addPowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(true); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(true); - removeRestrictBackgroundBlacklist(mUid); - removePowerSaveModeWhitelist(TEST_APP2_PKG); } /** * Tests that powersave whitelists works as expected when doze and battery saver modes * are enabled. */ + @RequiredProperties({DOZE_MODE, BATTERY_SAVER_MODE}) + @Test public void testDozeAndBatterySaverMode_powerSaveWhitelists() throws Exception { - if (!isBatterySaverSupported()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Battery saver mode"); - return; - } - if (!isSupported()) { - return; - } - setBatterySaverMode(true); setDozeMode(true); @@ -250,11 +228,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { * Tests that powersave whitelists works as expected when doze and appIdle modes * are enabled. */ + @RequiredProperties({DOZE_MODE, APP_STANDBY_MODE}) + @Test public void testDozeAndAppIdle_powerSaveWhitelists() throws Exception { - if (!isSupported()) { - return; - } - setDozeMode(true); setAppIdle(true); @@ -276,11 +252,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } + @RequiredProperties({APP_STANDBY_MODE, DOZE_MODE}) + @Test public void testAppIdleAndDoze_tempPowerSaveWhitelists() throws Exception { - if (!isSupported()) { - return; - } - setDozeMode(true); setAppIdle(true); @@ -299,16 +273,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } + @RequiredProperties({APP_STANDBY_MODE, BATTERY_SAVER_MODE}) + @Test public void testAppIdleAndBatterySaver_tempPowerSaveWhitelists() throws Exception { - if (!isBatterySaverSupported()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Battery saver mode"); - return; - } - if (!isSupported()) { - return; - } - setBatterySaverMode(true); setAppIdle(true); @@ -330,11 +297,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { /** * Tests that the app idle whitelist works as expected when doze and appIdle mode are enabled. */ + @RequiredProperties({DOZE_MODE, APP_STANDBY_MODE}) + @Test public void testDozeAndAppIdle_appIdleWhitelist() throws Exception { - if (!isSupported()) { - return; - } - setDozeMode(true); setAppIdle(true); @@ -353,11 +318,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } + @RequiredProperties({APP_STANDBY_MODE, DOZE_MODE}) + @Test public void testAppIdleAndDoze_tempPowerSaveAndAppIdleWhitelists() throws Exception { - if (!isSupported()) { - return; - } - setDozeMode(true); setAppIdle(true); @@ -380,16 +343,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } + @RequiredProperties({APP_STANDBY_MODE, BATTERY_SAVER_MODE}) + @Test public void testAppIdleAndBatterySaver_tempPowerSaveAndAppIdleWhitelists() throws Exception { - if (!isBatterySaverSupported()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Battery saver mode"); - return; - } - if (!isSupported()) { - return; - } - setBatterySaverMode(true); setAppIdle(true); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java index 24dde9d356..ed397b91fc 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java @@ -16,15 +16,26 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground; +import static com.android.cts.net.hostside.Property.BATTERY_SAVER_MODE; +import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + import android.net.Network; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + import java.util.Objects; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCase { - private boolean mIsDataSaverSupported; private Network mNetwork; private final TestNetworkCallback mTestNetworkCallback = new TestNetworkCallback(); @@ -132,108 +143,122 @@ public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCa } } - @Override + @Before public void setUp() throws Exception { super.setUp(); - mIsDataSaverSupported = isDataSaverSupported(); - mNetwork = mCm.getActiveNetwork(); - // Set initial state. - setBatterySaverMode(false); registerBroadcastReceiver(); - if (!mIsDataSaverSupported) return; - setRestrictBackground(false); removeRestrictBackgroundWhitelist(mUid); removeRestrictBackgroundBlacklist(mUid); assertRestrictBackgroundChangedReceived(0); } - @Override - protected void tearDown() throws Exception { + @After + public void tearDown() throws Exception { super.tearDown(); - if (!mIsDataSaverSupported) return; + setRestrictBackground(false); + setBatterySaverMode(false); + } + @RequiredProperties({DATA_SAVER_MODE}) + @Test + public void testOnBlockedStatusChanged_dataSaver() throws Exception { + // Initial state + setBatterySaverMode(false); + setRestrictBackground(false); + + final MeterednessConfigurationRule meterednessConfiguration + = new MeterednessConfigurationRule(); + meterednessConfiguration.configureNetworkMeteredness(true); try { - resetMeteredNetwork(); + // Register callback + registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); + mTestNetworkCallback.expectAvailableCallback(mNetwork); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Enable restrict background + setRestrictBackground(true); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); + + // Add to whitelist + addRestrictBackgroundWhitelist(mUid); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Remove from whitelist + removeRestrictBackgroundWhitelist(mUid); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); } finally { + meterednessConfiguration.resetNetworkMeteredness(); + } + + // Set to non-metered network + meterednessConfiguration.configureNetworkMeteredness(false); + try { + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Disable restrict background, should not trigger callback setRestrictBackground(false); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.assertNoCallback(); + } finally { + meterednessConfiguration.resetNetworkMeteredness(); } } - public void testOnBlockedStatusChanged_data_saver() throws Exception { - if (!mIsDataSaverSupported) return; - - // Prepare metered wifi - if (!setMeteredNetwork()) return; - - // Register callback - registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); - mTestNetworkCallback.expectAvailableCallback(mNetwork); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - - // Enable restrict background - setRestrictBackground(true); - assertBackgroundNetworkAccess(false); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); - - // Add to whitelist - addRestrictBackgroundWhitelist(mUid); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - - // Remove from whitelist - removeRestrictBackgroundWhitelist(mUid); - assertBackgroundNetworkAccess(false); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); - - // Set to non-metered network - setUnmeteredNetwork(); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - - // Disable restrict background, should not trigger callback + @RequiredProperties({BATTERY_SAVER_MODE}) + @Test + public void testOnBlockedStatusChanged_powerSaver() throws Exception { + // Set initial state. + setBatterySaverMode(false); setRestrictBackground(false); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.assertNoCallback(); - } + final MeterednessConfigurationRule meterednessConfiguration + = new MeterednessConfigurationRule(); + meterednessConfiguration.configureNetworkMeteredness(true); + try { + // Register callback + registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); + mTestNetworkCallback.expectAvailableCallback(mNetwork); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - public void testOnBlockedStatusChanged_power_saver() throws Exception { - // Prepare metered wifi - if (!setMeteredNetwork()) return; + // Enable Power Saver + setBatterySaverMode(true); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); - // Register callback - registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); - mTestNetworkCallback.expectAvailableCallback(mNetwork); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - - // Enable Power Saver - setBatterySaverMode(true); - assertBackgroundNetworkAccess(false); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); - - // Disable Power Saver - setBatterySaverMode(false); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + // Disable Power Saver + setBatterySaverMode(false); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + } finally { + meterednessConfiguration.resetNetworkMeteredness(); + } // Set to non-metered network - setUnmeteredNetwork(); - mTestNetworkCallback.assertNoCallback(); + meterednessConfiguration.configureNetworkMeteredness(false); + try { + mTestNetworkCallback.assertNoCallback(); - // Enable Power Saver - setBatterySaverMode(true); - assertBackgroundNetworkAccess(false); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); + // Enable Power Saver + setBatterySaverMode(true); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); - // Disable Power Saver - setBatterySaverMode(false); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + // Disable Power Saver + setBatterySaverMode(false); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + } finally { + meterednessConfiguration.resetNetworkMeteredness(); + } } // TODO: 1. test against VPN lockdown. diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java new file mode 100644 index 0000000000..ca2864c0b8 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; +import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; +import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; +import static android.net.NetworkCapabilities.TRANSPORT_WIFI; + +import static com.android.compatibility.common.util.SystemUtil.runShellCommand; +import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TAG; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import android.app.ActivityManager; +import android.app.Instrumentation; +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.ConnectivityManager.NetworkCallback; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.wifi.WifiManager; +import android.text.TextUtils; +import android.util.Log; +import android.util.Pair; + +import com.android.compatibility.common.util.AppStandbyUtils; +import com.android.compatibility.common.util.BatteryUtils; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import androidx.test.platform.app.InstrumentationRegistry; + +public class NetworkPolicyTestUtils { + + private static final int TIMEOUT_CHANGE_METEREDNESS_MS = 5000; + + private static ConnectivityManager mCm; + private static WifiManager mWm; + + private static Boolean mBatterySaverSupported; + private static Boolean mDataSaverSupported; + private static Boolean mDozeModeSupported; + private static Boolean mAppStandbySupported; + + private NetworkPolicyTestUtils() {} + + public static boolean isBatterySaverSupported() { + if (mBatterySaverSupported == null) { + mBatterySaverSupported = BatteryUtils.isBatterySaverSupported(); + } + return mBatterySaverSupported; + } + + /** + * As per CDD requirements, if the device doesn't support data saver mode then + * ConnectivityManager.getRestrictBackgroundStatus() will always return + * RESTRICT_BACKGROUND_STATUS_DISABLED. So, enable the data saver mode and check if + * ConnectivityManager.getRestrictBackgroundStatus() for an app in background returns + * RESTRICT_BACKGROUND_STATUS_DISABLED or not. + */ + public static boolean isDataSaverSupported() { + if (mDataSaverSupported == null) { + assertMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + try { + setRestrictBackground(true); + mDataSaverSupported = !isMyRestrictBackgroundStatus( + RESTRICT_BACKGROUND_STATUS_DISABLED); + } finally { + setRestrictBackground(false); + } + } + return mDataSaverSupported; + } + + public static boolean isDozeModeSupported() { + if (mDozeModeSupported == null) { + final String result = executeShellCommand("cmd deviceidle enabled deep"); + mDozeModeSupported = result.equals("1"); + } + return mDozeModeSupported; + } + + public static boolean isAppStandbySupported() { + if (mAppStandbySupported == null) { + mAppStandbySupported = AppStandbyUtils.isAppStandbyEnabled(); + } + return mAppStandbySupported; + } + + public static boolean isLowRamDevice() { + final ActivityManager am = (ActivityManager) getContext().getSystemService( + Context.ACTIVITY_SERVICE); + return am.isLowRamDevice(); + } + + public static boolean isActiveNetworkMetered(boolean metered) { + return getConnectivityManager().isActiveNetworkMetered() == metered; + } + + public static boolean canChangeActiveNetworkMeteredness() { + final Network activeNetwork = getConnectivityManager().getActiveNetwork(); + final NetworkCapabilities networkCapabilities + = getConnectivityManager().getNetworkCapabilities(activeNetwork); + return networkCapabilities.hasTransport(TRANSPORT_WIFI); + } + + public static Pair setupMeteredNetwork(boolean metered) throws Exception { + if (isActiveNetworkMetered(metered)) { + return null; + } + final String ssid = unquoteSSID(getWifiManager().getConnectionInfo().getSSID()); + setWifiMeteredStatus(ssid, metered); + return Pair.create(ssid, !metered); + } + + public static void resetMeteredNetwork(String ssid, boolean metered) throws Exception { + setWifiMeteredStatus(ssid, metered); + } + + public static void setWifiMeteredStatus(String ssid, boolean metered) throws Exception { + assertFalse("SSID should not be empty", TextUtils.isEmpty(ssid)); + final String cmd = "cmd netpolicy set metered-network " + ssid + " " + metered; + executeShellCommand(cmd); + assertWifiMeteredStatus(ssid, metered); + assertActiveNetworkMetered(metered); + } + + public static void assertWifiMeteredStatus(String ssid, boolean expectedMeteredStatus) { + final String result = executeShellCommand("cmd netpolicy list wifi-networks"); + final String expectedLine = ssid + ";" + expectedMeteredStatus; + assertTrue("Expected line: " + expectedLine + "; Actual result: " + result, + result.contains(expectedLine)); + } + + // Copied from cts/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java + public static void assertActiveNetworkMetered(boolean expectedMeteredStatus) throws Exception { + final CountDownLatch latch = new CountDownLatch(1); + final NetworkCallback networkCallback = new NetworkCallback() { + @Override + public void onCapabilitiesChanged(Network network, NetworkCapabilities nc) { + final boolean metered = !nc.hasCapability(NET_CAPABILITY_NOT_METERED); + if (metered == expectedMeteredStatus) { + latch.countDown(); + } + } + }; + // Registering a callback here guarantees onCapabilitiesChanged is called immediately + // with the current setting. Therefore, if the setting has already been changed, + // this method will return right away, and if not it will wait for the setting to change. + getConnectivityManager().registerDefaultNetworkCallback(networkCallback); + if (!latch.await(TIMEOUT_CHANGE_METEREDNESS_MS, TimeUnit.MILLISECONDS)) { + fail("Timed out waiting for active network metered status to change to " + + expectedMeteredStatus + " ; network = " + + getConnectivityManager().getActiveNetwork()); + } + getConnectivityManager().unregisterNetworkCallback(networkCallback); + } + + public static void setRestrictBackground(boolean enabled) { + executeShellCommand("cmd netpolicy set restrict-background " + enabled); + final String output = executeShellCommand("cmd netpolicy get restrict-background"); + final String expectedSuffix = enabled ? "enabled" : "disabled"; + assertTrue("output '" + output + "' should end with '" + expectedSuffix + "'", + output.endsWith(expectedSuffix)); + } + + public static boolean isMyRestrictBackgroundStatus(int expectedStatus) { + final int actualStatus = getConnectivityManager().getRestrictBackgroundStatus(); + if (expectedStatus != actualStatus) { + Log.d(TAG, "MyRestrictBackgroundStatus: " + + "Expected: " + restrictBackgroundValueToString(expectedStatus) + + "; Actual: " + restrictBackgroundValueToString(actualStatus)); + return false; + } + return true; + } + + // Copied from cts/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java + private static String unquoteSSID(String ssid) { + // SSID is returned surrounded by quotes if it can be decoded as UTF-8. + // Otherwise it's guaranteed not to start with a quote. + if (ssid.charAt(0) == '"') { + return ssid.substring(1, ssid.length() - 1); + } else { + return ssid; + } + } + + public static String restrictBackgroundValueToString(int status) { + switch (status) { + case RESTRICT_BACKGROUND_STATUS_DISABLED: + return "DISABLED"; + case RESTRICT_BACKGROUND_STATUS_WHITELISTED: + return "WHITELISTED"; + case RESTRICT_BACKGROUND_STATUS_ENABLED: + return "ENABLED"; + default: + return "UNKNOWN_STATUS_" + status; + } + } + + public static String executeShellCommand(String command) { + final String result = runShellCommand(command).trim(); + Log.d(TAG, "Output of '" + command + "': '" + result + "'"); + return result; + } + + public static void assertMyRestrictBackgroundStatus(int expectedStatus) { + final int actualStatus = getConnectivityManager().getRestrictBackgroundStatus(); + assertEquals(restrictBackgroundValueToString(expectedStatus), + restrictBackgroundValueToString(actualStatus)); + } + + public static ConnectivityManager getConnectivityManager() { + if (mCm == null) { + mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); + } + return mCm; + } + + public static WifiManager getWifiManager() { + if (mWm == null) { + mWm = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); + } + return mWm; + } + + public static Context getContext() { + return getInstrumentation().getContext(); + } + + public static Instrumentation getInstrumentation() { + return InstrumentationRegistry.getInstrumentation(); + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/Property.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/Property.java new file mode 100644 index 0000000000..18805f9613 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/Property.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.canChangeActiveNetworkMeteredness; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isActiveNetworkMetered; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isAppStandbySupported; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isBatterySaverSupported; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isDataSaverSupported; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isDozeModeSupported; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isLowRamDevice; + +public enum Property { + BATTERY_SAVER_MODE(1 << 0) { + public boolean isSupported() { return isBatterySaverSupported(); } + }, + + DATA_SAVER_MODE(1 << 1) { + public boolean isSupported() { return isDataSaverSupported(); } + }, + + NO_DATA_SAVER_MODE(~DATA_SAVER_MODE.getValue()) { + public boolean isSupported() { return !isDataSaverSupported(); } + }, + + DOZE_MODE(1 << 2) { + public boolean isSupported() { return isDozeModeSupported(); } + }, + + APP_STANDBY_MODE(1 << 3) { + public boolean isSupported() { return isAppStandbySupported(); } + }, + + NOT_LOW_RAM_DEVICE(1 << 4) { + public boolean isSupported() { return !isLowRamDevice(); } + }, + + METERED_NETWORK(1 << 5) { + public boolean isSupported() { + return isActiveNetworkMetered(true) || canChangeActiveNetworkMeteredness(); + } + }, + + NON_METERED_NETWORK(~METERED_NETWORK.getValue()) { + public boolean isSupported() { + return isActiveNetworkMetered(false) || canChangeActiveNetworkMeteredness(); + } + }; + + private int mValue; + + Property(int value) { mValue = value; } + + public int getValue() { return mValue; } + + abstract boolean isSupported(); +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredProperties.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredProperties.java new file mode 100644 index 0000000000..96838bba0a --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredProperties.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(RUNTIME) +@Target({METHOD, TYPE}) +@Inherited +public @interface RequiredProperties { + Property[] value(); +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java new file mode 100644 index 0000000000..1e333200db --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TAG; + +import android.text.TextUtils; +import android.util.ArraySet; +import android.util.Log; + +import com.android.compatibility.common.util.BeforeAfterRule; + +import org.junit.Assume; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import java.util.ArrayList; +import java.util.Collections; + +public class RequiredPropertiesRule extends BeforeAfterRule { + + private static ArraySet mRequiredProperties; + + @Override + public void onBefore(Statement base, Description description) { + mRequiredProperties = getAllRequiredProperties(description); + + final String testName = description.getClassName() + "#" + description.getMethodName(); + assertTestIsValid(testName, mRequiredProperties); + Log.i(TAG, "Running test " + testName + " with required properties: " + + propertiesToString(mRequiredProperties)); + } + + private ArraySet getAllRequiredProperties(Description description) { + final ArraySet allRequiredProperties = new ArraySet<>(); + RequiredProperties requiredProperties = description.getAnnotation(RequiredProperties.class); + if (requiredProperties != null) { + Collections.addAll(allRequiredProperties, requiredProperties.value()); + } + + for (Class clazz = description.getTestClass(); + clazz != null; clazz = clazz.getSuperclass()) { + requiredProperties = clazz.getDeclaredAnnotation(RequiredProperties.class); + if (requiredProperties == null) { + continue; + } + for (Property requiredProperty : requiredProperties.value()) { + if (!allRequiredProperties.contains(~requiredProperty.getValue())) { + allRequiredProperties.add(requiredProperty); + } + } + } + return allRequiredProperties; + } + + private void assertTestIsValid(String testName, ArraySet requiredProperies) { + if (requiredProperies == null) { + return; + } + final ArrayList unsupportedProperties = new ArrayList<>(); + for (Property property : requiredProperies) { + if (!property.isSupported()) { + unsupportedProperties.add(property); + } + } + Assume.assumeTrue("Unsupported properties: " + + propertiesToString(unsupportedProperties), unsupportedProperties.isEmpty()); + } + + public static ArraySet getRequiredProperties() { + return mRequiredProperties; + } + + private static String propertiesToString(Iterable properties) { + return "[" + TextUtils.join(",", properties) + "]"; + } +} diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java index 8d6c4acd7d..1312085478 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java @@ -29,14 +29,14 @@ public class HostsideNetworkCallbackTests extends HostsideNetworkTestCase { uninstallPackage(TEST_APP2_PKG, true); } - public void testOnBlockedStatusChanged_data_saver() throws Exception { + public void testOnBlockedStatusChanged_dataSaver() throws Exception { runDeviceTests(TEST_PKG, - TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_data_saver"); + TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_dataSaver"); } - public void testOnBlockedStatusChanged_power_saver() throws Exception { + public void testOnBlockedStatusChanged_powerSaver() throws Exception { runDeviceTests(TEST_PKG, - TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_power_saver"); + TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_powerSaver"); } } diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java index a2443b391a..ce203795f9 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java @@ -79,7 +79,8 @@ abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiRec protected void installPackage(String apk) throws FileNotFoundException, DeviceNotAvailableException { CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild); - assertNull(getDevice().installPackage(buildHelper.getTestFile(apk), false)); + assertNull(getDevice().installPackage(buildHelper.getTestFile(apk), + false /* reinstall */, true /* grantPermissions */)); } protected void uninstallPackage(String packageName, boolean shouldSucceed) From 39cc315273a2216e5947a1dd856b04dd8b67beb4 Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Wed, 22 Apr 2020 13:50:15 -0700 Subject: [PATCH 0910/1109] Fix Error Prone errors Soong wasn't including android_app or android_test sources in the javac-check target used for the Error Prone build, which allowed some Error Prone errors to get in. Fix them so Error Prone can be re-enabled for these targets. Fixes: cts/hostsidetests/net/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java:61: error: [CollectionIncompatibleType] Argument '~requiredProperty.getValue()' should not be passed to this method; its type int is not compatible with its collection's type argument Property Bug: 146455923 Test: m RUN_ERROR_PRONE=true javac-check Change-Id: I7c5bf823bf371902285ce3ee3929796fa40c653b Merged-In: I48b1ccb61c807d0b41a165298ef5981258d6656e --- .../android/cts/net/hostside/RequiredPropertiesRule.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java index 1e333200db..98c97c5687 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java @@ -58,8 +58,12 @@ public class RequiredPropertiesRule extends BeforeAfterRule { continue; } for (Property requiredProperty : requiredProperties.value()) { - if (!allRequiredProperties.contains(~requiredProperty.getValue())) { - allRequiredProperties.add(requiredProperty); + for (Property p : Property.values()) { + if (p.getValue() == ~requiredProperty.getValue()) { + if (!allRequiredProperties.contains(p)) { + allRequiredProperties.add(requiredProperty); + } + } } } } From a6a1ad183ed2158ec3e11fa3177db79805e6f0fa Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Wed, 5 Feb 2020 17:54:01 -0800 Subject: [PATCH 0911/1109] Fix a regression in how required properties are collected. + Enable app standby mode before running the tests. Fixes: 147459100 Fixes: 117169751 Test: atest hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java Test: cts-tradefed run singleCommand cts-on-gsi --skip-device-info \ --skip-preconditions -m CtsHostsideNetworkTests \ -t com.android.cts.net.HostsideRestrictBackgroundNetworkTests Change-Id: I782f8a06922622d28f9a9d5c9f2afa2b12f8aa80 Merged-In: I782f8a06922622d28f9a9d5c9f2afa2b12f8aa80 --- tests/cts/hostside/AndroidTest.xml | 1 + .../net/hostside/RequiredPropertiesRule.java | 8 +-- .../cts/net/NetworkPolicyTestsPreparer.java | 59 +++++++++++++++++++ 3 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 tests/cts/hostside/src/com/android/cts/net/NetworkPolicyTestsPreparer.java diff --git a/tests/cts/hostside/AndroidTest.xml b/tests/cts/hostside/AndroidTest.xml index 5479c51a4c..d4f30e0cf3 100644 --- a/tests/cts/hostside/AndroidTest.xml +++ b/tests/cts/hostside/AndroidTest.xml @@ -21,6 +21,7 @@

    TODO(b/148689509): Statically include the PacketUtils source file instead of copying it. + */ +public class PacketUtils { + private static final String TAG = PacketUtils.class.getSimpleName(); + + private static final int DATA_BUFFER_LEN = 4096; + + static final int IP4_HDRLEN = 20; + static final int IP6_HDRLEN = 40; + static final int UDP_HDRLEN = 8; + static final int TCP_HDRLEN = 20; + static final int TCP_HDRLEN_WITH_TIMESTAMP_OPT = TCP_HDRLEN + 12; + + // Not defined in OsConstants + static final int IPPROTO_IPV4 = 4; + static final int IPPROTO_ESP = 50; + + // Encryption parameters + static final int AES_GCM_IV_LEN = 8; + static final int AES_CBC_IV_LEN = 16; + static final int AES_GCM_BLK_SIZE = 4; + static final int AES_CBC_BLK_SIZE = 16; + + // Encryption algorithms + static final String AES = "AES"; + static final String AES_CBC = "AES/CBC/NoPadding"; + static final String HMAC_SHA_256 = "HmacSHA256"; + + public interface Payload { + byte[] getPacketBytes(IpHeader header) throws Exception; + + void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) throws Exception; + + short length(); + + int getProtocolId(); + } + + public abstract static class IpHeader { + + public final byte proto; + public final InetAddress srcAddr; + public final InetAddress dstAddr; + public final Payload payload; + + public IpHeader(int proto, InetAddress src, InetAddress dst, Payload payload) { + this.proto = (byte) proto; + this.srcAddr = src; + this.dstAddr = dst; + this.payload = payload; + } + + public abstract byte[] getPacketBytes() throws Exception; + + public abstract int getProtocolId(); + } + + public static class Ip4Header extends IpHeader { + private short checksum; + + public Ip4Header(int proto, Inet4Address src, Inet4Address dst, Payload payload) { + super(proto, src, dst, payload); + } + + public byte[] getPacketBytes() throws Exception { + ByteBuffer resultBuffer = buildHeader(); + payload.addPacketBytes(this, resultBuffer); + + return getByteArrayFromBuffer(resultBuffer); + } + + public ByteBuffer buildHeader() { + ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN); + + // Version, IHL + bb.put((byte) (0x45)); + + // DCSP, ECN + bb.put((byte) 0); + + // Total Length + bb.putShort((short) (IP4_HDRLEN + payload.length())); + + // Empty for Identification, Flags and Fragment Offset + bb.putShort((short) 0); + bb.put((byte) 0x40); + bb.put((byte) 0x00); + + // TTL + bb.put((byte) 64); + + // Protocol + bb.put(proto); + + // Header Checksum + final int ipChecksumOffset = bb.position(); + bb.putShort((short) 0); + + // Src/Dst addresses + bb.put(srcAddr.getAddress()); + bb.put(dstAddr.getAddress()); + + bb.putShort(ipChecksumOffset, calculateChecksum(bb)); + + return bb; + } + + private short calculateChecksum(ByteBuffer bb) { + int checksum = 0; + + // Calculate sum of 16-bit values, excluding checksum. IPv4 headers are always 32-bit + // aligned, so no special cases needed for unaligned values. + ShortBuffer shortBuffer = ByteBuffer.wrap(getByteArrayFromBuffer(bb)).asShortBuffer(); + while (shortBuffer.hasRemaining()) { + short val = shortBuffer.get(); + + // Wrap as needed + checksum = addAndWrapForChecksum(checksum, val); + } + + return onesComplement(checksum); + } + + public int getProtocolId() { + return IPPROTO_IPV4; + } + } + + public static class Ip6Header extends IpHeader { + public Ip6Header(int nextHeader, Inet6Address src, Inet6Address dst, Payload payload) { + super(nextHeader, src, dst, payload); + } + + public byte[] getPacketBytes() throws Exception { + ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN); + + // Version | Traffic Class (First 4 bits) + bb.put((byte) 0x60); + + // Traffic class (Last 4 bits), Flow Label + bb.put((byte) 0); + bb.put((byte) 0); + bb.put((byte) 0); + + // Payload Length + bb.putShort((short) payload.length()); + + // Next Header + bb.put(proto); + + // Hop Limit + bb.put((byte) 64); + + // Src/Dst addresses + bb.put(srcAddr.getAddress()); + bb.put(dstAddr.getAddress()); + + // Payload + payload.addPacketBytes(this, bb); + + return getByteArrayFromBuffer(bb); + } + + public int getProtocolId() { + return IPPROTO_IPV6; + } + } + + public static class BytePayload implements Payload { + public final byte[] payload; + + public BytePayload(byte[] payload) { + this.payload = payload; + } + + public int getProtocolId() { + return -1; + } + + public byte[] getPacketBytes(IpHeader header) { + ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN); + + addPacketBytes(header, bb); + return getByteArrayFromBuffer(bb); + } + + public void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) { + resultBuffer.put(payload); + } + + public short length() { + return (short) payload.length; + } + } + + public static class UdpHeader implements Payload { + + public final short srcPort; + public final short dstPort; + public final Payload payload; + + public UdpHeader(int srcPort, int dstPort, Payload payload) { + this.srcPort = (short) srcPort; + this.dstPort = (short) dstPort; + this.payload = payload; + } + + public int getProtocolId() { + return IPPROTO_UDP; + } + + public short length() { + return (short) (payload.length() + 8); + } + + public byte[] getPacketBytes(IpHeader header) throws Exception { + ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN); + + addPacketBytes(header, bb); + return getByteArrayFromBuffer(bb); + } + + public void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) throws Exception { + // Source, Destination port + resultBuffer.putShort(srcPort); + resultBuffer.putShort(dstPort); + + // Payload Length + resultBuffer.putShort(length()); + + // Get payload bytes for checksum + payload + ByteBuffer payloadBuffer = ByteBuffer.allocate(DATA_BUFFER_LEN); + payload.addPacketBytes(header, payloadBuffer); + byte[] payloadBytes = getByteArrayFromBuffer(payloadBuffer); + + // Checksum + resultBuffer.putShort(calculateChecksum(header, payloadBytes)); + + // Payload + resultBuffer.put(payloadBytes); + } + + private short calculateChecksum(IpHeader header, byte[] payloadBytes) throws Exception { + int newChecksum = 0; + ShortBuffer srcBuffer = ByteBuffer.wrap(header.srcAddr.getAddress()).asShortBuffer(); + ShortBuffer dstBuffer = ByteBuffer.wrap(header.dstAddr.getAddress()).asShortBuffer(); + + while (srcBuffer.hasRemaining() || dstBuffer.hasRemaining()) { + short val = srcBuffer.hasRemaining() ? srcBuffer.get() : dstBuffer.get(); + + // Wrap as needed + newChecksum = addAndWrapForChecksum(newChecksum, val); + } + + // Add pseudo-header values. Proto is 0-padded, so just use the byte. + newChecksum = addAndWrapForChecksum(newChecksum, header.proto); + newChecksum = addAndWrapForChecksum(newChecksum, length()); + newChecksum = addAndWrapForChecksum(newChecksum, srcPort); + newChecksum = addAndWrapForChecksum(newChecksum, dstPort); + newChecksum = addAndWrapForChecksum(newChecksum, length()); + + ShortBuffer payloadShortBuffer = ByteBuffer.wrap(payloadBytes).asShortBuffer(); + while (payloadShortBuffer.hasRemaining()) { + newChecksum = addAndWrapForChecksum(newChecksum, payloadShortBuffer.get()); + } + if (payload.length() % 2 != 0) { + newChecksum = + addAndWrapForChecksum( + newChecksum, (payloadBytes[payloadBytes.length - 1] << 8)); + } + + return onesComplement(newChecksum); + } + } + + public static class EspHeader implements Payload { + public final int nextHeader; + public final int spi; + public final int seqNum; + public final byte[] key; + public final byte[] payload; + + /** + * Generic constructor for ESP headers. + * + *

    For Tunnel mode, payload will be a full IP header + attached payloads + * + *

    For Transport mode, payload will be only the attached payloads, but with the checksum + * calculated using the pre-encryption IP header + */ + public EspHeader(int nextHeader, int spi, int seqNum, byte[] key, byte[] payload) { + this.nextHeader = nextHeader; + this.spi = spi; + this.seqNum = seqNum; + this.key = key; + this.payload = payload; + } + + public int getProtocolId() { + return IPPROTO_ESP; + } + + public short length() { + // ALWAYS uses AES-CBC, HMAC-SHA256 (128b trunc len) + return (short) + calculateEspPacketSize(payload.length, AES_CBC_IV_LEN, AES_CBC_BLK_SIZE, 128); + } + + public byte[] getPacketBytes(IpHeader header) throws Exception { + ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN); + + addPacketBytes(header, bb); + return getByteArrayFromBuffer(bb); + } + + public void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) throws Exception { + ByteBuffer espPayloadBuffer = ByteBuffer.allocate(DATA_BUFFER_LEN); + espPayloadBuffer.putInt(spi); + espPayloadBuffer.putInt(seqNum); + espPayloadBuffer.put(getCiphertext(key)); + + espPayloadBuffer.put(getIcv(getByteArrayFromBuffer(espPayloadBuffer)), 0, 16); + resultBuffer.put(getByteArrayFromBuffer(espPayloadBuffer)); + } + + private byte[] getIcv(byte[] authenticatedSection) throws GeneralSecurityException { + Mac sha256HMAC = Mac.getInstance(HMAC_SHA_256); + SecretKeySpec authKey = new SecretKeySpec(key, HMAC_SHA_256); + sha256HMAC.init(authKey); + + return sha256HMAC.doFinal(authenticatedSection); + } + + /** + * Encrypts and builds ciphertext block. Includes the IV, Padding and Next-Header blocks + * + *

    The ciphertext does NOT include the SPI/Sequence numbers, or the ICV. + */ + private byte[] getCiphertext(byte[] key) throws GeneralSecurityException { + int paddedLen = calculateEspEncryptedLength(payload.length, AES_CBC_BLK_SIZE); + ByteBuffer paddedPayload = ByteBuffer.allocate(paddedLen); + paddedPayload.put(payload); + + // Add padding - consecutive integers from 0x01 + int pad = 1; + while (paddedPayload.position() < paddedPayload.limit()) { + paddedPayload.put((byte) pad++); + } + + paddedPayload.position(paddedPayload.limit() - 2); + paddedPayload.put((byte) (paddedLen - 2 - payload.length)); // Pad length + paddedPayload.put((byte) nextHeader); + + // Generate Initialization Vector + byte[] iv = new byte[AES_CBC_IV_LEN]; + new SecureRandom().nextBytes(iv); + IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); + SecretKeySpec secretKeySpec = new SecretKeySpec(key, AES); + + // Encrypt payload + Cipher cipher = Cipher.getInstance(AES_CBC); + cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); + byte[] encrypted = cipher.doFinal(getByteArrayFromBuffer(paddedPayload)); + + // Build ciphertext + ByteBuffer cipherText = ByteBuffer.allocate(AES_CBC_IV_LEN + encrypted.length); + cipherText.put(iv); + cipherText.put(encrypted); + + return getByteArrayFromBuffer(cipherText); + } + } + + private static int addAndWrapForChecksum(int currentChecksum, int value) { + currentChecksum += value & 0x0000ffff; + + // Wrap anything beyond the first 16 bits, and add to lower order bits + return (currentChecksum >>> 16) + (currentChecksum & 0x0000ffff); + } + + private static short onesComplement(int val) { + val = (val >>> 16) + (val & 0xffff); + + if (val == 0) return 0; + return (short) ((~val) & 0xffff); + } + + public static int calculateEspPacketSize( + int payloadLen, int cryptIvLength, int cryptBlockSize, int authTruncLen) { + final int ESP_HDRLEN = 4 + 4; // SPI + Seq# + final int ICV_LEN = authTruncLen / 8; // Auth trailer; based on truncation length + payloadLen += cryptIvLength; // Initialization Vector + + // Align to block size of encryption algorithm + payloadLen = calculateEspEncryptedLength(payloadLen, cryptBlockSize); + return payloadLen + ESP_HDRLEN + ICV_LEN; + } + + private static int calculateEspEncryptedLength(int payloadLen, int cryptBlockSize) { + payloadLen += 2; // ESP trailer + + // Align to block size of encryption algorithm + return payloadLen + calculateEspPadLen(payloadLen, cryptBlockSize); + } + + private static int calculateEspPadLen(int payloadLen, int cryptBlockSize) { + return (cryptBlockSize - (payloadLen % cryptBlockSize)) % cryptBlockSize; + } + + private static byte[] getByteArrayFromBuffer(ByteBuffer buffer) { + return Arrays.copyOfRange(buffer.array(), 0, buffer.position()); + } + + /* + * Debug printing + */ + private static final char[] hexArray = "0123456789ABCDEF".toCharArray(); + + public static String bytesToHex(byte[] bytes) { + StringBuilder sb = new StringBuilder(); + for (byte b : bytes) { + sb.append(hexArray[b >>> 4]); + sb.append(hexArray[b & 0x0F]); + sb.append(' '); + } + return sb.toString(); + } +} diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TunUtils.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TunUtils.java new file mode 100644 index 0000000000..71450ea9c0 --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TunUtils.java @@ -0,0 +1,264 @@ +/* + * 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.ipsec.ike.cts; + +import static android.net.ipsec.ike.cts.PacketUtils.IP4_HDRLEN; +import static android.net.ipsec.ike.cts.PacketUtils.IP6_HDRLEN; +import static android.net.ipsec.ike.cts.PacketUtils.IPPROTO_ESP; +import static android.net.ipsec.ike.cts.PacketUtils.UDP_HDRLEN; +import static android.system.OsConstants.IPPROTO_UDP; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.fail; + +import android.os.ParcelFileDescriptor; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.function.Predicate; + +/** + * This code is a exact copy of {@link TunUtils} in + * cts/tests/tests/net/src/android/net/cts/TunUtils.java, except the import path of PacketUtils is + * the path to the copy of PacktUtils. + * + *

    TODO(b/148689509): Statically include the TunUtils source file instead of copying it. + */ +public class TunUtils { + private static final String TAG = TunUtils.class.getSimpleName(); + + private static final int DATA_BUFFER_LEN = 4096; + private static final int TIMEOUT = 100; + + private static final int IP4_PROTO_OFFSET = 9; + private static final int IP6_PROTO_OFFSET = 6; + + private static final int IP4_ADDR_OFFSET = 12; + private static final int IP4_ADDR_LEN = 4; + private static final int IP6_ADDR_OFFSET = 8; + private static final int IP6_ADDR_LEN = 16; + + private final ParcelFileDescriptor mTunFd; + private final List mPackets = new ArrayList<>(); + private final Thread mReaderThread; + + public TunUtils(ParcelFileDescriptor tunFd) { + mTunFd = tunFd; + + // Start background reader thread + mReaderThread = + new Thread( + () -> { + try { + // Loop will exit and thread will quit when tunFd is closed. + // Receiving either EOF or an exception will exit this reader loop. + // FileInputStream in uninterruptable, so there's no good way to + // ensure that this thread shuts down except upon FD closure. + while (true) { + byte[] intercepted = receiveFromTun(); + if (intercepted == null) { + // Exit once we've hit EOF + return; + } else if (intercepted.length > 0) { + // Only save packet if we've received any bytes. + synchronized (mPackets) { + mPackets.add(intercepted); + mPackets.notifyAll(); + } + } + } + } catch (IOException ignored) { + // Simply exit this reader thread + return; + } + }); + mReaderThread.start(); + } + + private byte[] receiveFromTun() throws IOException { + FileInputStream in = new FileInputStream(mTunFd.getFileDescriptor()); + byte[] inBytes = new byte[DATA_BUFFER_LEN]; + int bytesRead = in.read(inBytes); + + if (bytesRead < 0) { + return null; // return null for EOF + } else if (bytesRead >= DATA_BUFFER_LEN) { + throw new IllegalStateException("Too big packet. Fragmentation unsupported"); + } + return Arrays.copyOf(inBytes, bytesRead); + } + + private byte[] getFirstMatchingPacket(Predicate verifier, int startIndex) { + synchronized (mPackets) { + for (int i = startIndex; i < mPackets.size(); i++) { + byte[] pkt = mPackets.get(i); + if (verifier.test(pkt)) { + return pkt; + } + } + } + return null; + } + + /** + * Checks if the specified bytes were ever sent in plaintext. + * + *

    Only checks for known plaintext bytes to prevent triggering on ICMP/RA packets or the like + * + * @param plaintext the plaintext bytes to check for + * @param startIndex the index in the list to check for + */ + public boolean hasPlaintextPacket(byte[] plaintext, int startIndex) { + Predicate verifier = + (pkt) -> { + return Collections.indexOfSubList(Arrays.asList(pkt), Arrays.asList(plaintext)) + != -1; + }; + return getFirstMatchingPacket(verifier, startIndex) != null; + } + + public byte[] getEspPacket(int spi, boolean encap, int startIndex) { + return getFirstMatchingPacket( + (pkt) -> { + return isEsp(pkt, spi, encap); + }, + startIndex); + } + + public byte[] awaitEspPacketNoPlaintext( + int spi, byte[] plaintext, boolean useEncap, int expectedPacketSize) throws Exception { + long endTime = System.currentTimeMillis() + TIMEOUT; + int startIndex = 0; + + synchronized (mPackets) { + while (System.currentTimeMillis() < endTime) { + byte[] espPkt = getEspPacket(spi, useEncap, startIndex); + if (espPkt != null) { + // Validate packet size + assertEquals(expectedPacketSize, espPkt.length); + + // Always check plaintext from start + assertFalse(hasPlaintextPacket(plaintext, 0)); + return espPkt; // We've found the packet we're looking for. + } + + startIndex = mPackets.size(); + + // Try to prevent waiting too long. If waitTimeout <= 0, we've already hit timeout + long waitTimeout = endTime - System.currentTimeMillis(); + if (waitTimeout > 0) { + mPackets.wait(waitTimeout); + } + } + + fail("No such ESP packet found with SPI " + spi); + } + return null; + } + + private static boolean isSpiEqual(byte[] pkt, int espOffset, int spi) { + // Check SPI byte by byte. + return pkt[espOffset] == (byte) ((spi >>> 24) & 0xff) + && pkt[espOffset + 1] == (byte) ((spi >>> 16) & 0xff) + && pkt[espOffset + 2] == (byte) ((spi >>> 8) & 0xff) + && pkt[espOffset + 3] == (byte) (spi & 0xff); + } + + private static boolean isEsp(byte[] pkt, int spi, boolean encap) { + if (isIpv6(pkt)) { + // IPv6 UDP encap not supported by kernels; assume non-encap. + return pkt[IP6_PROTO_OFFSET] == IPPROTO_ESP && isSpiEqual(pkt, IP6_HDRLEN, spi); + } else { + // Use default IPv4 header length (assuming no options) + if (encap) { + return pkt[IP4_PROTO_OFFSET] == IPPROTO_UDP + && isSpiEqual(pkt, IP4_HDRLEN + UDP_HDRLEN, spi); + } else { + return pkt[IP4_PROTO_OFFSET] == IPPROTO_ESP && isSpiEqual(pkt, IP4_HDRLEN, spi); + } + } + } + + private static boolean isIpv6(byte[] pkt) { + // First nibble shows IP version. 0x60 for IPv6 + return (pkt[0] & (byte) 0xF0) == (byte) 0x60; + } + + private static byte[] getReflectedPacket(byte[] pkt) { + byte[] reflected = Arrays.copyOf(pkt, pkt.length); + + if (isIpv6(pkt)) { + // Set reflected packet's dst to that of the original's src + System.arraycopy( + pkt, // src + IP6_ADDR_OFFSET + IP6_ADDR_LEN, // src offset + reflected, // dst + IP6_ADDR_OFFSET, // dst offset + IP6_ADDR_LEN); // len + // Set reflected packet's src IP to that of the original's dst IP + System.arraycopy( + pkt, // src + IP6_ADDR_OFFSET, // src offset + reflected, // dst + IP6_ADDR_OFFSET + IP6_ADDR_LEN, // dst offset + IP6_ADDR_LEN); // len + } else { + // Set reflected packet's dst to that of the original's src + System.arraycopy( + pkt, // src + IP4_ADDR_OFFSET + IP4_ADDR_LEN, // src offset + reflected, // dst + IP4_ADDR_OFFSET, // dst offset + IP4_ADDR_LEN); // len + // Set reflected packet's src IP to that of the original's dst IP + System.arraycopy( + pkt, // src + IP4_ADDR_OFFSET, // src offset + reflected, // dst + IP4_ADDR_OFFSET + IP4_ADDR_LEN, // dst offset + IP4_ADDR_LEN); // len + } + return reflected; + } + + /** Takes all captured packets, flips the src/dst, and re-injects them. */ + public void reflectPackets() throws IOException { + synchronized (mPackets) { + for (byte[] pkt : mPackets) { + injectPacket(getReflectedPacket(pkt)); + } + } + } + + public void injectPacket(byte[] pkt) throws IOException { + FileOutputStream out = new FileOutputStream(mTunFd.getFileDescriptor()); + out.write(pkt); + out.flush(); + } + + /** Resets the intercepted packets. */ + public void reset() throws IOException { + synchronized (mPackets) { + mPackets.clear(); + } + } +} From f46d6a1e8d1d059d2b6597ab100786f179e5dafd Mon Sep 17 00:00:00 2001 From: Mark Chien Date: Thu, 23 Apr 2020 13:28:22 +0000 Subject: [PATCH 0917/1109] Test enable tethering permission and stopAllTethering 1. Test whether start tethering is gated by suitable permission. 2. Test stopAllTethering Bug: 153613718 Test: atest CtsTetheringTest Merged-In: I38702886ea355e1aec8eb8ac404fdd46a44582e3 Change-Id: I38702886ea355e1aec8eb8ac404fdd46a44582e3 --- tests/cts/tethering/Android.bp | 1 + .../tethering/cts/TetheringManagerTest.java | 274 ++++++++++++------ 2 files changed, 189 insertions(+), 86 deletions(-) diff --git a/tests/cts/tethering/Android.bp b/tests/cts/tethering/Android.bp index 37894ec4dc..9f32403c98 100644 --- a/tests/cts/tethering/Android.bp +++ b/tests/cts/tethering/Android.bp @@ -28,6 +28,7 @@ android_test { "TetheringCommonTests", "TetheringIntegrationTestsLib", "compatibility-device-util-axt", + "net-tests-utils", "ctstestrunner-axt", "junit", "junit-params", diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java index ccad14cdd2..60f9400363 100644 --- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java +++ b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java @@ -15,20 +15,24 @@ */ package android.tethering.test; -import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED; -import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED; -import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED; import static android.net.TetheringManager.TETHERING_USB; import static android.net.TetheringManager.TETHERING_WIFI; import static android.net.TetheringManager.TETHERING_WIFI_P2P; import static android.net.TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN; +import static android.net.TetheringManager.TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION; +import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR; +import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED; +import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED; +import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import android.app.UiAutomation; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -48,6 +52,8 @@ import androidx.annotation.NonNull; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; +import com.android.testutils.ArrayTrackRecord; + import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -77,11 +83,21 @@ public class TetheringManagerTest { private static final int DEFAULT_TIMEOUT_MS = 60_000; + private void adoptShellPermissionIdentity() { + final UiAutomation uiAutomation = + InstrumentationRegistry.getInstrumentation().getUiAutomation(); + uiAutomation.adoptShellPermissionIdentity(); + } + + private void dropShellPermissionIdentity() { + final UiAutomation uiAutomation = + InstrumentationRegistry.getInstrumentation().getUiAutomation(); + uiAutomation.dropShellPermissionIdentity(); + } + @Before public void setUp() throws Exception { - InstrumentationRegistry.getInstrumentation() - .getUiAutomation() - .adoptShellPermissionIdentity(); + adoptShellPermissionIdentity(); mContext = InstrumentationRegistry.getContext(); mTM = (TetheringManager) mContext.getSystemService(Context.TETHERING_SERVICE); mTetherChangeReceiver = new TetherChangeReceiver(); @@ -93,10 +109,9 @@ public class TetheringManagerTest { @After public void tearDown() throws Exception { + mTM.stopAllTethering(); mContext.unregisterReceiver(mTetherChangeReceiver); - InstrumentationRegistry.getInstrumentation() - .getUiAutomation() - .dropShellPermissionIdentity(); + dropShellPermissionIdentity(); } private class TetherChangeReceiver extends BroadcastReceiver { @@ -202,15 +217,54 @@ public class TetheringManagerTest { } } - private class StartTetheringCallback implements TetheringManager.StartTetheringCallback { + private static class StartTetheringCallback implements TetheringManager.StartTetheringCallback { + private static int TIMEOUT_MS = 30_000; + public static class CallbackValue { + public final int error; + + private CallbackValue(final int e) { + error = e; + } + + public static class OnTetheringStarted extends CallbackValue { + OnTetheringStarted() { super(TETHER_ERROR_NO_ERROR); } + } + + public static class OnTetheringFailed extends CallbackValue { + OnTetheringFailed(final int error) { super(error); } + } + + @Override + public String toString() { + return String.format("%s(%d)", getClass().getSimpleName(), error); + } + } + + private final ArrayTrackRecord.ReadHead mHistory = + new ArrayTrackRecord().newReadHead(); + @Override public void onTetheringStarted() { - // Do nothing, TetherChangeReceiver will wait until it receives the broadcast. + mHistory.add(new CallbackValue.OnTetheringStarted()); } @Override public void onTetheringFailed(final int error) { - fail("startTethering fail: " + error); + mHistory.add(new CallbackValue.OnTetheringFailed(error)); + } + + public void verifyTetheringStarted() { + final CallbackValue cv = mHistory.poll(TIMEOUT_MS, c -> true); + assertNotNull("No onTetheringStarted after " + TIMEOUT_MS + " ms", cv); + assertTrue("Fail start tethering:" + cv, + cv instanceof CallbackValue.OnTetheringStarted); + } + + public void expectTetheringFailed(final int expected) throws InterruptedException { + final CallbackValue cv = mHistory.poll(TIMEOUT_MS, c -> true); + assertNotNull("No onTetheringFailed after " + TIMEOUT_MS + " ms", cv); + assertTrue("Expect fail with error code " + expected + ", but received: " + cv, + (cv instanceof CallbackValue.OnTetheringFailed) && (cv.error == expected)); } } @@ -244,8 +298,10 @@ public class TetheringManagerTest { mTetherChangeReceiver.expectNoActiveTethering(0 /** timeout */); final StartTetheringCallback startTetheringCallback = new StartTetheringCallback(); - mTM.startTethering(new TetheringRequest.Builder(TETHERING_WIFI).build(), c -> c.run(), - startTetheringCallback); + mTM.startTethering(new TetheringRequest.Builder(TETHERING_WIFI).build(), + c -> c.run() /* executor */, startTetheringCallback); + startTetheringCallback.verifyTetheringStarted(); + mTetherChangeReceiver.expectActiveTethering(wifiRegexs); mTM.stopTethering(TETHERING_WIFI); @@ -277,6 +333,7 @@ public class TetheringManagerTest { // Must poll the callback before looking at the member. private static class TestTetheringEventCallback implements TetheringEventCallback { + private static final int TIMEOUT_MS = 30_000; public enum CallbackType { ON_SUPPORTED, ON_UPSTREAM, @@ -299,7 +356,10 @@ public class TetheringManagerTest { this.callbackParam2 = param2; } } - private final LinkedBlockingQueue mCallbacks = new LinkedBlockingQueue<>(); + + private final ArrayTrackRecord.ReadHead mHistory = + new ArrayTrackRecord().newReadHead(); + private TetheringInterfaceRegexps mTetherableRegex; private List mTetherableIfaces; @@ -307,108 +367,96 @@ public class TetheringManagerTest { @Override public void onTetheringSupported(boolean supported) { - mCallbacks.add(new CallbackValue(CallbackType.ON_SUPPORTED, null, 0)); + mHistory.add(new CallbackValue(CallbackType.ON_SUPPORTED, null, 0)); } @Override public void onUpstreamChanged(Network network) { - mCallbacks.add(new CallbackValue(CallbackType.ON_UPSTREAM, network, 0)); + mHistory.add(new CallbackValue(CallbackType.ON_UPSTREAM, network, 0)); } @Override public void onTetherableInterfaceRegexpsChanged(TetheringInterfaceRegexps reg) { mTetherableRegex = reg; - mCallbacks.add(new CallbackValue(CallbackType.ON_TETHERABLE_REGEX, reg, 0)); + mHistory.add(new CallbackValue(CallbackType.ON_TETHERABLE_REGEX, reg, 0)); } @Override public void onTetherableInterfacesChanged(List interfaces) { mTetherableIfaces = interfaces; - mCallbacks.add(new CallbackValue(CallbackType.ON_TETHERABLE_IFACES, interfaces, 0)); + mHistory.add(new CallbackValue(CallbackType.ON_TETHERABLE_IFACES, interfaces, 0)); } @Override public void onTetheredInterfacesChanged(List interfaces) { mTetheredIfaces = interfaces; - mCallbacks.add(new CallbackValue(CallbackType.ON_TETHERED_IFACES, interfaces, 0)); + mHistory.add(new CallbackValue(CallbackType.ON_TETHERED_IFACES, interfaces, 0)); } @Override public void onError(String ifName, int error) { - mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, ifName, error)); + mHistory.add(new CallbackValue(CallbackType.ON_ERROR, ifName, error)); } @Override public void onClientsChanged(Collection clients) { - mCallbacks.add(new CallbackValue(CallbackType.ON_CLIENTS, clients, 0)); + mHistory.add(new CallbackValue(CallbackType.ON_CLIENTS, clients, 0)); } @Override public void onOffloadStatusChanged(int status) { - mCallbacks.add(new CallbackValue(CallbackType.ON_OFFLOAD_STATUS, status, 0)); - } - - public CallbackValue pollCallback() { - try { - return mCallbacks.poll(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - fail("Callback not seen"); - } - return null; + mHistory.add(new CallbackValue(CallbackType.ON_OFFLOAD_STATUS, status, 0)); } public void expectTetherableInterfacesChanged(@NonNull List regexs) { - while (true) { - final CallbackValue cv = pollCallback(); - if (cv == null) fail("No expected tetherable ifaces callback"); - if (cv.callbackType != CallbackType.ON_TETHERABLE_IFACES) continue; - - final List interfaces = (List) cv.callbackParam; - if (isIfaceMatch(regexs, interfaces)) break; - } + assertNotNull("No expected tetherable ifaces callback", mHistory.poll(TIMEOUT_MS, + (cv) -> { + if (cv.callbackType != CallbackType.ON_TETHERABLE_IFACES) return false; + final List interfaces = (List) cv.callbackParam; + return isIfaceMatch(regexs, interfaces); + })); } public void expectTetheredInterfacesChanged(@NonNull List regexs) { - while (true) { - final CallbackValue cv = pollCallback(); - if (cv == null) fail("No expected tethered ifaces callback"); - if (cv.callbackType != CallbackType.ON_TETHERED_IFACES) continue; + assertNotNull("No expected tethered ifaces callback", mHistory.poll(TIMEOUT_MS, + (cv) -> { + if (cv.callbackType != CallbackType.ON_TETHERED_IFACES) return false; - final List interfaces = (List) cv.callbackParam; + final List interfaces = (List) cv.callbackParam; - // Null regexs means no active tethering. - if (regexs == null) { - if (interfaces.size() == 0) break; - } else if (isIfaceMatch(regexs, interfaces)) { - break; - } - } + // Null regexs means no active tethering. + if (regexs == null) return interfaces.isEmpty(); + + return isIfaceMatch(regexs, interfaces); + })); } public void expectCallbackStarted() { + int receivedBitMap = 0; // The each bit represent a type from CallbackType.ON_*. // Expect all of callbacks except for ON_ERROR. - final int expectedBitMap = 0x7f ^ (1 << CallbackType.ON_ERROR.ordinal()); - int receivedBitMap = 0; - while (receivedBitMap != expectedBitMap) { - final CallbackValue cv = pollCallback(); + final int expectedBitMap = 0xff ^ (1 << CallbackType.ON_ERROR.ordinal()); + // Receive ON_ERROR on started callback is not matter. It just means tethering is + // failed last time, should able to continue the test this time. + while ((receivedBitMap & expectedBitMap) != expectedBitMap) { + final CallbackValue cv = mHistory.poll(TIMEOUT_MS, c -> true); if (cv == null) { fail("No expected callbacks, " + "expected bitmap: " + expectedBitMap + ", actual: " + receivedBitMap); } - receivedBitMap = receivedBitMap | (1 << cv.callbackType.ordinal()); + receivedBitMap |= (1 << cv.callbackType.ordinal()); } } public void expectOneOfOffloadStatusChanged(int... offloadStatuses) { - while (true) { - final CallbackValue cv = pollCallback(); - if (cv == null) fail("No expected offload status change callback"); - if (cv.callbackType != CallbackType.ON_OFFLOAD_STATUS) continue; + assertNotNull("No offload status changed", mHistory.poll(TIMEOUT_MS, (cv) -> { + if (cv.callbackType != CallbackType.ON_OFFLOAD_STATUS) return false; final int status = (int) cv.callbackParam; - for (int offloadStatus : offloadStatuses) if (offloadStatus == status) return; - } + for (int offloadStatus : offloadStatuses) if (offloadStatus == status) return true; + + return false; + })); } public TetheringInterfaceRegexps getTetheringInterfaceRegexps() { @@ -424,52 +472,78 @@ public class TetheringManagerTest { } } - @Test - public void testRegisterTetheringEventCallback() throws Exception { - if (!mTM.isTetheringSupported()) return; - + private TestTetheringEventCallback registerTetheringEventCallback() { final TestTetheringEventCallback tetherEventCallback = new TestTetheringEventCallback(); - mTM.registerTetheringEventCallback(c -> c.run(), tetherEventCallback); + mTM.registerTetheringEventCallback(c -> c.run() /* executor */, tetherEventCallback); tetherEventCallback.expectCallbackStarted(); - tetherEventCallback.expectOneOfOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); - final TetheringInterfaceRegexps tetherableRegexs = - tetherEventCallback.getTetheringInterfaceRegexps(); - final List wifiRegexs = tetherableRegexs.getTetherableWifiRegexs(); - if (wifiRegexs.size() == 0) return; + return tetherEventCallback; + } + private void unregisterTetheringEventCallback(final TestTetheringEventCallback callback) { + mTM.unregisterTetheringEventCallback(callback); + } + + private List getWifiTetherableInterfaceRegexps( + final TestTetheringEventCallback callback) { + return callback.getTetheringInterfaceRegexps().getTetherableWifiRegexs(); + } + + private boolean isWifiTetheringSupported(final TestTetheringEventCallback callback) { + return !getWifiTetherableInterfaceRegexps(callback).isEmpty(); + } + + private void startWifiTethering(final TestTetheringEventCallback callback) + throws InterruptedException { + final List wifiRegexs = getWifiTetherableInterfaceRegexps(callback); final boolean isIfaceAvailWhenNoTethering = - isIfaceMatch(wifiRegexs, tetherEventCallback.getTetherableInterfaces()); + isIfaceMatch(wifiRegexs, callback.getTetherableInterfaces()); - mTM.startTethering(new TetheringRequest.Builder(TETHERING_WIFI).build(), c -> c.run(), - new StartTetheringCallback()); + final StartTetheringCallback startTetheringCallback = new StartTetheringCallback(); + mTM.startTethering(new TetheringRequest.Builder(TETHERING_WIFI).build(), + c -> c.run() /* executor */, startTetheringCallback); + startTetheringCallback.verifyTetheringStarted(); // If interface is already available before starting tethering, the available callback may // not be sent after tethering enabled. if (!isIfaceAvailWhenNoTethering) { - tetherEventCallback.expectTetherableInterfacesChanged(wifiRegexs); + callback.expectTetherableInterfacesChanged(wifiRegexs); } - tetherEventCallback.expectTetheredInterfacesChanged(wifiRegexs); - tetherEventCallback.expectOneOfOffloadStatusChanged( + callback.expectTetheredInterfacesChanged(wifiRegexs); + + callback.expectOneOfOffloadStatusChanged( TETHER_HARDWARE_OFFLOAD_STARTED, TETHER_HARDWARE_OFFLOAD_FAILED); + } + private void stopWifiTethering(final TestTetheringEventCallback callback) { mTM.stopTethering(TETHERING_WIFI); + callback.expectTetheredInterfacesChanged(null); + callback.expectOneOfOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); + } - tetherEventCallback.expectTetheredInterfacesChanged(null); - tetherEventCallback.expectOneOfOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); - mTM.unregisterTetheringEventCallback(tetherEventCallback); + @Test + public void testRegisterTetheringEventCallback() throws Exception { + if (!mTM.isTetheringSupported()) return; + + final TestTetheringEventCallback tetherEventCallback = registerTetheringEventCallback(); + + if (!isWifiTetheringSupported(tetherEventCallback)) return; + + startWifiTethering(tetherEventCallback); + + stopWifiTethering(tetherEventCallback); + + unregisterTetheringEventCallback(tetherEventCallback); } @Test public void testGetTetherableInterfaceRegexps() { if (!mTM.isTetheringSupported()) return; - final TestTetheringEventCallback tetherEventCallback = new TestTetheringEventCallback(); - mTM.registerTetheringEventCallback(c -> c.run(), tetherEventCallback); - tetherEventCallback.expectCallbackStarted(); + final TestTetheringEventCallback tetherEventCallback = registerTetheringEventCallback(); final TetheringInterfaceRegexps tetherableRegexs = tetherEventCallback.getTetheringInterfaceRegexps(); @@ -486,7 +560,35 @@ public class TetheringManagerTest { wifiRegexs.forEach(s -> assertFalse(btRegexs.contains(s))); usbRegexs.forEach(s -> assertFalse(btRegexs.contains(s))); - mTM.unregisterTetheringEventCallback(tetherEventCallback); + unregisterTetheringEventCallback(tetherEventCallback); + } + + @Test + public void testStopAllTethering() throws Exception { + if (!mTM.isTetheringSupported()) return; + + final TestTetheringEventCallback tetherEventCallback = registerTetheringEventCallback(); + + if (!isWifiTetheringSupported(tetherEventCallback)) return; + + // TODO: start ethernet tethering here when TetheringManagerTest is moved to + // TetheringIntegrationTest. + + startWifiTethering(tetherEventCallback); + + mTM.stopAllTethering(); + tetherEventCallback.expectTetheredInterfacesChanged(null); + + unregisterTetheringEventCallback(tetherEventCallback); + } + + @Test + public void testEnableTetheringPermission() throws Exception { + dropShellPermissionIdentity(); + final StartTetheringCallback startTetheringCallback = new StartTetheringCallback(); + mTM.startTethering(new TetheringRequest.Builder(TETHERING_WIFI).build(), + c -> c.run() /* executor */, startTetheringCallback); + startTetheringCallback.expectTetheringFailed(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION); } private class EntitlementResultListener implements OnTetheringEntitlementResultListener { From 8cfc634bbc75fc9f3f91a725ba60e5118a5bb54f Mon Sep 17 00:00:00 2001 From: evitayan Date: Thu, 16 Apr 2020 23:03:47 -0700 Subject: [PATCH 0918/1109] Create base class that sets up test network This class will be extended by both IkeSessionParamsTest and IkeSessionTestBase Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: I98979758a7a684219e35c02ded93224ea172d44f --- .../ike/cts/IkeSessionParamsTestBase.java | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTestBase.java diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTestBase.java new file mode 100644 index 0000000000..c3e3ba353c --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTestBase.java @@ -0,0 +1,85 @@ +/* + * 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.ipsec.ike.cts; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.LinkAddress; +import android.net.Network; +import android.net.TestNetworkInterface; +import android.net.TestNetworkManager; +import android.net.ipsec.ike.cts.TestNetworkUtils.TestNetworkCallback; +import android.os.Binder; +import android.os.IBinder; +import android.os.ParcelFileDescriptor; +import android.platform.test.annotations.AppModeFull; + +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@AppModeFull(reason = "MANAGE_TEST_NETWORKS permission can't be granted to instant apps") +abstract class IkeSessionParamsTestBase extends IkeTestBase { + // Static state to reduce setup/teardown + static ConnectivityManager sCM; + static TestNetworkManager sTNM; + static ParcelFileDescriptor sTunFd; + static TestNetworkCallback sTunNetworkCallback; + static Network sTunNetwork; + + static Context sContext = InstrumentationRegistry.getContext(); + static IBinder sBinder = new Binder(); + + // This method is guaranteed to run in subclasses and will run before subclasses' @BeforeClass + // methods. + @BeforeClass + public static void setUpTestNetworkBeforeClass() throws Exception { + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .adoptShellPermissionIdentity(); + sCM = (ConnectivityManager) sContext.getSystemService(Context.CONNECTIVITY_SERVICE); + sTNM = (TestNetworkManager) sContext.getSystemService(Context.TEST_NETWORK_SERVICE); + + TestNetworkInterface testIface = + sTNM.createTunInterface( + new LinkAddress[] {new LinkAddress(IPV4_ADDRESS_LOCAL, IP4_PREFIX_LEN)}); + + sTunFd = testIface.getFileDescriptor(); + sTunNetworkCallback = + TestNetworkUtils.setupAndGetTestNetwork( + sCM, sTNM, testIface.getInterfaceName(), sBinder); + sTunNetwork = sTunNetworkCallback.getNetworkBlocking(); + } + + // This method is guaranteed to run in subclasses and will run after subclasses' @AfterClass + // methods. + @AfterClass + public static void tearDownTestNetworkAfterClass() throws Exception { + sCM.unregisterNetworkCallback(sTunNetworkCallback); + + sTNM.teardownTestNetwork(sTunNetwork); + sTunFd.close(); + + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .dropShellPermissionIdentity(); + } +} From 3cd28c2a39a24599a7ee767ec2244590050939ba Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Wed, 22 Apr 2020 12:25:23 -0700 Subject: [PATCH 0919/1109] Reland "Pull service dumps to help debug test failures." + Convert tests to use Junit4 + Add annotations to specify required conditions for the test to run. This reverts commit 89099548f8ea46046095ccac1e82c2c88d1d0bee. Bug: 137859686 Change-Id: I7bb2a7e4b2dca3696761e7c030f3380b9226b676 Merged-In: I93317c201a0ea06732e29154ab7e140735381f59 --- tests/cts/hostside/AndroidTest.xml | 5 + tests/cts/hostside/app/Android.bp | 2 + tests/cts/hostside/app/AndroidManifest.xml | 3 +- .../net/hostside/AbstractAppIdleTestCase.java | 76 ++-- .../AbstractBatterySaverModeTestCase.java | 68 +--- .../hostside/AbstractDozeModeTestCase.java | 66 +--- ...ractRestrictBackgroundNetworkTestCase.java | 361 ++---------------- .../cts/net/hostside/AppIdleMeteredTest.java | 13 +- .../net/hostside/AppIdleNonMeteredTest.java | 7 +- .../hostside/BatterySaverModeMeteredTest.java | 13 +- .../BatterySaverModeNonMeteredTest.java | 9 +- .../cts/net/hostside/DataSaverModeTest.java | 66 ++-- .../cts/net/hostside/DozeModeMeteredTest.java | 13 +- .../net/hostside/DozeModeNonMeteredTest.java | 8 +- .../cts/net/hostside/DumpOnFailureRule.java | 91 +++++ .../MeterednessConfigurationRule.java | 60 +++ .../cts/net/hostside/MixedModesTest.java | 230 +++++------ .../cts/net/hostside/NetworkCallbackTest.java | 173 +++++---- .../net/hostside/NetworkPolicyTestUtils.java | 255 +++++++++++++ .../android/cts/net/hostside/Property.java | 70 ++++ .../cts/net/hostside/RequiredProperties.java | 31 ++ .../net/hostside/RequiredPropertiesRule.java | 90 +++++ .../cts/net/HostsideNetworkCallbackTests.java | 8 +- .../cts/net/HostsideNetworkTestCase.java | 3 +- 24 files changed, 939 insertions(+), 782 deletions(-) create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/Property.java create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredProperties.java create mode 100644 tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java diff --git a/tests/cts/hostside/AndroidTest.xml b/tests/cts/hostside/AndroidTest.xml index dbff1794e9..5479c51a4c 100644 --- a/tests/cts/hostside/AndroidTest.xml +++ b/tests/cts/hostside/AndroidTest.xml @@ -31,4 +31,9 @@

    By default is empty - it's up to subclasses to override. - */ - protected void setUpMeteredNetwork() throws Exception { - } - - /** - * Resets the (non) metered network state. - * - *

    By default is empty - it's up to subclasses to override. - */ - protected void tearDownMeteredNetwork() throws Exception { + setBatterySaverMode(false); } + @Test public void testBackgroundNetworkAccess_enabled() throws Exception { - if (!isSupported()) return; - setBatterySaverMode(true); assertBackgroundNetworkAccess(false); @@ -118,9 +80,8 @@ abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgrou assertBackgroundNetworkAccess(false); } + @Test public void testBackgroundNetworkAccess_whitelisted() throws Exception { - if (!isSupported()) return; - setBatterySaverMode(true); assertBackgroundNetworkAccess(false); @@ -140,9 +101,8 @@ abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgrou assertBackgroundNetworkAccess(false); } + @Test public void testBackgroundNetworkAccess_disabled() throws Exception { - if (!isSupported()) return; - assertBackgroundNetworkAccess(true); assertsForegroundAlwaysHasNetworkAccess(); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java index f20f1d1c4d..6f32c563c1 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java @@ -16,20 +16,25 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.Property.DOZE_MODE; +import static com.android.cts.net.hostside.Property.NOT_LOW_RAM_DEVICE; + import android.os.SystemClock; -import android.util.Log; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; /** * Base class for metered and non-metered Doze Mode tests. */ +@RequiredProperties({DOZE_MODE}) abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetworkTestCase { - @Override - protected final void setUp() throws Exception { + @Before + public final void setUp() throws Exception { super.setUp(); - if (!isSupported()) return; - // Set initial state. removePowerSaveModeWhitelist(TEST_APP2_PKG); removePowerSaveModeExceptIdleWhitelist(TEST_APP2_PKG); @@ -38,48 +43,15 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor registerBroadcastReceiver(); } - @Override - protected final void tearDown() throws Exception { + @After + public final void tearDown() throws Exception { super.tearDown(); - if (!isSupported()) return; - - try { - tearDownMeteredNetwork(); - } finally { - setDozeMode(false); - } - } - - @Override - protected boolean isSupported() throws Exception { - boolean supported = isDozeModeEnabled(); - if (!supported) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Doze Mode"); - } - return supported; - } - - /** - * Sets the initial (non) metered network state. - * - *

    By default is empty - it's up to subclasses to override. - */ - protected void setUpMeteredNetwork() throws Exception { - } - - /** - * Resets the (non) metered network state. - * - *

    By default is empty - it's up to subclasses to override. - */ - protected void tearDownMeteredNetwork() throws Exception { + setDozeMode(false); } + @Test public void testBackgroundNetworkAccess_enabled() throws Exception { - if (!isSupported()) return; - setDozeMode(true); assertBackgroundNetworkAccess(false); @@ -96,9 +68,8 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor assertBackgroundNetworkAccess(false); } + @Test public void testBackgroundNetworkAccess_whitelisted() throws Exception { - if (!isSupported()) return; - setDozeMode(true); assertBackgroundNetworkAccess(false); @@ -118,19 +89,18 @@ abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetwor assertBackgroundNetworkAccess(false); } + @Test public void testBackgroundNetworkAccess_disabled() throws Exception { - if (!isSupported()) return; - assertBackgroundNetworkAccess(true); assertsForegroundAlwaysHasNetworkAccess(); assertBackgroundNetworkAccess(true); } + @RequiredProperties({NOT_LOW_RAM_DEVICE}) + @Test public void testBackgroundNetworkAccess_enabledButWhitelistedOnNotificationAction() throws Exception { - if (!isSupported() || isLowRamDevice()) return; - setPendingIntentWhitelistDuration(NETWORK_TIMEOUT_MS); try { registerNotificationListenerService(); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 40d7e34fcc..57b7bb4f8d 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -17,14 +17,22 @@ package com.android.cts.net.hostside; import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; -import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; -import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; -import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; import static android.os.BatteryManager.BATTERY_PLUGGED_AC; import static android.os.BatteryManager.BATTERY_PLUGGED_USB; import static android.os.BatteryManager.BATTERY_PLUGGED_WIRELESS; -import static com.android.compatibility.common.util.SystemUtil.runShellCommand; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.executeShellCommand; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getConnectivityManager; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getContext; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getInstrumentation; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.getWifiManager; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isDozeModeSupported; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.restrictBackgroundValueToString; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import android.app.ActivityManager; import android.app.Instrumentation; @@ -34,9 +42,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.pm.PackageManager; import android.net.ConnectivityManager; -import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; import android.net.wifi.WifiManager; @@ -44,24 +50,27 @@ import android.os.BatteryManager; import android.os.Binder; import android.os.Bundle; import android.os.SystemClock; -import android.os.SystemProperties; import android.provider.Settings; import android.service.notification.NotificationListenerService; -import android.test.InstrumentationTestCase; -import android.text.TextUtils; import android.util.Log; -import com.android.compatibility.common.util.BatteryUtils; +import org.junit.Rule; +import org.junit.rules.RuleChain; +import org.junit.runner.RunWith; import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + /** * Superclass for tests related to background network restrictions. */ -abstract class AbstractRestrictBackgroundNetworkTestCase extends InstrumentationTestCase { - protected static final String TAG = "RestrictBackgroundNetworkTests"; +@RunWith(AndroidJUnit4.class) +public abstract class AbstractRestrictBackgroundNetworkTestCase { + public static final String TAG = "RestrictBackgroundNetworkTests"; protected static final String TEST_PKG = "com.android.cts.net.hostside"; protected static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2"; @@ -98,8 +107,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation static final int NETWORK_TIMEOUT_MS = 15 * SECOND_IN_MS; private static int PROCESS_STATE_FOREGROUND_SERVICE; - private static final int PROCESS_STATE_TOP = 2; - private static final String KEY_NETWORK_STATE_OBSERVER = TEST_PKG + ".observer"; protected static final int TYPE_COMPONENT_ACTIVTIY = 0; @@ -126,22 +133,23 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected WifiManager mWfm; protected int mUid; private int mMyUid; - private String mMeteredWifi; private MyServiceClient mServiceClient; private String mDeviceIdleConstantsSetting; - private boolean mSupported; private boolean mIsLocationOn; - @Override + @Rule + public final RuleChain mRuleChain = RuleChain.outerRule(new DumpOnFailureRule()) + .around(new RequiredPropertiesRule()) + .around(new MeterednessConfigurationRule()); + protected void setUp() throws Exception { - super.setUp(); PROCESS_STATE_FOREGROUND_SERVICE = (Integer) ActivityManager.class .getDeclaredField("PROCESS_STATE_FOREGROUND_SERVICE").get(null); mInstrumentation = getInstrumentation(); - mContext = mInstrumentation.getContext(); - mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); - mWfm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); + mContext = getContext(); + mCm = getConnectivityManager(); + mWfm = getWifiManager(); mUid = getUid(TEST_APP2_PKG); mMyUid = getUid(mContext.getPackageName()); mServiceClient = new MyServiceClient(mContext); @@ -151,10 +159,9 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation if (!mIsLocationOn) { enableLocation(); } - mSupported = setUpActiveNetworkMeteringState(); setAppIdle(false); - Log.i(TAG, "Apps status on " + getName() + ":\n" + Log.i(TAG, "Apps status:\n" + "\ttest app: uid=" + mMyUid + ", state=" + getProcessStateByUid(mMyUid) + "\n" + "\tapp2: uid=" + mUid + ", state=" + getProcessStateByUid(mUid)); @@ -165,16 +172,13 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation final String currentConstants = executeShellCommand("settings get global app_idle_constants"); assertEquals(appIdleConstants, currentConstants); - } + } - @Override protected void tearDown() throws Exception { if (!mIsLocationOn) { disableLocation(); } mServiceClient.unbind(); - - super.tearDown(); } private void enableLocation() throws Exception { @@ -259,23 +263,8 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected void assertRestrictBackgroundStatus(int expectedStatus) throws Exception { final String status = mServiceClient.getRestrictBackgroundStatus(); assertNotNull("didn't get API status from app2", status); - final String actualStatus = toString(Integer.parseInt(status)); - assertEquals("wrong status", toString(expectedStatus), actualStatus); - } - - protected void assertMyRestrictBackgroundStatus(int expectedStatus) throws Exception { - final int actualStatus = mCm.getRestrictBackgroundStatus(); - assertEquals("Wrong status", toString(expectedStatus), toString(actualStatus)); - } - - protected boolean isMyRestrictBackgroundStatus(int expectedStatus) throws Exception { - final int actualStatus = mCm.getRestrictBackgroundStatus(); - if (expectedStatus != actualStatus) { - Log.d(TAG, "Expected: " + toString(expectedStatus) - + " but actual: " + toString(actualStatus)); - return false; - } - return true; + assertEquals(restrictBackgroundValueToString(expectedStatus), + restrictBackgroundValueToString(Integer.parseInt(status))); } protected void assertBackgroundNetworkAccess(boolean expectAllowed) throws Exception { @@ -297,28 +286,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation assertNetworkAccess(true /* expectAvailable */, false /* needScreenOn */); } - /** - * Whether this device suport this type of test. - * - *

    Should be overridden when necessary (but always calling - * {@code super.isSupported()} first), and explicitly used before each test - * Example: - * - *

    
    -     * public void testSomething() {
    -     *    if (!isSupported()) return;
    -     * 
    - * - * @return {@code true} by default. - */ - protected boolean isSupported() throws Exception { - return mSupported; - } - - protected boolean isBatterySaverSupported() { - return BatteryUtils.isBatterySaverSupported(); - } - /** * Asserts that an app always have access while on foreground or running a foreground service. * @@ -387,23 +354,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation fail("App2 is not on foreground service state after " + maxTries + " attempts: " + state ); } - /** - * As per CDD requirements, if the device doesn't support data saver mode then - * ConnectivityManager.getRestrictBackgroundStatus() will always return - * RESTRICT_BACKGROUND_STATUS_DISABLED. So, enable the data saver mode and check if - * ConnectivityManager.getRestrictBackgroundStatus() for an app in background returns - * RESTRICT_BACKGROUND_STATUS_DISABLED or not. - */ - protected boolean isDataSaverSupported() throws Exception { - assertMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); - try { - setRestrictBackground(true); - return !isMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); - } finally { - setRestrictBackground(false); - } - } - /** * Returns whether an app state should be considered "background" for restriction purposes. */ @@ -443,40 +393,10 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation // Exponential back-off. timeoutMs = Math.min(timeoutMs*2, NETWORK_TIMEOUT_MS); } - dumpOnFailure(); fail("Invalid state for expectAvailable=" + expectAvailable + " after " + maxTries + " attempts.\nLast error: " + error); } - private void dumpOnFailure() throws Exception { - dumpAllNetworkRules(); - Log.d(TAG, "Usagestats dump: " + getUsageStatsDump()); - executeShellCommand("settings get global app_idle_constants"); - } - - private void dumpAllNetworkRules() throws Exception { - final String networkManagementDump = runShellCommand(mInstrumentation, - "dumpsys network_management").trim(); - final String networkPolicyDump = runShellCommand(mInstrumentation, - "dumpsys netpolicy").trim(); - TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter('\n'); - splitter.setString(networkManagementDump); - String next; - Log.d(TAG, ">>> Begin network_management dump"); - while (splitter.hasNext()) { - next = splitter.next(); - Log.d(TAG, next); - } - Log.d(TAG, "<<< End network_management dump"); - splitter.setString(networkPolicyDump); - Log.d(TAG, ">>> Begin netpolicy dump"); - while (splitter.hasNext()) { - next = splitter.next(); - Log.d(TAG, next); - } - Log.d(TAG, "<<< End netpolicy dump"); - } - /** * Checks whether the network is available as expected. * @@ -528,22 +448,10 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation return errors.toString(); } - protected boolean isLowRamDevice() { - final ActivityManager am = (ActivityManager) mContext.getSystemService( - Context.ACTIVITY_SERVICE); - return am.isLowRamDevice(); - } - - protected String executeShellCommand(String command) throws Exception { - final String result = runShellCommand(mInstrumentation, command).trim(); - if (DEBUG) Log.d(TAG, "Command '" + command + "' returned '" + result + "'"); - return result; - } - /** * Runs a Shell command which is not expected to generate output. */ - protected void executeSilentShellCommand(String command) throws Exception { + protected void executeSilentShellCommand(String command) { final String result = executeShellCommand(command); assertTrue("Command '" + command + "' failed: " + result, result.trim().isEmpty()); } @@ -572,10 +480,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation }); } - protected void assertDelayedShellCommand(String command, ExpectResultChecker checker) - throws Exception { - assertDelayedShellCommand(command, 5, 1, checker); - } protected void assertDelayedShellCommand(String command, int maxTries, int napTimeSeconds, ExpectResultChecker checker) throws Exception { String result = ""; @@ -592,159 +496,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation + " attempts. Last result: '" + result + "'"); } - /** - * Sets the initial metering state for the active network. - * - *

    It's called on setup and by default does nothing - it's up to the - * subclasses to override. - * - * @return whether the tests in the subclass are supported on this device. - */ - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return true; - } - - /** - * Makes sure the active network is not metered. - * - *

    If the device does not supoprt un-metered networks (for example if it - * only has cellular data but not wi-fi), it should return {@code false}; - * otherwise, it should return {@code true} (or fail if the un-metered - * network could not be set). - * - * @return {@code true} if the network is now unmetered. - */ - protected boolean setUnmeteredNetwork() throws Exception { - final NetworkInfo info = mCm.getActiveNetworkInfo(); - assertNotNull("Could not get active network", info); - if (!mCm.isActiveNetworkMetered()) { - Log.d(TAG, "Active network is not metered: " + info); - } else if (info.getType() == ConnectivityManager.TYPE_WIFI) { - Log.i(TAG, "Setting active WI-FI network as not metered: " + info ); - setWifiMeteredStatus(false); - } else { - Log.d(TAG, "Active network cannot be set to un-metered: " + info); - return false; - } - assertActiveNetworkMetered(false); // Sanity check. - return true; - } - - /** - * Enables metering on the active network if supported. - * - *

    If the device does not support metered networks it should return - * {@code false}; otherwise, it should return {@code true} (or fail if the - * metered network could not be set). - * - * @return {@code true} if the network is now metered. - */ - protected boolean setMeteredNetwork() throws Exception { - final NetworkInfo info = mCm.getActiveNetworkInfo(); - final boolean metered = mCm.isActiveNetworkMetered(); - if (metered) { - Log.d(TAG, "Active network already metered: " + info); - return true; - } else if (info.getType() != ConnectivityManager.TYPE_WIFI) { - Log.w(TAG, "Active network does not support metering: " + info); - return false; - } else { - Log.w(TAG, "Active network not metered: " + info); - } - final String netId = setWifiMeteredStatus(true); - - // Set flag so status is reverted on resetMeteredNetwork(); - mMeteredWifi = netId; - // Sanity check. - assertWifiMeteredStatus(netId, true); - assertActiveNetworkMetered(true); - return true; - } - - /** - * Resets the device metering state to what it was before the test started. - * - *

    This reverts any metering changes made by {@code setMeteredNetwork}. - */ - protected void resetMeteredNetwork() throws Exception { - if (mMeteredWifi != null) { - Log.i(TAG, "resetMeteredNetwork(): SID '" + mMeteredWifi - + "' was set as metered by test case; resetting it"); - setWifiMeteredStatus(mMeteredWifi, false); - assertActiveNetworkMetered(false); // Sanity check. - } - } - - private void assertActiveNetworkMetered(boolean expected) throws Exception { - final int maxTries = 5; - NetworkInfo info = null; - for (int i = 1; i <= maxTries; i++) { - info = mCm.getActiveNetworkInfo(); - if (info == null) { - Log.v(TAG, "No active network info on attempt #" + i - + "; sleeping 1s before polling again"); - } else if (mCm.isActiveNetworkMetered() != expected) { - Log.v(TAG, "Wrong metered status for active network " + info + "; expected=" - + expected + "; sleeping 1s before polling again"); - } else { - break; - } - Thread.sleep(SECOND_IN_MS); - } - assertNotNull("No active network after " + maxTries + " attempts", info); - assertEquals("Wrong metered status for active network " + info, expected, - mCm.isActiveNetworkMetered()); - } - - private String setWifiMeteredStatus(boolean metered) throws Exception { - // We could call setWifiEnabled() here, but it might take sometime to be in a consistent - // state (for example, if one of the saved network is not properly authenticated), so it's - // better to let the hostside test take care of that. - assertTrue("wi-fi is disabled", mWfm.isWifiEnabled()); - // TODO: if it's not guaranteed the device has wi-fi, we need to change the tests - // to make the actual verification of restrictions optional. - final String ssid = mWfm.getConnectionInfo().getSSID(); - return setWifiMeteredStatus(ssid, metered); - } - - private String setWifiMeteredStatus(String ssid, boolean metered) throws Exception { - assertNotNull("null SSID", ssid); - final String netId = ssid.trim().replaceAll("\"", ""); // remove quotes, if any. - assertFalse("empty SSID", ssid.isEmpty()); - - Log.i(TAG, "Setting wi-fi network " + netId + " metered status to " + metered); - final String setCommand = "cmd netpolicy set metered-network " + netId + " " + metered; - assertDelayedShellCommand(setCommand, ""); - - return netId; - } - - private void assertWifiMeteredStatus(String netId, boolean status) throws Exception { - final String command = "cmd netpolicy list wifi-networks"; - final String expectedLine = netId + ";" + status; - assertDelayedShellCommand(command, new ExpectResultChecker() { - - @Override - public boolean isExpected(String result) { - return result.contains(expectedLine); - } - - @Override - public String getExpected() { - return "line containing " + expectedLine; - } - }); - } - - protected void setRestrictBackground(boolean enabled) throws Exception { - executeShellCommand("cmd netpolicy set restrict-background " + enabled); - final String output = executeShellCommand("cmd netpolicy get restrict-background "); - final String expectedSuffix = enabled ? "enabled" : "disabled"; - // TODO: use MoreAsserts? - assertTrue("output '" + output + "' should end with '" + expectedSuffix + "'", - output.endsWith(expectedSuffix)); - } - protected void addRestrictBackgroundWhitelist(int uid) throws Exception { executeShellCommand("cmd netpolicy add restrict-background-whitelist " + uid); assertRestrictBackgroundWhitelist(uid, true); @@ -924,7 +675,7 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation protected void setDozeMode(boolean enabled) throws Exception { // Sanity check, since tests should check beforehand.... - assertTrue("Device does not support Doze Mode", isDozeModeEnabled()); + assertTrue("Device does not support Doze Mode", isDozeModeSupported()); Log.i(TAG, "Setting Doze Mode to " + enabled); if (enabled) { @@ -944,43 +695,16 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation assertDelayedShellCommand("dumpsys deviceidle get deep", enabled ? "IDLE" : "ACTIVE"); } - protected boolean isDozeModeEnabled() throws Exception { - final String result = executeShellCommand("cmd deviceidle enabled deep").trim(); - return result.equals("1"); - } - protected void setAppIdle(boolean enabled) throws Exception { Log.i(TAG, "Setting app idle to " + enabled); executeSilentShellCommand("am set-inactive " + TEST_APP2_PKG + " " + enabled ); assertAppIdle(enabled); // Sanity check } - private String getUsageStatsDump() throws Exception { - final String output = runShellCommand(mInstrumentation, "dumpsys usagestats").trim(); - final StringBuilder sb = new StringBuilder(); - final TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter('\n'); - splitter.setString(output); - String str; - while (splitter.hasNext()) { - str = splitter.next(); - if (str.contains("package=") - && !str.contains(TEST_PKG) && !str.contains(TEST_APP2_PKG)) { - continue; - } - if (str.trim().startsWith("config=") || str.trim().startsWith("time=")) { - continue; - } - sb.append(str).append('\n'); - } - return sb.toString(); - } - protected void assertAppIdle(boolean enabled) throws Exception { try { assertDelayedShellCommand("am get-inactive " + TEST_APP2_PKG, 15, 2, "Idle=" + enabled); } catch (Throwable e) { - Log.d(TAG, "UsageStats dump:\n" + getUsageStatsDump()); - executeShellCommand("settings get global app_idle_constants"); throw e; } } @@ -1061,12 +785,10 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation // App didn't come to foreground when the activity is started, so try again. assertForegroundNetworkAccess(); } else { - dumpOnFailure(); fail("Network is not available for app2 (" + mUid + "): " + errors[0]); } } } else { - dumpOnFailure(); fail("Timed out waiting for network availability status from app2 (" + mUid + ")"); } } else { @@ -1150,19 +872,6 @@ abstract class AbstractRestrictBackgroundNetworkTestCase extends Instrumentation } } - private String toString(int status) { - switch (status) { - case RESTRICT_BACKGROUND_STATUS_DISABLED: - return "DISABLED"; - case RESTRICT_BACKGROUND_STATUS_WHITELISTED: - return "WHITELISTED"; - case RESTRICT_BACKGROUND_STATUS_ENABLED: - return "ENABLED"; - default: - return "UNKNOWN_STATUS_" + status; - } - } - private ProcessState getProcessStateByUid(int uid) throws Exception { return new ProcessState(executeShellCommand("cmd activity get-uid-state " + uid)); } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java index 622d99361f..f1858d65a5 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java @@ -16,15 +16,8 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; + +@RequiredProperties({METERED_NETWORK}) public class AppIdleMeteredTest extends AbstractAppIdleTestCase { - - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setMeteredNetwork(); - } - - @Override - protected void tearDownMeteredNetwork() throws Exception { - resetMeteredNetwork(); - } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java index bde71f9100..e737a6dabe 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java @@ -16,9 +16,8 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; + +@RequiredProperties({NON_METERED_NETWORK}) public class AppIdleNonMeteredTest extends AbstractAppIdleTestCase { - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setUnmeteredNetwork(); - } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java index 3071cfe3f1..c78ca2ec77 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java @@ -16,15 +16,8 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; + +@RequiredProperties({METERED_NETWORK}) public class BatterySaverModeMeteredTest extends AbstractBatterySaverModeTestCase { - - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setMeteredNetwork(); - } - - @Override - protected void tearDownMeteredNetwork() throws Exception { - resetMeteredNetwork(); - } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java index 6d3076fe0e..fb52a540d8 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java @@ -16,10 +16,9 @@ package com.android.cts.net.hostside; -public class BatterySaverModeNonMeteredTest extends AbstractBatterySaverModeTestCase { - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setUnmeteredNetwork(); - } +import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; + +@RequiredProperties({NON_METERED_NETWORK}) +public class BatterySaverModeNonMeteredTest extends AbstractBatterySaverModeTestCase { } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java index cfe6a73a0f..aa2c914e02 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java @@ -20,24 +20,33 @@ import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLE import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; -import android.util.Log; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground; +import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; +import static com.android.cts.net.hostside.Property.NO_DATA_SAVER_MODE; + +import static org.junit.Assert.fail; import com.android.compatibility.common.util.CddTest; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import androidx.test.filters.LargeTest; + +@RequiredProperties({DATA_SAVER_MODE, METERED_NETWORK}) +@LargeTest public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase { private static final String[] REQUIRED_WHITELISTED_PACKAGES = { "com.android.providers.downloads" }; - private boolean mIsDataSaverSupported; - - @Override + @Before public void setUp() throws Exception { super.setUp(); - mIsDataSaverSupported = isDataSaverSupported(); - // Set initial state. setRestrictBackground(false); removeRestrictBackgroundWhitelist(mUid); @@ -47,36 +56,15 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertRestrictBackgroundChangedReceived(0); } - @Override - protected void tearDown() throws Exception { + @After + public void tearDown() throws Exception { super.tearDown(); - if (!isSupported()) return; - - try { - resetMeteredNetwork(); - } finally { - setRestrictBackground(false); - } - } - - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setMeteredNetwork(); - } - - @Override - protected boolean isSupported() throws Exception { - if (!mIsDataSaverSupported) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Data Saver Mode"); - } - return mIsDataSaverSupported && super.isSupported(); + setRestrictBackground(false); } + @Test public void testGetRestrictBackgroundStatus_disabled() throws Exception { - if (!isSupported()) return; - assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED); // Sanity check: make sure status is always disabled, never whitelisted @@ -88,9 +76,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_DISABLED); } + @Test public void testGetRestrictBackgroundStatus_whitelisted() throws Exception { - if (!isSupported()) return; - setRestrictBackground(true); assertRestrictBackgroundChangedReceived(1); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); @@ -107,9 +94,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); } + @Test public void testGetRestrictBackgroundStatus_enabled() throws Exception { - if (!isSupported()) return; - setRestrictBackground(true); assertRestrictBackgroundChangedReceived(1); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); @@ -142,9 +128,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertBackgroundNetworkAccess(false); } + @Test public void testGetRestrictBackgroundStatus_blacklisted() throws Exception { - if (!isSupported()) return; - addRestrictBackgroundBlacklist(mUid); assertRestrictBackgroundChangedReceived(1); assertDataSaverStatusOnBackground(RESTRICT_BACKGROUND_STATUS_ENABLED); @@ -180,9 +165,8 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase assertsForegroundAlwaysHasNetworkAccess(); } + @Test public void testGetRestrictBackgroundStatus_requiredWhitelistedPackages() throws Exception { - if (!isSupported()) return; - final StringBuilder error = new StringBuilder(); for (String packageName : REQUIRED_WHITELISTED_PACKAGES) { int uid = -1; @@ -202,10 +186,10 @@ public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase } } + @RequiredProperties({NO_DATA_SAVER_MODE}) @CddTest(requirement="7.4.7/C-2-2") + @Test public void testBroadcastNotSentOnUnsupportedDevices() throws Exception { - if (isSupported()) return; - setRestrictBackground(true); assertRestrictBackgroundChangedReceived(0); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java index e4189af587..4306c991c2 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java @@ -16,15 +16,8 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; + +@RequiredProperties({METERED_NETWORK}) public class DozeModeMeteredTest extends AbstractDozeModeTestCase { - - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setMeteredNetwork(); - } - - @Override - protected void tearDownMeteredNetwork() throws Exception { - resetMeteredNetwork(); - } } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java index edbbb9e1ce..1e89f158a3 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java @@ -16,10 +16,8 @@ package com.android.cts.net.hostside; -public class DozeModeNonMeteredTest extends AbstractDozeModeTestCase { +import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; - @Override - protected boolean setUpActiveNetworkMeteringState() throws Exception { - return setUnmeteredNetwork(); - } +@RequiredProperties({NON_METERED_NETWORK}) +public class DozeModeNonMeteredTest extends AbstractDozeModeTestCase { } diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java new file mode 100644 index 0000000000..cedd62a0bc --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DumpOnFailureRule.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TAG; +import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TEST_PKG; + +import android.os.Environment; +import android.os.FileUtils; +import android.os.ParcelFileDescriptor; +import android.util.Log; + +import com.android.compatibility.common.util.OnFailureRule; + +import org.junit.AssumptionViolatedException; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import androidx.test.platform.app.InstrumentationRegistry; + +public class DumpOnFailureRule extends OnFailureRule { + private File mDumpDir = new File(Environment.getExternalStorageDirectory(), + "CtsHostsideNetworkTests"); + + @Override + public void onTestFailure(Statement base, Description description, Throwable throwable) { + final String testName = description.getClassName() + "_" + description.getMethodName(); + + if (throwable instanceof AssumptionViolatedException) { + Log.d(TAG, "Skipping test " + testName + ": " + throwable); + return; + } + + prepareDumpRootDir(); + final File dumpFile = new File(mDumpDir, "dump-" + testName); + Log.i(TAG, "Dumping debug info for " + description + ": " + dumpFile.getPath()); + try (FileOutputStream out = new FileOutputStream(dumpFile)) { + for (String cmd : new String[] { + "dumpsys netpolicy", + "dumpsys network_management", + "dumpsys usagestats " + TEST_PKG, + "dumpsys usagestats appstandby", + }) { + dumpCommandOutput(out, cmd); + } + } catch (FileNotFoundException e) { + Log.e(TAG, "Error opening file: " + dumpFile, e); + } catch (IOException e) { + Log.e(TAG, "Error closing file: " + dumpFile, e); + } + } + + void dumpCommandOutput(FileOutputStream out, String cmd) { + final ParcelFileDescriptor pfd = InstrumentationRegistry.getInstrumentation() + .getUiAutomation().executeShellCommand(cmd); + try (FileInputStream in = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) { + out.write(("Output of '" + cmd + "':\n").getBytes(StandardCharsets.UTF_8)); + FileUtils.copy(in, out); + out.write("\n\n=================================================================\n\n" + .getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + Log.e(TAG, "Error dumping '" + cmd + "'", e); + } + } + + void prepareDumpRootDir() { + if (!mDumpDir.exists() && !mDumpDir.mkdir()) { + Log.e(TAG, "Error creating " + mDumpDir); + } + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java new file mode 100644 index 0000000000..8fadf9e295 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MeterednessConfigurationRule.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.resetMeteredNetwork; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setupMeteredNetwork; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; +import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; + +import android.util.ArraySet; +import android.util.Pair; + +import com.android.compatibility.common.util.BeforeAfterRule; + +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +public class MeterednessConfigurationRule extends BeforeAfterRule { + private Pair mSsidAndInitialMeteredness; + + @Override + public void onBefore(Statement base, Description description) throws Throwable { + final ArraySet requiredProperties + = RequiredPropertiesRule.getRequiredProperties(); + if (requiredProperties.contains(METERED_NETWORK)) { + configureNetworkMeteredness(true); + } else if (requiredProperties.contains(NON_METERED_NETWORK)) { + configureNetworkMeteredness(false); + } + } + + @Override + public void onAfter(Statement base, Description description) throws Throwable { + resetNetworkMeteredness(); + } + + public void configureNetworkMeteredness(boolean metered) throws Exception { + mSsidAndInitialMeteredness = setupMeteredNetwork(metered); + } + + public void resetNetworkMeteredness() throws Exception { + if (mSsidAndInitialMeteredness != null) { + resetMeteredNetwork(mSsidAndInitialMeteredness.first, + mSsidAndInitialMeteredness.second); + } + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java index b1a21867b3..c9edda6e0b 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/MixedModesTest.java @@ -15,9 +15,21 @@ */ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground; +import static com.android.cts.net.hostside.Property.APP_STANDBY_MODE; +import static com.android.cts.net.hostside.Property.BATTERY_SAVER_MODE; +import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE; +import static com.android.cts.net.hostside.Property.DOZE_MODE; +import static com.android.cts.net.hostside.Property.METERED_NETWORK; +import static com.android.cts.net.hostside.Property.NON_METERED_NETWORK; + import android.os.SystemClock; import android.util.Log; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + /** * Test cases for the more complex scenarios where multiple restrictions (like Battery Saver Mode * and Data Saver Mode) are applied simultaneously. @@ -29,12 +41,10 @@ import android.util.Log; public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { private static final String TAG = "MixedModesTest"; - @Override + @Before public void setUp() throws Exception { super.setUp(); - if (!isSupported()) return; - // Set initial state. removeRestrictBackgroundWhitelist(mUid); removeRestrictBackgroundBlacklist(mUid); @@ -44,12 +54,10 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { registerBroadcastReceiver(); } - @Override - protected void tearDown() throws Exception { + @After + public void tearDown() throws Exception { super.tearDown(); - if (!isSupported()) return; - try { setRestrictBackground(false); } finally { @@ -57,34 +65,15 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } - @Override - public boolean isSupported() throws Exception { - if (!isDozeModeEnabled()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Doze Mode"); - return false; - } - return true; - } - /** * Tests all DS ON and BS ON scenarios from network-policy-restrictions.md on metered networks. */ + @RequiredProperties({DATA_SAVER_MODE, BATTERY_SAVER_MODE, METERED_NETWORK}) + @Test public void testDataAndBatterySaverModes_meteredNetwork() throws Exception { - if (!isBatterySaverSupported()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Battery saver mode"); - return; - } - if (!isSupported()) return; - - Log.i(TAG, "testDataAndBatterySaverModes_meteredNetwork() tests"); - if (!setMeteredNetwork()) { - Log.w(TAG, "testDataAndBatterySaverModes_meteredNetwork() skipped because " - + "device cannot use a metered network"); - return; - } - + final MeterednessConfigurationRule meterednessConfiguration + = new MeterednessConfigurationRule(); + meterednessConfiguration.configureNetworkMeteredness(true); try { setRestrictBackground(true); setBatterySaverMode(true); @@ -137,7 +126,7 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { removeRestrictBackgroundBlacklist(mUid); removePowerSaveModeWhitelist(TEST_APP2_PKG); } finally { - resetMeteredNetwork(); + meterednessConfiguration.resetNetworkMeteredness(); } } @@ -145,86 +134,75 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { * Tests all DS ON and BS ON scenarios from network-policy-restrictions.md on non-metered * networks. */ + @RequiredProperties({DATA_SAVER_MODE, BATTERY_SAVER_MODE, NON_METERED_NETWORK}) + @Test public void testDataAndBatterySaverModes_nonMeteredNetwork() throws Exception { - if (!isBatterySaverSupported()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Battery saver mode"); - return; + final MeterednessConfigurationRule meterednessConfiguration + = new MeterednessConfigurationRule(); + meterednessConfiguration.configureNetworkMeteredness(false); + try { + setRestrictBackground(true); + setBatterySaverMode(true); + + Log.v(TAG, "Not whitelisted for any."); + assertBackgroundNetworkAccess(false); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + + Log.v(TAG, "Whitelisted for Data Saver but not for Battery Saver."); + addRestrictBackgroundWhitelist(mUid); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + removeRestrictBackgroundWhitelist(mUid); + + Log.v(TAG, "Whitelisted for Battery Saver but not for Data Saver."); + addPowerSaveModeWhitelist(TEST_APP2_PKG); + removeRestrictBackgroundWhitelist(mUid); + assertBackgroundNetworkAccess(true); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(true); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + + Log.v(TAG, "Whitelisted for both."); + addRestrictBackgroundWhitelist(mUid); + addPowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(true); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(true); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + removeRestrictBackgroundWhitelist(mUid); + + Log.v(TAG, "Blacklisted for Data Saver, not whitelisted for Battery Saver."); + addRestrictBackgroundBlacklist(mUid); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(false); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(false); + removeRestrictBackgroundBlacklist(mUid); + + Log.v(TAG, "Blacklisted for Data Saver, whitelisted for Battery Saver."); + addRestrictBackgroundBlacklist(mUid); + addPowerSaveModeWhitelist(TEST_APP2_PKG); + assertBackgroundNetworkAccess(true); + assertsForegroundAlwaysHasNetworkAccess(); + assertBackgroundNetworkAccess(true); + removeRestrictBackgroundBlacklist(mUid); + removePowerSaveModeWhitelist(TEST_APP2_PKG); + } finally { + meterednessConfiguration.resetNetworkMeteredness(); } - if (!isSupported()) return; - - if (!setUnmeteredNetwork()) { - Log.w(TAG, "testDataAndBatterySaverModes_nonMeteredNetwork() skipped because network" - + " is metered"); - return; - } - Log.i(TAG, "testDataAndBatterySaverModes_nonMeteredNetwork() tests"); - setRestrictBackground(true); - setBatterySaverMode(true); - - Log.v(TAG, "Not whitelisted for any."); - assertBackgroundNetworkAccess(false); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(false); - - Log.v(TAG, "Whitelisted for Data Saver but not for Battery Saver."); - addRestrictBackgroundWhitelist(mUid); - removePowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(false); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(false); - removeRestrictBackgroundWhitelist(mUid); - - Log.v(TAG, "Whitelisted for Battery Saver but not for Data Saver."); - addPowerSaveModeWhitelist(TEST_APP2_PKG); - removeRestrictBackgroundWhitelist(mUid); - assertBackgroundNetworkAccess(true); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(true); - removePowerSaveModeWhitelist(TEST_APP2_PKG); - - Log.v(TAG, "Whitelisted for both."); - addRestrictBackgroundWhitelist(mUid); - addPowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(true); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(true); - removePowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(false); - removeRestrictBackgroundWhitelist(mUid); - - Log.v(TAG, "Blacklisted for Data Saver, not whitelisted for Battery Saver."); - addRestrictBackgroundBlacklist(mUid); - removePowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(false); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(false); - removeRestrictBackgroundBlacklist(mUid); - - Log.v(TAG, "Blacklisted for Data Saver, whitelisted for Battery Saver."); - addRestrictBackgroundBlacklist(mUid); - addPowerSaveModeWhitelist(TEST_APP2_PKG); - assertBackgroundNetworkAccess(true); - assertsForegroundAlwaysHasNetworkAccess(); - assertBackgroundNetworkAccess(true); - removeRestrictBackgroundBlacklist(mUid); - removePowerSaveModeWhitelist(TEST_APP2_PKG); } /** * Tests that powersave whitelists works as expected when doze and battery saver modes * are enabled. */ + @RequiredProperties({DOZE_MODE, BATTERY_SAVER_MODE}) + @Test public void testDozeAndBatterySaverMode_powerSaveWhitelists() throws Exception { - if (!isBatterySaverSupported()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Battery saver mode"); - return; - } - if (!isSupported()) { - return; - } - setBatterySaverMode(true); setDozeMode(true); @@ -250,11 +228,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { * Tests that powersave whitelists works as expected when doze and appIdle modes * are enabled. */ + @RequiredProperties({DOZE_MODE, APP_STANDBY_MODE}) + @Test public void testDozeAndAppIdle_powerSaveWhitelists() throws Exception { - if (!isSupported()) { - return; - } - setDozeMode(true); setAppIdle(true); @@ -276,11 +252,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } + @RequiredProperties({APP_STANDBY_MODE, DOZE_MODE}) + @Test public void testAppIdleAndDoze_tempPowerSaveWhitelists() throws Exception { - if (!isSupported()) { - return; - } - setDozeMode(true); setAppIdle(true); @@ -299,16 +273,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } + @RequiredProperties({APP_STANDBY_MODE, BATTERY_SAVER_MODE}) + @Test public void testAppIdleAndBatterySaver_tempPowerSaveWhitelists() throws Exception { - if (!isBatterySaverSupported()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Battery saver mode"); - return; - } - if (!isSupported()) { - return; - } - setBatterySaverMode(true); setAppIdle(true); @@ -330,11 +297,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { /** * Tests that the app idle whitelist works as expected when doze and appIdle mode are enabled. */ + @RequiredProperties({DOZE_MODE, APP_STANDBY_MODE}) + @Test public void testDozeAndAppIdle_appIdleWhitelist() throws Exception { - if (!isSupported()) { - return; - } - setDozeMode(true); setAppIdle(true); @@ -353,11 +318,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } + @RequiredProperties({APP_STANDBY_MODE, DOZE_MODE}) + @Test public void testAppIdleAndDoze_tempPowerSaveAndAppIdleWhitelists() throws Exception { - if (!isSupported()) { - return; - } - setDozeMode(true); setAppIdle(true); @@ -380,16 +343,9 @@ public class MixedModesTest extends AbstractRestrictBackgroundNetworkTestCase { } } + @RequiredProperties({APP_STANDBY_MODE, BATTERY_SAVER_MODE}) + @Test public void testAppIdleAndBatterySaver_tempPowerSaveAndAppIdleWhitelists() throws Exception { - if (!isBatterySaverSupported()) { - Log.i(TAG, "Skipping " + getClass() + "." + getName() - + "() because device does not support Battery saver mode"); - return; - } - if (!isSupported()) { - return; - } - setBatterySaverMode(true); setAppIdle(true); diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java index 24dde9d356..ed397b91fc 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java @@ -16,15 +16,26 @@ package com.android.cts.net.hostside; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.setRestrictBackground; +import static com.android.cts.net.hostside.Property.BATTERY_SAVER_MODE; +import static com.android.cts.net.hostside.Property.DATA_SAVER_MODE; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + import android.net.Network; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + import java.util.Objects; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCase { - private boolean mIsDataSaverSupported; private Network mNetwork; private final TestNetworkCallback mTestNetworkCallback = new TestNetworkCallback(); @@ -132,108 +143,122 @@ public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCa } } - @Override + @Before public void setUp() throws Exception { super.setUp(); - mIsDataSaverSupported = isDataSaverSupported(); - mNetwork = mCm.getActiveNetwork(); - // Set initial state. - setBatterySaverMode(false); registerBroadcastReceiver(); - if (!mIsDataSaverSupported) return; - setRestrictBackground(false); removeRestrictBackgroundWhitelist(mUid); removeRestrictBackgroundBlacklist(mUid); assertRestrictBackgroundChangedReceived(0); } - @Override - protected void tearDown() throws Exception { + @After + public void tearDown() throws Exception { super.tearDown(); - if (!mIsDataSaverSupported) return; + setRestrictBackground(false); + setBatterySaverMode(false); + } + @RequiredProperties({DATA_SAVER_MODE}) + @Test + public void testOnBlockedStatusChanged_dataSaver() throws Exception { + // Initial state + setBatterySaverMode(false); + setRestrictBackground(false); + + final MeterednessConfigurationRule meterednessConfiguration + = new MeterednessConfigurationRule(); + meterednessConfiguration.configureNetworkMeteredness(true); try { - resetMeteredNetwork(); + // Register callback + registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); + mTestNetworkCallback.expectAvailableCallback(mNetwork); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Enable restrict background + setRestrictBackground(true); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); + + // Add to whitelist + addRestrictBackgroundWhitelist(mUid); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Remove from whitelist + removeRestrictBackgroundWhitelist(mUid); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); } finally { + meterednessConfiguration.resetNetworkMeteredness(); + } + + // Set to non-metered network + meterednessConfiguration.configureNetworkMeteredness(false); + try { + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + + // Disable restrict background, should not trigger callback setRestrictBackground(false); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.assertNoCallback(); + } finally { + meterednessConfiguration.resetNetworkMeteredness(); } } - public void testOnBlockedStatusChanged_data_saver() throws Exception { - if (!mIsDataSaverSupported) return; - - // Prepare metered wifi - if (!setMeteredNetwork()) return; - - // Register callback - registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); - mTestNetworkCallback.expectAvailableCallback(mNetwork); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - - // Enable restrict background - setRestrictBackground(true); - assertBackgroundNetworkAccess(false); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); - - // Add to whitelist - addRestrictBackgroundWhitelist(mUid); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - - // Remove from whitelist - removeRestrictBackgroundWhitelist(mUid); - assertBackgroundNetworkAccess(false); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); - - // Set to non-metered network - setUnmeteredNetwork(); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - - // Disable restrict background, should not trigger callback + @RequiredProperties({BATTERY_SAVER_MODE}) + @Test + public void testOnBlockedStatusChanged_powerSaver() throws Exception { + // Set initial state. + setBatterySaverMode(false); setRestrictBackground(false); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.assertNoCallback(); - } + final MeterednessConfigurationRule meterednessConfiguration + = new MeterednessConfigurationRule(); + meterednessConfiguration.configureNetworkMeteredness(true); + try { + // Register callback + registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); + mTestNetworkCallback.expectAvailableCallback(mNetwork); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - public void testOnBlockedStatusChanged_power_saver() throws Exception { - // Prepare metered wifi - if (!setMeteredNetwork()) return; + // Enable Power Saver + setBatterySaverMode(true); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); - // Register callback - registerNetworkCallback((INetworkCallback.Stub) mTestNetworkCallback); - mTestNetworkCallback.expectAvailableCallback(mNetwork); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); - - // Enable Power Saver - setBatterySaverMode(true); - assertBackgroundNetworkAccess(false); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); - - // Disable Power Saver - setBatterySaverMode(false); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + // Disable Power Saver + setBatterySaverMode(false); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + } finally { + meterednessConfiguration.resetNetworkMeteredness(); + } // Set to non-metered network - setUnmeteredNetwork(); - mTestNetworkCallback.assertNoCallback(); + meterednessConfiguration.configureNetworkMeteredness(false); + try { + mTestNetworkCallback.assertNoCallback(); - // Enable Power Saver - setBatterySaverMode(true); - assertBackgroundNetworkAccess(false); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); + // Enable Power Saver + setBatterySaverMode(true); + assertBackgroundNetworkAccess(false); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, true); - // Disable Power Saver - setBatterySaverMode(false); - assertBackgroundNetworkAccess(true); - mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + // Disable Power Saver + setBatterySaverMode(false); + assertBackgroundNetworkAccess(true); + mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false); + } finally { + meterednessConfiguration.resetNetworkMeteredness(); + } } // TODO: 1. test against VPN lockdown. diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java new file mode 100644 index 0000000000..ca2864c0b8 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; +import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; +import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; +import static android.net.NetworkCapabilities.TRANSPORT_WIFI; + +import static com.android.compatibility.common.util.SystemUtil.runShellCommand; +import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TAG; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import android.app.ActivityManager; +import android.app.Instrumentation; +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.ConnectivityManager.NetworkCallback; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.wifi.WifiManager; +import android.text.TextUtils; +import android.util.Log; +import android.util.Pair; + +import com.android.compatibility.common.util.AppStandbyUtils; +import com.android.compatibility.common.util.BatteryUtils; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import androidx.test.platform.app.InstrumentationRegistry; + +public class NetworkPolicyTestUtils { + + private static final int TIMEOUT_CHANGE_METEREDNESS_MS = 5000; + + private static ConnectivityManager mCm; + private static WifiManager mWm; + + private static Boolean mBatterySaverSupported; + private static Boolean mDataSaverSupported; + private static Boolean mDozeModeSupported; + private static Boolean mAppStandbySupported; + + private NetworkPolicyTestUtils() {} + + public static boolean isBatterySaverSupported() { + if (mBatterySaverSupported == null) { + mBatterySaverSupported = BatteryUtils.isBatterySaverSupported(); + } + return mBatterySaverSupported; + } + + /** + * As per CDD requirements, if the device doesn't support data saver mode then + * ConnectivityManager.getRestrictBackgroundStatus() will always return + * RESTRICT_BACKGROUND_STATUS_DISABLED. So, enable the data saver mode and check if + * ConnectivityManager.getRestrictBackgroundStatus() for an app in background returns + * RESTRICT_BACKGROUND_STATUS_DISABLED or not. + */ + public static boolean isDataSaverSupported() { + if (mDataSaverSupported == null) { + assertMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED); + try { + setRestrictBackground(true); + mDataSaverSupported = !isMyRestrictBackgroundStatus( + RESTRICT_BACKGROUND_STATUS_DISABLED); + } finally { + setRestrictBackground(false); + } + } + return mDataSaverSupported; + } + + public static boolean isDozeModeSupported() { + if (mDozeModeSupported == null) { + final String result = executeShellCommand("cmd deviceidle enabled deep"); + mDozeModeSupported = result.equals("1"); + } + return mDozeModeSupported; + } + + public static boolean isAppStandbySupported() { + if (mAppStandbySupported == null) { + mAppStandbySupported = AppStandbyUtils.isAppStandbyEnabled(); + } + return mAppStandbySupported; + } + + public static boolean isLowRamDevice() { + final ActivityManager am = (ActivityManager) getContext().getSystemService( + Context.ACTIVITY_SERVICE); + return am.isLowRamDevice(); + } + + public static boolean isActiveNetworkMetered(boolean metered) { + return getConnectivityManager().isActiveNetworkMetered() == metered; + } + + public static boolean canChangeActiveNetworkMeteredness() { + final Network activeNetwork = getConnectivityManager().getActiveNetwork(); + final NetworkCapabilities networkCapabilities + = getConnectivityManager().getNetworkCapabilities(activeNetwork); + return networkCapabilities.hasTransport(TRANSPORT_WIFI); + } + + public static Pair setupMeteredNetwork(boolean metered) throws Exception { + if (isActiveNetworkMetered(metered)) { + return null; + } + final String ssid = unquoteSSID(getWifiManager().getConnectionInfo().getSSID()); + setWifiMeteredStatus(ssid, metered); + return Pair.create(ssid, !metered); + } + + public static void resetMeteredNetwork(String ssid, boolean metered) throws Exception { + setWifiMeteredStatus(ssid, metered); + } + + public static void setWifiMeteredStatus(String ssid, boolean metered) throws Exception { + assertFalse("SSID should not be empty", TextUtils.isEmpty(ssid)); + final String cmd = "cmd netpolicy set metered-network " + ssid + " " + metered; + executeShellCommand(cmd); + assertWifiMeteredStatus(ssid, metered); + assertActiveNetworkMetered(metered); + } + + public static void assertWifiMeteredStatus(String ssid, boolean expectedMeteredStatus) { + final String result = executeShellCommand("cmd netpolicy list wifi-networks"); + final String expectedLine = ssid + ";" + expectedMeteredStatus; + assertTrue("Expected line: " + expectedLine + "; Actual result: " + result, + result.contains(expectedLine)); + } + + // Copied from cts/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java + public static void assertActiveNetworkMetered(boolean expectedMeteredStatus) throws Exception { + final CountDownLatch latch = new CountDownLatch(1); + final NetworkCallback networkCallback = new NetworkCallback() { + @Override + public void onCapabilitiesChanged(Network network, NetworkCapabilities nc) { + final boolean metered = !nc.hasCapability(NET_CAPABILITY_NOT_METERED); + if (metered == expectedMeteredStatus) { + latch.countDown(); + } + } + }; + // Registering a callback here guarantees onCapabilitiesChanged is called immediately + // with the current setting. Therefore, if the setting has already been changed, + // this method will return right away, and if not it will wait for the setting to change. + getConnectivityManager().registerDefaultNetworkCallback(networkCallback); + if (!latch.await(TIMEOUT_CHANGE_METEREDNESS_MS, TimeUnit.MILLISECONDS)) { + fail("Timed out waiting for active network metered status to change to " + + expectedMeteredStatus + " ; network = " + + getConnectivityManager().getActiveNetwork()); + } + getConnectivityManager().unregisterNetworkCallback(networkCallback); + } + + public static void setRestrictBackground(boolean enabled) { + executeShellCommand("cmd netpolicy set restrict-background " + enabled); + final String output = executeShellCommand("cmd netpolicy get restrict-background"); + final String expectedSuffix = enabled ? "enabled" : "disabled"; + assertTrue("output '" + output + "' should end with '" + expectedSuffix + "'", + output.endsWith(expectedSuffix)); + } + + public static boolean isMyRestrictBackgroundStatus(int expectedStatus) { + final int actualStatus = getConnectivityManager().getRestrictBackgroundStatus(); + if (expectedStatus != actualStatus) { + Log.d(TAG, "MyRestrictBackgroundStatus: " + + "Expected: " + restrictBackgroundValueToString(expectedStatus) + + "; Actual: " + restrictBackgroundValueToString(actualStatus)); + return false; + } + return true; + } + + // Copied from cts/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java + private static String unquoteSSID(String ssid) { + // SSID is returned surrounded by quotes if it can be decoded as UTF-8. + // Otherwise it's guaranteed not to start with a quote. + if (ssid.charAt(0) == '"') { + return ssid.substring(1, ssid.length() - 1); + } else { + return ssid; + } + } + + public static String restrictBackgroundValueToString(int status) { + switch (status) { + case RESTRICT_BACKGROUND_STATUS_DISABLED: + return "DISABLED"; + case RESTRICT_BACKGROUND_STATUS_WHITELISTED: + return "WHITELISTED"; + case RESTRICT_BACKGROUND_STATUS_ENABLED: + return "ENABLED"; + default: + return "UNKNOWN_STATUS_" + status; + } + } + + public static String executeShellCommand(String command) { + final String result = runShellCommand(command).trim(); + Log.d(TAG, "Output of '" + command + "': '" + result + "'"); + return result; + } + + public static void assertMyRestrictBackgroundStatus(int expectedStatus) { + final int actualStatus = getConnectivityManager().getRestrictBackgroundStatus(); + assertEquals(restrictBackgroundValueToString(expectedStatus), + restrictBackgroundValueToString(actualStatus)); + } + + public static ConnectivityManager getConnectivityManager() { + if (mCm == null) { + mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); + } + return mCm; + } + + public static WifiManager getWifiManager() { + if (mWm == null) { + mWm = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); + } + return mWm; + } + + public static Context getContext() { + return getInstrumentation().getContext(); + } + + public static Instrumentation getInstrumentation() { + return InstrumentationRegistry.getInstrumentation(); + } +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/Property.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/Property.java new file mode 100644 index 0000000000..18805f9613 --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/Property.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.canChangeActiveNetworkMeteredness; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isActiveNetworkMetered; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isAppStandbySupported; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isBatterySaverSupported; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isDataSaverSupported; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isDozeModeSupported; +import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isLowRamDevice; + +public enum Property { + BATTERY_SAVER_MODE(1 << 0) { + public boolean isSupported() { return isBatterySaverSupported(); } + }, + + DATA_SAVER_MODE(1 << 1) { + public boolean isSupported() { return isDataSaverSupported(); } + }, + + NO_DATA_SAVER_MODE(~DATA_SAVER_MODE.getValue()) { + public boolean isSupported() { return !isDataSaverSupported(); } + }, + + DOZE_MODE(1 << 2) { + public boolean isSupported() { return isDozeModeSupported(); } + }, + + APP_STANDBY_MODE(1 << 3) { + public boolean isSupported() { return isAppStandbySupported(); } + }, + + NOT_LOW_RAM_DEVICE(1 << 4) { + public boolean isSupported() { return !isLowRamDevice(); } + }, + + METERED_NETWORK(1 << 5) { + public boolean isSupported() { + return isActiveNetworkMetered(true) || canChangeActiveNetworkMeteredness(); + } + }, + + NON_METERED_NETWORK(~METERED_NETWORK.getValue()) { + public boolean isSupported() { + return isActiveNetworkMetered(false) || canChangeActiveNetworkMeteredness(); + } + }; + + private int mValue; + + Property(int value) { mValue = value; } + + public int getValue() { return mValue; } + + abstract boolean isSupported(); +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredProperties.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredProperties.java new file mode 100644 index 0000000000..96838bba0a --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredProperties.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(RUNTIME) +@Target({METHOD, TYPE}) +@Inherited +public @interface RequiredProperties { + Property[] value(); +} diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java new file mode 100644 index 0000000000..1e333200db --- /dev/null +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2019 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.cts.net.hostside; + +import static com.android.cts.net.hostside.AbstractRestrictBackgroundNetworkTestCase.TAG; + +import android.text.TextUtils; +import android.util.ArraySet; +import android.util.Log; + +import com.android.compatibility.common.util.BeforeAfterRule; + +import org.junit.Assume; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import java.util.ArrayList; +import java.util.Collections; + +public class RequiredPropertiesRule extends BeforeAfterRule { + + private static ArraySet mRequiredProperties; + + @Override + public void onBefore(Statement base, Description description) { + mRequiredProperties = getAllRequiredProperties(description); + + final String testName = description.getClassName() + "#" + description.getMethodName(); + assertTestIsValid(testName, mRequiredProperties); + Log.i(TAG, "Running test " + testName + " with required properties: " + + propertiesToString(mRequiredProperties)); + } + + private ArraySet getAllRequiredProperties(Description description) { + final ArraySet allRequiredProperties = new ArraySet<>(); + RequiredProperties requiredProperties = description.getAnnotation(RequiredProperties.class); + if (requiredProperties != null) { + Collections.addAll(allRequiredProperties, requiredProperties.value()); + } + + for (Class clazz = description.getTestClass(); + clazz != null; clazz = clazz.getSuperclass()) { + requiredProperties = clazz.getDeclaredAnnotation(RequiredProperties.class); + if (requiredProperties == null) { + continue; + } + for (Property requiredProperty : requiredProperties.value()) { + if (!allRequiredProperties.contains(~requiredProperty.getValue())) { + allRequiredProperties.add(requiredProperty); + } + } + } + return allRequiredProperties; + } + + private void assertTestIsValid(String testName, ArraySet requiredProperies) { + if (requiredProperies == null) { + return; + } + final ArrayList unsupportedProperties = new ArrayList<>(); + for (Property property : requiredProperies) { + if (!property.isSupported()) { + unsupportedProperties.add(property); + } + } + Assume.assumeTrue("Unsupported properties: " + + propertiesToString(unsupportedProperties), unsupportedProperties.isEmpty()); + } + + public static ArraySet getRequiredProperties() { + return mRequiredProperties; + } + + private static String propertiesToString(Iterable properties) { + return "[" + TextUtils.join(",", properties) + "]"; + } +} diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java index 8d6c4acd7d..1312085478 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkCallbackTests.java @@ -29,14 +29,14 @@ public class HostsideNetworkCallbackTests extends HostsideNetworkTestCase { uninstallPackage(TEST_APP2_PKG, true); } - public void testOnBlockedStatusChanged_data_saver() throws Exception { + public void testOnBlockedStatusChanged_dataSaver() throws Exception { runDeviceTests(TEST_PKG, - TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_data_saver"); + TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_dataSaver"); } - public void testOnBlockedStatusChanged_power_saver() throws Exception { + public void testOnBlockedStatusChanged_powerSaver() throws Exception { runDeviceTests(TEST_PKG, - TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_power_saver"); + TEST_PKG + ".NetworkCallbackTest", "testOnBlockedStatusChanged_powerSaver"); } } diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java index a2443b391a..ce203795f9 100644 --- a/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java +++ b/tests/cts/hostside/src/com/android/cts/net/HostsideNetworkTestCase.java @@ -79,7 +79,8 @@ abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiRec protected void installPackage(String apk) throws FileNotFoundException, DeviceNotAvailableException { CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild); - assertNull(getDevice().installPackage(buildHelper.getTestFile(apk), false)); + assertNull(getDevice().installPackage(buildHelper.getTestFile(apk), + false /* reinstall */, true /* grantPermissions */)); } protected void uninstallPackage(String packageName, boolean shouldSucceed) From a0e71e89eaef5491aa8363c6287712bf261c8491 Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Wed, 22 Apr 2020 13:50:15 -0700 Subject: [PATCH 0920/1109] Fix Error Prone errors Soong wasn't including android_app or android_test sources in the javac-check target used for the Error Prone build, which allowed some Error Prone errors to get in. Fix them so Error Prone can be re-enabled for these targets. Fixes: cts/hostsidetests/net/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java:61: error: [CollectionIncompatibleType] Argument '~requiredProperty.getValue()' should not be passed to this method; its type int is not compatible with its collection's type argument Property Bug: 146455923 Test: m RUN_ERROR_PRONE=true javac-check Change-Id: I7c5bf823bf371902285ce3ee3929796fa40c653b Merged-In: I48b1ccb61c807d0b41a165298ef5981258d6656e --- .../android/cts/net/hostside/RequiredPropertiesRule.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java index 1e333200db..98c97c5687 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RequiredPropertiesRule.java @@ -58,8 +58,12 @@ public class RequiredPropertiesRule extends BeforeAfterRule { continue; } for (Property requiredProperty : requiredProperties.value()) { - if (!allRequiredProperties.contains(~requiredProperty.getValue())) { - allRequiredProperties.add(requiredProperty); + for (Property p : Property.values()) { + if (p.getValue() == ~requiredProperty.getValue()) { + if (!allRequiredProperties.contains(p)) { + allRequiredProperties.add(requiredProperty); + } + } } } } From 004c442de90543dd2ba3b8d152f7a2b90e0b2c91 Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Wed, 5 Feb 2020 17:54:01 -0800 Subject: [PATCH 0921/1109] Fix a regression in how required properties are collected. + Enable app standby mode before running the tests. Fixes: 147459100 Fixes: 117169751 Test: atest hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java Test: cts-tradefed run singleCommand cts-on-gsi --skip-device-info \ --skip-preconditions -m CtsHostsideNetworkTests \ -t com.android.cts.net.HostsideRestrictBackgroundNetworkTests Change-Id: I782f8a06922622d28f9a9d5c9f2afa2b12f8aa80 Merged-In: I782f8a06922622d28f9a9d5c9f2afa2b12f8aa80 --- tests/cts/hostside/AndroidTest.xml | 1 + .../net/hostside/RequiredPropertiesRule.java | 8 +-- .../cts/net/NetworkPolicyTestsPreparer.java | 59 +++++++++++++++++++ 3 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 tests/cts/hostside/src/com/android/cts/net/NetworkPolicyTestsPreparer.java diff --git a/tests/cts/hostside/AndroidTest.xml b/tests/cts/hostside/AndroidTest.xml index 5479c51a4c..d4f30e0cf3 100644 --- a/tests/cts/hostside/AndroidTest.xml +++ b/tests/cts/hostside/AndroidTest.xml @@ -21,6 +21,7 @@

    Authentication method is arbitrarily selected. Using other method (e.g. setAuthEap) also + * works. + */ + private IkeSessionParams.Builder createIkeParamsBuilderMinimum() { + return new IkeSessionParams.Builder(sContext) + .setNetwork(sTunNetwork) + .setServerHostname(IPV4_ADDRESS_REMOTE.getHostAddress()) + .addSaProposal(SA_PROPOSAL) + .setLocalIdentification(LOCAL_ID) + .setRemoteIdentification(REMOTE_ID) + .setAuthPsk(IKE_PSK); + } + + /** + * Verify the minimum configurations to build an IkeSessionParams. + * + * @see #createIkeParamsBuilderMinimum + */ + private void verifyIkeParamsMinimum(IkeSessionParams sessionParams) { + assertEquals(sTunNetwork, sessionParams.getNetwork()); + assertEquals(IPV4_ADDRESS_REMOTE.getHostAddress(), sessionParams.getServerHostname()); + assertEquals(Arrays.asList(SA_PROPOSAL), sessionParams.getSaProposals()); + assertEquals(LOCAL_ID, sessionParams.getLocalIdentification()); + assertEquals(REMOTE_ID, sessionParams.getRemoteIdentification()); + + IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig(); + assertTrue(localConfig instanceof IkeAuthPskConfig); + assertArrayEquals(IKE_PSK, ((IkeAuthPskConfig) localConfig).getPsk()); + IkeAuthConfig remoteConfig = sessionParams.getRemoteAuthConfig(); + assertTrue(remoteConfig instanceof IkeAuthPskConfig); + assertArrayEquals(IKE_PSK, ((IkeAuthPskConfig) remoteConfig).getPsk()); + } + + private void verifySpecificPcscfConfigReqs( + HashSet expectedAddresses, IkeSessionParams sessionParams) { + Set resultAddresses = new HashSet<>(); + + for (IkeConfigRequest req : sessionParams.getConfigurationRequests()) { + if (req instanceof ConfigRequestIpv4PcscfServer + && ((ConfigRequestIpv4PcscfServer) req).getAddress() != null) { + resultAddresses.add(((ConfigRequestIpv4PcscfServer) req).getAddress()); + } else if (req instanceof ConfigRequestIpv6PcscfServer + && ((ConfigRequestIpv6PcscfServer) req).getAddress() != null) { + resultAddresses.add(((ConfigRequestIpv6PcscfServer) req).getAddress()); + } + } + + assertEquals(expectedAddresses, resultAddresses); + } + + @Test + public void testBuildWithMinimumSet() throws Exception { + IkeSessionParams sessionParams = createIkeParamsBuilderMinimum().build(); + + verifyIkeParamsMinimum(sessionParams); + + // Verify default values that do not need explicit configuration. Do not do assertEquals + // to be avoid being a change-detector test + assertTrue(sessionParams.getHardLifetimeSeconds() > sessionParams.getSoftLifetimeSeconds()); + assertTrue(sessionParams.getSoftLifetimeSeconds() > 0); + assertTrue(sessionParams.getDpdDelaySeconds() > 0); + assertTrue(sessionParams.getRetransmissionTimeoutsMillis().length > 0); + for (int timeout : sessionParams.getRetransmissionTimeoutsMillis()) { + assertTrue(timeout > 0); + } + assertTrue(sessionParams.getConfigurationRequests().isEmpty()); + assertFalse(sessionParams.hasIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID)); + } + + @Test + public void testSetLifetimes() throws Exception { + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimum() + .setLifetimeSeconds(HARD_LIFETIME_SECONDS, SOFT_LIFETIME_SECONDS) + .build(); + + verifyIkeParamsMinimum(sessionParams); + assertEquals(HARD_LIFETIME_SECONDS, sessionParams.getHardLifetimeSeconds()); + assertEquals(SOFT_LIFETIME_SECONDS, sessionParams.getSoftLifetimeSeconds()); + } + + @Test + public void testSetDpdDelay() throws Exception { + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimum().setDpdDelaySeconds(DPD_DELAY_SECONDS).build(); + + verifyIkeParamsMinimum(sessionParams); + assertEquals(DPD_DELAY_SECONDS, sessionParams.getDpdDelaySeconds()); + } + + @Test + public void testSetRetransmissionTimeouts() throws Exception { + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimum() + .setRetransmissionTimeoutsMillis(RETRANS_TIMEOUT_MS_LIST) + .build(); + + verifyIkeParamsMinimum(sessionParams); + assertArrayEquals(RETRANS_TIMEOUT_MS_LIST, sessionParams.getRetransmissionTimeoutsMillis()); + } + + @Test + public void testSetPcscfConfigRequests() throws Exception { + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimum() + .setRetransmissionTimeoutsMillis(RETRANS_TIMEOUT_MS_LIST) + .addPcscfServerRequest(AF_INET) + .addPcscfServerRequest(PCSCF_IPV4_ADDRESS_1) + .addPcscfServerRequest(PCSCF_IPV6_ADDRESS_1) + .addPcscfServerRequest(AF_INET6) + .addPcscfServerRequest(PCSCF_IPV4_ADDRESS_2) + .addPcscfServerRequest(PCSCF_IPV6_ADDRESS_2) + .build(); + + verifyIkeParamsMinimum(sessionParams); + verifyConfigRequestTypes(EXPECTED_REQ_COUNT, sessionParams.getConfigurationRequests()); + + Set resultAddresses = new HashSet<>(); + for (IkeConfigRequest req : sessionParams.getConfigurationRequests()) { + if (req instanceof ConfigRequestIpv4PcscfServer + && ((ConfigRequestIpv4PcscfServer) req).getAddress() != null) { + resultAddresses.add(((ConfigRequestIpv4PcscfServer) req).getAddress()); + } else if (req instanceof ConfigRequestIpv6PcscfServer + && ((ConfigRequestIpv6PcscfServer) req).getAddress() != null) { + resultAddresses.add(((ConfigRequestIpv6PcscfServer) req).getAddress()); + } + } + assertEquals(EXPECTED_PCSCF_SERVERS, resultAddresses); + } + + @Test + public void testAddIkeOption() throws Exception { + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimum() + .addIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID) + .build(); + + verifyIkeParamsMinimum(sessionParams); + assertTrue(sessionParams.hasIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID)); + } + + @Test + public void testRemoveIkeOption() throws Exception { + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimum() + .addIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID) + .removeIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID) + .build(); + + verifyIkeParamsMinimum(sessionParams); + assertFalse(sessionParams.hasIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID)); + } + + @Test + public void testBuildWithPsk() throws Exception { + IkeSessionParams sessionParams = + new IkeSessionParams.Builder(sContext) + .setNetwork(sTunNetwork) + .setServerHostname(IPV4_ADDRESS_REMOTE.getHostAddress()) + .addSaProposal(SA_PROPOSAL) + .setLocalIdentification(LOCAL_ID) + .setRemoteIdentification(REMOTE_ID) + .setAuthPsk(IKE_PSK) + .build(); + assertEquals(sTunNetwork, sessionParams.getNetwork()); + assertEquals(IPV4_ADDRESS_REMOTE.getHostAddress(), sessionParams.getServerHostname()); + assertEquals(Arrays.asList(SA_PROPOSAL), sessionParams.getSaProposals()); + assertEquals(LOCAL_ID, sessionParams.getLocalIdentification()); + assertEquals(REMOTE_ID, sessionParams.getRemoteIdentification()); + + IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig(); + assertTrue(localConfig instanceof IkeAuthPskConfig); + assertArrayEquals(IKE_PSK, ((IkeAuthPskConfig) localConfig).getPsk()); + IkeAuthConfig remoteConfig = sessionParams.getRemoteAuthConfig(); + assertTrue(remoteConfig instanceof IkeAuthPskConfig); + assertArrayEquals(IKE_PSK, ((IkeAuthPskConfig) remoteConfig).getPsk()); + } + + // TODO(b/148689509): Add tests for building IkeSessionParams using EAP and + // digital-signature-based authentication +} diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java index d3aa8d03d5..5f608df137 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java @@ -24,6 +24,7 @@ import android.net.ipsec.ike.IkeTrafficSelector; import java.net.Inet4Address; import java.net.Inet6Address; +import java.net.InetAddress; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -40,6 +41,11 @@ abstract class IkeTestBase { static final int IP4_PREFIX_LEN = 32; static final int IP6_PREFIX_LEN = 64; + static final byte[] IKE_PSK = "ikeAndroidPsk".getBytes(); + + static final String LOCAL_HOSTNAME = "client.test.ike.android.net"; + static final String REMOTE_HOSTNAME = "server.test.ike.android.net"; + static final Inet4Address IPV4_ADDRESS_LOCAL = (Inet4Address) (InetAddresses.parseNumericAddress("192.0.2.100")); static final Inet4Address IPV4_ADDRESS_REMOTE = @@ -49,6 +55,13 @@ abstract class IkeTestBase { static final Inet6Address IPV6_ADDRESS_REMOTE = (Inet6Address) (InetAddresses.parseNumericAddress("2001:db8:255::100")); + static final InetAddress PCSCF_IPV4_ADDRESS_1 = InetAddresses.parseNumericAddress("192.0.2.1"); + static final InetAddress PCSCF_IPV4_ADDRESS_2 = InetAddresses.parseNumericAddress("192.0.2.2"); + static final InetAddress PCSCF_IPV6_ADDRESS_1 = + InetAddresses.parseNumericAddress("2001:DB8::1"); + static final InetAddress PCSCF_IPV6_ADDRESS_2 = + InetAddresses.parseNumericAddress("2001:DB8::2"); + static final IkeTrafficSelector DEFAULT_V4_TS = new IkeTrafficSelector( MIN_PORT, From 9dcef4002333d2ee50ce1f772eb0c29a2c1948fb Mon Sep 17 00:00:00 2001 From: evitayan Date: Mon, 20 Apr 2020 15:15:24 -0700 Subject: [PATCH 0928/1109] Add test for IkeIdentification Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: Ieda584446c37d121fc16a212e2c6c60b934b0f53 --- .../ipsec/ike/cts/IkeIdentificationTest.java | 75 +++++++++++++++++++ .../net/ipsec/ike/cts/IkeTestBase.java | 3 + 2 files changed, 78 insertions(+) create mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeIdentificationTest.java diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeIdentificationTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeIdentificationTest.java new file mode 100644 index 0000000000..0317def92e --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeIdentificationTest.java @@ -0,0 +1,75 @@ +/* + * 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.ipsec.ike.cts; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +import android.net.ipsec.ike.IkeDerAsn1DnIdentification; +import android.net.ipsec.ike.IkeFqdnIdentification; +import android.net.ipsec.ike.IkeIpv4AddrIdentification; +import android.net.ipsec.ike.IkeIpv6AddrIdentification; +import android.net.ipsec.ike.IkeKeyIdIdentification; +import android.net.ipsec.ike.IkeRfc822AddrIdentification; + +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import javax.security.auth.x500.X500Principal; + +@RunWith(AndroidJUnit4.class) +public final class IkeIdentificationTest extends IkeTestBase { + @Test + public void testIkeDerAsn1DnIdentification() throws Exception { + X500Principal asn1Dn = new X500Principal(LOCAL_ASN1_DN_STRING); + + IkeDerAsn1DnIdentification ikeId = new IkeDerAsn1DnIdentification(asn1Dn); + assertEquals(asn1Dn, ikeId.derAsn1Dn); + } + + @Test + public void testIkeFqdnIdentification() throws Exception { + IkeFqdnIdentification ikeId = new IkeFqdnIdentification(LOCAL_HOSTNAME); + assertEquals(LOCAL_HOSTNAME, ikeId.fqdn); + } + + @Test + public void testIkeIpv4AddrIdentification() throws Exception { + IkeIpv4AddrIdentification ikeId = new IkeIpv4AddrIdentification(IPV4_ADDRESS_LOCAL); + assertEquals(IPV4_ADDRESS_LOCAL, ikeId.ipv4Address); + } + + @Test + public void testIkeIpv6AddrIdentification() throws Exception { + IkeIpv6AddrIdentification ikeId = new IkeIpv6AddrIdentification(IPV6_ADDRESS_LOCAL); + assertEquals(IPV6_ADDRESS_LOCAL, ikeId.ipv6Address); + } + + @Test + public void testIkeKeyIdIdentification() throws Exception { + IkeKeyIdIdentification ikeId = new IkeKeyIdIdentification(LOCAL_KEY_ID); + assertArrayEquals(LOCAL_KEY_ID, ikeId.keyId); + } + + @Test + public void testIkeRfc822AddrIdentification() throws Exception { + IkeRfc822AddrIdentification ikeId = new IkeRfc822AddrIdentification(LOCAL_RFC822_NAME); + assertEquals(LOCAL_RFC822_NAME, ikeId.rfc822Name); + } +} diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java index 5f608df137..08477446d2 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java @@ -45,6 +45,9 @@ abstract class IkeTestBase { static final String LOCAL_HOSTNAME = "client.test.ike.android.net"; static final String REMOTE_HOSTNAME = "server.test.ike.android.net"; + static final String LOCAL_ASN1_DN_STRING = "CN=client.test.ike.android.net, O=Android, C=US"; + static final String LOCAL_RFC822_NAME = "client.test.ike@example.com"; + static final byte[] LOCAL_KEY_ID = "Local Key ID".getBytes(); static final Inet4Address IPV4_ADDRESS_LOCAL = (Inet4Address) (InetAddresses.parseNumericAddress("192.0.2.100")); From de7f511bd1866d17c8c5e259a6363bba5340571c Mon Sep 17 00:00:00 2001 From: Yan Yan Date: Thu, 23 Apr 2020 23:20:51 +0000 Subject: [PATCH 0929/1109] Create base class that sets up test network This class will be extended by both IkeSessionParamsTest and IkeSessionTestBase Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: I98979758a7a684219e35c02ded93224ea172d44f Merged-In: I98979758a7a684219e35c02ded93224ea172d44f (cherry picked from commit 50908b926635355f0753b7388f96b684f6be351d) --- .../ike/cts/IkeSessionParamsTestBase.java | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTestBase.java diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTestBase.java new file mode 100644 index 0000000000..c3e3ba353c --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTestBase.java @@ -0,0 +1,85 @@ +/* + * 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.ipsec.ike.cts; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.LinkAddress; +import android.net.Network; +import android.net.TestNetworkInterface; +import android.net.TestNetworkManager; +import android.net.ipsec.ike.cts.TestNetworkUtils.TestNetworkCallback; +import android.os.Binder; +import android.os.IBinder; +import android.os.ParcelFileDescriptor; +import android.platform.test.annotations.AppModeFull; + +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@AppModeFull(reason = "MANAGE_TEST_NETWORKS permission can't be granted to instant apps") +abstract class IkeSessionParamsTestBase extends IkeTestBase { + // Static state to reduce setup/teardown + static ConnectivityManager sCM; + static TestNetworkManager sTNM; + static ParcelFileDescriptor sTunFd; + static TestNetworkCallback sTunNetworkCallback; + static Network sTunNetwork; + + static Context sContext = InstrumentationRegistry.getContext(); + static IBinder sBinder = new Binder(); + + // This method is guaranteed to run in subclasses and will run before subclasses' @BeforeClass + // methods. + @BeforeClass + public static void setUpTestNetworkBeforeClass() throws Exception { + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .adoptShellPermissionIdentity(); + sCM = (ConnectivityManager) sContext.getSystemService(Context.CONNECTIVITY_SERVICE); + sTNM = (TestNetworkManager) sContext.getSystemService(Context.TEST_NETWORK_SERVICE); + + TestNetworkInterface testIface = + sTNM.createTunInterface( + new LinkAddress[] {new LinkAddress(IPV4_ADDRESS_LOCAL, IP4_PREFIX_LEN)}); + + sTunFd = testIface.getFileDescriptor(); + sTunNetworkCallback = + TestNetworkUtils.setupAndGetTestNetwork( + sCM, sTNM, testIface.getInterfaceName(), sBinder); + sTunNetwork = sTunNetworkCallback.getNetworkBlocking(); + } + + // This method is guaranteed to run in subclasses and will run after subclasses' @AfterClass + // methods. + @AfterClass + public static void tearDownTestNetworkAfterClass() throws Exception { + sCM.unregisterNetworkCallback(sTunNetworkCallback); + + sTNM.teardownTestNetwork(sTunNetwork); + sTunFd.close(); + + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .dropShellPermissionIdentity(); + } +} From 7db1b713ba761dd9d61164e4f691167f77572f6d Mon Sep 17 00:00:00 2001 From: Yan Yan Date: Fri, 24 Apr 2020 01:15:02 +0000 Subject: [PATCH 0930/1109] Add CTS for EapSessionConfig Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: I54dedff0555bdfcaae390ddde7b05d24dfabe9b0 Merged-In: I54dedff0555bdfcaae390ddde7b05d24dfabe9b0 (cherry picked from commit b6dff211348df9b4b8d7ce0631512cba65195e47) --- .../net/eap/cts/EapSessionConfigTest.java | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 tests/cts/net/ipsec/src/android/net/eap/cts/EapSessionConfigTest.java diff --git a/tests/cts/net/ipsec/src/android/net/eap/cts/EapSessionConfigTest.java b/tests/cts/net/ipsec/src/android/net/eap/cts/EapSessionConfigTest.java new file mode 100644 index 0000000000..c24379dae0 --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/eap/cts/EapSessionConfigTest.java @@ -0,0 +1,98 @@ +/* + * 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.eap.cts; + +import static android.telephony.TelephonyManager.APPTYPE_USIM; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import android.net.eap.EapSessionConfig; +import android.net.eap.EapSessionConfig.EapAkaConfig; +import android.net.eap.EapSessionConfig.EapAkaPrimeConfig; +import android.net.eap.EapSessionConfig.EapMsChapV2Config; +import android.net.eap.EapSessionConfig.EapSimConfig; +import android.net.eap.EapSessionConfig.EapUiccConfig; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class EapSessionConfigTest { + // These constants are IANA-defined values and are copies of hidden constants in + // frameworks/opt/net/ike/src/java/com/android/internal/net/eap/message/EapData.java. + private static final int EAP_TYPE_SIM = 18; + private static final int EAP_TYPE_AKA = 23; + private static final int EAP_TYPE_MSCHAP_V2 = 26; + private static final int EAP_TYPE_AKA_PRIME = 50; + + private static final int SUB_ID = 1; + private static final byte[] EAP_IDENTITY = "test@android.net".getBytes(); + private static final String NETWORK_NAME = "android.net"; + private static final String EAP_MSCHAPV2_USERNAME = "username"; + private static final String EAP_MSCHAPV2_PASSWORD = "password"; + + @Test + public void testBuildWithAllEapMethods() { + EapSessionConfig result = + new EapSessionConfig.Builder() + .setEapIdentity(EAP_IDENTITY) + .setEapSimConfig(SUB_ID, APPTYPE_USIM) + .setEapAkaConfig(SUB_ID, APPTYPE_USIM) + .setEapAkaPrimeConfig( + SUB_ID, + APPTYPE_USIM, + NETWORK_NAME, + true /* allowMismatchedNetworkNames */) + .setEapMsChapV2Config(EAP_MSCHAPV2_USERNAME, EAP_MSCHAPV2_PASSWORD) + .build(); + + assertArrayEquals(EAP_IDENTITY, result.getEapIdentity()); + + EapSimConfig eapSimConfig = result.getEapSimConfig(); + assertNotNull(eapSimConfig); + assertEquals(EAP_TYPE_SIM, eapSimConfig.getMethodType()); + verifyEapUiccConfigCommon(eapSimConfig); + + EapAkaConfig eapAkaConfig = result.getEapAkaConfig(); + assertNotNull(eapAkaConfig); + assertEquals(EAP_TYPE_AKA, eapAkaConfig.getMethodType()); + verifyEapUiccConfigCommon(eapAkaConfig); + + EapAkaPrimeConfig eapAkaPrimeConfig = result.getEapAkaPrimeConfig(); + assertNotNull(eapAkaPrimeConfig); + assertEquals(EAP_TYPE_AKA_PRIME, eapAkaPrimeConfig.getMethodType()); + assertEquals(NETWORK_NAME, eapAkaPrimeConfig.getNetworkName()); + assertTrue(NETWORK_NAME, eapAkaPrimeConfig.allowsMismatchedNetworkNames()); + verifyEapUiccConfigCommon(eapAkaPrimeConfig); + + EapMsChapV2Config eapMsChapV2Config = result.getEapMsChapV2onfig(); + assertNotNull(eapMsChapV2Config); + assertEquals(EAP_TYPE_MSCHAP_V2, eapMsChapV2Config.getMethodType()); + assertEquals(EAP_MSCHAPV2_USERNAME, eapMsChapV2Config.getUsername()); + assertEquals(EAP_MSCHAPV2_PASSWORD, eapMsChapV2Config.getPassword()); + } + + private void verifyEapUiccConfigCommon(EapUiccConfig config) { + assertEquals(SUB_ID, config.getSubId()); + assertEquals(APPTYPE_USIM, config.getAppType()); + } +} From e800e9503770368869d1b0e095d09a8906193795 Mon Sep 17 00:00:00 2001 From: evitayan Date: Tue, 14 Apr 2020 18:26:53 -0700 Subject: [PATCH 0931/1109] Test building IkeSessionParams with EAP Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: Iea7f4d14502f4b204c7a0d7357e1aaec99954e1f --- tests/cts/net/ipsec/Android.bp | 1 + .../assets/pem/server-a-self-signed-ca.pem | 20 +++ .../ipsec/ike/cts/IkeSessionParamsTest.java | 144 ++++++++++++++---- .../net/ipsec/ike/cts/IkeTestBase.java | 6 + 4 files changed, 141 insertions(+), 30 deletions(-) create mode 100644 tests/cts/net/ipsec/assets/pem/server-a-self-signed-ca.pem diff --git a/tests/cts/net/ipsec/Android.bp b/tests/cts/net/ipsec/Android.bp index 8c073c9602..f1f120b32b 100644 --- a/tests/cts/net/ipsec/Android.bp +++ b/tests/cts/net/ipsec/Android.bp @@ -26,6 +26,7 @@ android_test { srcs: [ "src/**/*.java", + ":ike-test-utils", ], static_libs: [ diff --git a/tests/cts/net/ipsec/assets/pem/server-a-self-signed-ca.pem b/tests/cts/net/ipsec/assets/pem/server-a-self-signed-ca.pem new file mode 100644 index 0000000000..972fd55372 --- /dev/null +++ b/tests/cts/net/ipsec/assets/pem/server-a-self-signed-ca.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDSDCCAjCgAwIBAgIITJQJ6HC1rjwwDQYJKoZIhvcNAQELBQAwQjELMAkGA1UE +BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxITAfBgNVBAMTGHJvb3QuY2EudGVzdC5h +bmRyb2lkLm5ldDAeFw0xOTA5MzAxNzU1NTJaFw0yOTA5MjcxNzU1NTJaMEIxCzAJ +BgNVBAYTAlVTMRAwDgYDVQQKEwdBbmRyb2lkMSEwHwYDVQQDExhyb290LmNhLnRl +c3QuYW5kcm9pZC5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCT +q3hGF+JvLaB1xW7KGKmaxiQ7BxX2Sn7cbp7ggoVYXsFlBUuPPv3+Vg5PfPCPhsJ8 +/7w4HyKo3uc/vHs5HpQ7rSd9blhAkfmJci2ULLq73FB8Mix4CzPwMx29RrN1X9bU +z4G0vJMczIBGxbZ0uw7n8bKcXBV7AIeax+J8lseEZ3k8iSuBkUJqGIpPFKTqByFZ +A1Lvt47xkON5SZh6c/Oe+o6291wXaCOJUSAKv6PAWZkq9HeD2fqKA/ck9dBaz1M3 +YvzQ9V/7so3/dECjAfKia388h1I6XSGNUM+d5hpxMXpAFgG42eUXHpJ10OjDvSwd +7ZSC91/kRQewUomEKBK1AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P +AQH/BAQDAgEGMB0GA1UdDgQWBBRJn6hHhdeDY/dXpCKUfrFYQhKAGjANBgkqhkiG +9w0BAQsFAAOCAQEAig/94aGfHBhZuvbbhwAK4rUNpizmR567u0ZJ+QUEKyAlo9lT +ZWYHSm7qTAZYvPEjzTQIptnAlxCHePXh3Cfwgo+r82lhG2rcdI03iRyvHWjM8gyk +BXCJTi0Q08JHHpTP6GnAqpz58qEIFkk8P766zNXdhYrGPOydF+p7MFcb1Zv1gum3 +zmRLt0XUAMfjPUv1Bl8kTKFxH5lkMBLR1E0jnoJoTTfgRPrf9CuFSoh48n7YhoBT +KV75xZY8b8+SuB0v6BvQmkpKZGoxBjuVsShyG7q1+4JTAtwhiP7BlkDvVkaBEi7t +WIMFp2r2ZDisHgastNaeYFyzHYz9g1FCCrHQ4w== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java index 91ef7789e3..532be675aa 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java @@ -17,16 +17,22 @@ package android.net.ipsec.ike.cts; import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID; +import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_EAP_ONLY_AUTH; import static android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig; +import static android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignRemoteConfig; +import static android.net.ipsec.ike.IkeSessionParams.IkeAuthEapConfig; import static android.net.ipsec.ike.IkeSessionParams.IkeAuthPskConfig; import static android.system.OsConstants.AF_INET; import static android.system.OsConstants.AF_INET6; +import static android.telephony.TelephonyManager.APPTYPE_USIM; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import android.net.eap.EapSessionConfig; import android.net.ipsec.ike.IkeFqdnIdentification; import android.net.ipsec.ike.IkeIdentification; import android.net.ipsec.ike.IkeSaProposal; @@ -37,10 +43,14 @@ import android.net.ipsec.ike.IkeSessionParams.IkeConfigRequest; import androidx.test.ext.junit.runners.AndroidJUnit4; +import com.android.internal.net.ipsec.ike.testutils.CertUtils; + +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.net.InetAddress; +import java.security.cert.X509Certificate; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; @@ -76,6 +86,29 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { private static final IkeIdentification LOCAL_ID = new IkeFqdnIdentification(LOCAL_HOSTNAME); private static final IkeIdentification REMOTE_ID = new IkeFqdnIdentification(REMOTE_HOSTNAME); + private static final EapSessionConfig EAP_ALL_METHODS_CONFIG = + createEapOnlySafeMethodsBuilder() + .setEapMsChapV2Config(EAP_MSCHAPV2_USERNAME, EAP_MSCHAPV2_PASSWORD) + .build(); + private static final EapSessionConfig EAP_ONLY_SAFE_METHODS_CONFIG = + createEapOnlySafeMethodsBuilder().build(); + + private X509Certificate mServerCaCert; + + @Before + public void setUp() throws Exception { + mServerCaCert = CertUtils.createCertFromPemFile("server-a-self-signed-ca.pem"); + } + + private static EapSessionConfig.Builder createEapOnlySafeMethodsBuilder() { + return new EapSessionConfig.Builder() + .setEapIdentity(EAP_IDENTITY) + .setEapSimConfig(SUB_ID, APPTYPE_USIM) + .setEapAkaConfig(SUB_ID, APPTYPE_USIM) + .setEapAkaPrimeConfig( + SUB_ID, APPTYPE_USIM, NETWORK_NAME, true /* allowMismatchedNetworkNames */); + } + /** * Create a Builder that has minimum configurations to build an IkeSessionParams. * @@ -112,23 +145,6 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { assertArrayEquals(IKE_PSK, ((IkeAuthPskConfig) remoteConfig).getPsk()); } - private void verifySpecificPcscfConfigReqs( - HashSet expectedAddresses, IkeSessionParams sessionParams) { - Set resultAddresses = new HashSet<>(); - - for (IkeConfigRequest req : sessionParams.getConfigurationRequests()) { - if (req instanceof ConfigRequestIpv4PcscfServer - && ((ConfigRequestIpv4PcscfServer) req).getAddress() != null) { - resultAddresses.add(((ConfigRequestIpv4PcscfServer) req).getAddress()); - } else if (req instanceof ConfigRequestIpv6PcscfServer - && ((ConfigRequestIpv6PcscfServer) req).getAddress() != null) { - resultAddresses.add(((ConfigRequestIpv6PcscfServer) req).getAddress()); - } - } - - assertEquals(expectedAddresses, resultAddresses); - } - @Test public void testBuildWithMinimumSet() throws Exception { IkeSessionParams sessionParams = createIkeParamsBuilderMinimum().build(); @@ -232,22 +248,39 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { assertFalse(sessionParams.hasIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID)); } - @Test - public void testBuildWithPsk() throws Exception { - IkeSessionParams sessionParams = - new IkeSessionParams.Builder(sContext) - .setNetwork(sTunNetwork) - .setServerHostname(IPV4_ADDRESS_REMOTE.getHostAddress()) - .addSaProposal(SA_PROPOSAL) - .setLocalIdentification(LOCAL_ID) - .setRemoteIdentification(REMOTE_ID) - .setAuthPsk(IKE_PSK) - .build(); + /** + * Create a Builder that has minimum configurations to build an IkeSessionParams, except for + * authentication method. + */ + private IkeSessionParams.Builder createIkeParamsBuilderMinimumWithoutAuth() { + return new IkeSessionParams.Builder(sContext) + .setNetwork(sTunNetwork) + .setServerHostname(IPV4_ADDRESS_REMOTE.getHostAddress()) + .addSaProposal(SA_PROPOSAL) + .setLocalIdentification(LOCAL_ID) + .setRemoteIdentification(REMOTE_ID); + } + + /** + * Verify the minimum configurations to build an IkeSessionParams, except for authentication + * method. + * + * @see #createIkeParamsBuilderMinimumWithoutAuth + */ + private void verifyIkeParamsMinimumWithoutAuth(IkeSessionParams sessionParams) { assertEquals(sTunNetwork, sessionParams.getNetwork()); assertEquals(IPV4_ADDRESS_REMOTE.getHostAddress(), sessionParams.getServerHostname()); assertEquals(Arrays.asList(SA_PROPOSAL), sessionParams.getSaProposals()); assertEquals(LOCAL_ID, sessionParams.getLocalIdentification()); assertEquals(REMOTE_ID, sessionParams.getRemoteIdentification()); + } + + @Test + public void testBuildWithPsk() throws Exception { + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimumWithoutAuth().setAuthPsk(IKE_PSK).build(); + + verifyIkeParamsMinimumWithoutAuth(sessionParams); IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig(); assertTrue(localConfig instanceof IkeAuthPskConfig); @@ -257,6 +290,57 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { assertArrayEquals(IKE_PSK, ((IkeAuthPskConfig) remoteConfig).getPsk()); } - // TODO(b/148689509): Add tests for building IkeSessionParams using EAP and - // digital-signature-based authentication + @Test + public void testBuildWithEap() throws Exception { + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimumWithoutAuth() + .setAuthEap(mServerCaCert, EAP_ALL_METHODS_CONFIG) + .build(); + + verifyIkeParamsMinimumWithoutAuth(sessionParams); + + IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig(); + assertTrue(localConfig instanceof IkeAuthEapConfig); + assertEquals(EAP_ALL_METHODS_CONFIG, ((IkeAuthEapConfig) localConfig).getEapConfig()); + IkeAuthConfig remoteConfig = sessionParams.getRemoteAuthConfig(); + assertTrue(remoteConfig instanceof IkeAuthDigitalSignRemoteConfig); + assertEquals( + mServerCaCert, ((IkeAuthDigitalSignRemoteConfig) remoteConfig).getRemoteCaCert()); + } + + @Test + public void testBuildWithEapOnlyAuth() throws Exception { + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimumWithoutAuth() + .setAuthEap(mServerCaCert, EAP_ONLY_SAFE_METHODS_CONFIG) + .addIkeOption(IKE_OPTION_EAP_ONLY_AUTH) + .build(); + + assertTrue(sessionParams.hasIkeOption(IKE_OPTION_EAP_ONLY_AUTH)); + verifyIkeParamsMinimumWithoutAuth(sessionParams); + + IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig(); + assertTrue(localConfig instanceof IkeAuthEapConfig); + assertEquals(EAP_ONLY_SAFE_METHODS_CONFIG, ((IkeAuthEapConfig) localConfig).getEapConfig()); + IkeAuthConfig remoteConfig = sessionParams.getRemoteAuthConfig(); + assertTrue(remoteConfig instanceof IkeAuthDigitalSignRemoteConfig); + assertEquals( + mServerCaCert, ((IkeAuthDigitalSignRemoteConfig) remoteConfig).getRemoteCaCert()); + } + + @Test + public void testThrowBuildEapOnlyAuthWithUnsafeMethod() throws Exception { + try { + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimumWithoutAuth() + .setAuthEap(mServerCaCert, EAP_ALL_METHODS_CONFIG) + .addIkeOption(IKE_OPTION_EAP_ONLY_AUTH) + .build(); + fail("Expected to fail because EAP only unsafe method is proposed"); + } catch (IllegalArgumentException expected) { + } + } + + // TODO(b/148689509): Add tests for building IkeSessionParams using digital-signature-based + // authentication } diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java index 5f608df137..54c28e3a92 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java @@ -46,6 +46,12 @@ abstract class IkeTestBase { static final String LOCAL_HOSTNAME = "client.test.ike.android.net"; static final String REMOTE_HOSTNAME = "server.test.ike.android.net"; + static final int SUB_ID = 1; + static final byte[] EAP_IDENTITY = "test@android.net".getBytes(); + static final String NETWORK_NAME = "android.net"; + static final String EAP_MSCHAPV2_USERNAME = "username"; + static final String EAP_MSCHAPV2_PASSWORD = "password"; + static final Inet4Address IPV4_ADDRESS_LOCAL = (Inet4Address) (InetAddresses.parseNumericAddress("192.0.2.100")); static final Inet4Address IPV4_ADDRESS_REMOTE = From bba019dc40e57bf53ac07dc59f1d45f22e4cbfd0 Mon Sep 17 00:00:00 2001 From: evitayan Date: Sun, 12 Apr 2020 19:37:22 -0700 Subject: [PATCH 0932/1109] Test configuring digital-signature-based auth Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: Ieaceaadf116cb2885cbf22ae48579cec88268416 --- .../ipsec/assets/key/client-a-private-key.key | 28 +++++++++ .../ipsec/assets/pem/client-a-end-cert.pem | 21 +++++++ .../pem/client-a-intermediate-ca-one.pem | 21 +++++++ .../pem/client-a-intermediate-ca-two.pem | 21 +++++++ .../ipsec/ike/cts/IkeSessionParamsTest.java | 63 ++++++++++++++++++- 5 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 tests/cts/net/ipsec/assets/key/client-a-private-key.key create mode 100644 tests/cts/net/ipsec/assets/pem/client-a-end-cert.pem create mode 100644 tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-one.pem create mode 100644 tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-two.pem diff --git a/tests/cts/net/ipsec/assets/key/client-a-private-key.key b/tests/cts/net/ipsec/assets/key/client-a-private-key.key new file mode 100644 index 0000000000..22736e98e0 --- /dev/null +++ b/tests/cts/net/ipsec/assets/key/client-a-private-key.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCv3CvrCGokJSWL +8ufg6u9LCW4EezztbktqpC0T+1m98+Ujb8/eJ0L2UaxZ9QBSBAqXxEoeZFBeoCXu +7ezUd5qUPfIhKLAkQTAyU/KgfhHh4i+MJK5ghPbGDE8r2gKUXOkM6M5//ZCpmu0K +Y/9uQL6D5bkxEaoWegEO+wSXm+hTTgKDtQKHvRibgdcZkcY0cA9JsLrC/nIkP+7i +pbBT+VTuV6gAnKIV0nq8zvI3A/Z3nAb5Gt0g3qaqs59StDT0QtuXzJkuZEo3XSrS +jon+8NjSNzqVbJj95B7+uiH+91VEbMtJYFz2MipKvJQDK7Zlxke7LxRj2xJfksJK +a92/ncxfAgMBAAECggEAQztaMvW5lm35J8LKsWs/5qEJRX9T8LWs8W0oqq36Riub +G2wgvR6ndAIPcSjAYZqX7iOl7m6NZ0+0kN63HxdGqovwKIskpAekBGmhpYftED1n +zh0r6UyMB3UnQ22KdOv8UOokIDxxdNX8728BdUYdT9Ggdkj5jLRB+VcwD0IUlNvo +zzTpURV9HEd87uiLqd4AAHXSI0lIHI5U43z24HI/J6/YbYHT3Rlh6CIa/LuwO6vL +gFkgqg0/oy6yJtjrHtzNVA67F0UaH62hR4YFgbC0d955SJnDidWOv/0j2DMpfdCc +9kFAcPwUSyykvUSLnGIKWSG4D+6gzIeAeUx4oO7kMQKBgQDVNRkX8AGTHyLg+NXf +spUWWcodwVioXl30Q7h6+4bt8OI61UbhQ7wX61wvJ1cySpa2KOYa2UdagQVhGhhL +ADu363R77uXF/jZgzVfmjjyJ2nfDqRgHWRTlSkuq/jCOQCz7VIPHRZg5WL/9D4ms +TAqMjpzqeMfFZI+w4/+xpcJIuQKBgQDTKBy+ZuerWrVT9icWKvLU58o5EVj/2yFy +GJvKm+wRAAX2WzjNnR4HVd4DmMREVz1BPYby0j5gqjvtDsxYYu39+NT7JvMioLLK +QPj+7k5geYgNqVgCxB1vP89RhY2X1RLrN9sTXOodgFPeXOQWNYITkGp3eQpx4nTJ ++K/al3oB1wKBgAjnc8nVIyuyxDEjE0OJYMKTM2a0uXAmqMPXxC+Wq5bqVXhhidlE +i+lv0eTCPtkB1nN7F8kNQ/aaps/cWCFhvBy9P5shagUvzbOTP9WIIS0cq53HRRKh +fMbqqGhWv05hjb9dUzeSR341n6cA7B3++v3Nwu3j52vt/DZF/1q68nc5AoGAS0SU +ImbKE/GsizZGLoe2sZ/CHN+LKwCwhlwxRGKaHmE0vuE7eUeVSaYZEo0lAPtb8WJ+ +NRYueASWgeTxgFwbW5mUScZTirdfo+rPFwhZVdhcYApKPgosN9i2DOgfVcz1BnWN +mPRY25U/0BaqkyQVruWeneG+kGPZn5kPDktKiVcCgYEAkzwU9vCGhm7ZVALvx/zR +wARz2zsL9ImBc0P4DK1ld8g90FEnHrEgeI9JEwz0zFHOCMLwlk7kG0Xev7vfjZ7G +xSqtQYOH33Qp6rtBOgdt8hSyDFvakvDl6bqhAw52gelO3MTpAB1+ZsfZ5gFx13Jf +idNFcaIrC52PtZIH7QCzdDY= +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/tests/cts/net/ipsec/assets/pem/client-a-end-cert.pem b/tests/cts/net/ipsec/assets/pem/client-a-end-cert.pem new file mode 100644 index 0000000000..e82da85c50 --- /dev/null +++ b/tests/cts/net/ipsec/assets/pem/client-a-end-cert.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDaDCCAlCgAwIBAgIIcorRI3n29E4wDQYJKoZIhvcNAQELBQAwQTELMAkGA1UE +BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxIDAeBgNVBAMTF3R3by5jYS50ZXN0LmFu +ZHJvaWQubmV0MB4XDTIwMDQxNDA1MDM0OVoXDTIzMDQxNDA1MDM0OVowRTELMAkG +A1UEBhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxJDAiBgNVBAMTG2NsaWVudC50ZXN0 +LmlrZS5hbmRyb2lkLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AK/cK+sIaiQlJYvy5+Dq70sJbgR7PO1uS2qkLRP7Wb3z5SNvz94nQvZRrFn1AFIE +CpfESh5kUF6gJe7t7NR3mpQ98iEosCRBMDJT8qB+EeHiL4wkrmCE9sYMTyvaApRc +6Qzozn/9kKma7Qpj/25AvoPluTERqhZ6AQ77BJeb6FNOAoO1Aoe9GJuB1xmRxjRw +D0mwusL+ciQ/7uKlsFP5VO5XqACcohXSerzO8jcD9necBvka3SDepqqzn1K0NPRC +25fMmS5kSjddKtKOif7w2NI3OpVsmP3kHv66If73VURsy0lgXPYyKkq8lAMrtmXG +R7svFGPbEl+Swkpr3b+dzF8CAwEAAaNgMF4wHwYDVR0jBBgwFoAUcqSu1uRYT/DL +bLoDNUz38nGvCKQwJgYDVR0RBB8wHYIbY2xpZW50LnRlc3QuaWtlLmFuZHJvaWQu +bmV0MBMGA1UdJQQMMAoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQCa53tK +I9RM9/MutZ5KNG2Gfs2cqaPyv8ZRhs90HDWZhkFVu7prywJAxOd2hxxHPsvgurio +4bKAxnT4EXevgz5YoCbj2TPIL9TdFYh59zZ97XXMxk+SRdypgF70M6ETqKPs3hDP +ZRMMoHvvYaqaPvp4StSBX9A44gSyjHxVYJkrjDZ0uffKg5lFL5IPvqfdmSRSpGab +SyGTP4OLTy0QiNV3pBsJGdl0h5BzuTPR9OTl4xgeqqBQy2bDjmfJBuiYyCSCkPi7 +T3ohDYCymhuSkuktHPNG1aKllUJaw0tuZuNydlgdAveXPYfM36uvK0sfd9qr9pAy +rmkYV2MAWguFeckh +-----END CERTIFICATE----- \ No newline at end of file diff --git a/tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-one.pem b/tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-one.pem new file mode 100644 index 0000000000..707e575bc3 --- /dev/null +++ b/tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-one.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDaDCCAlCgAwIBAgIIIbjMyRn2770wDQYJKoZIhvcNAQELBQAwQjELMAkGA1UE +BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxITAfBgNVBAMTGHJvb3QuY2EudGVzdC5h +bmRyb2lkLm5ldDAeFw0xOTA5MzAxODQzMThaFw0yNDA5MjgxODQzMThaMEExCzAJ +BgNVBAYTAlVTMRAwDgYDVQQKEwdBbmRyb2lkMSAwHgYDVQQDExdvbmUuY2EudGVz +dC5hbmRyb2lkLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNN +sRr5Z30rAEw2jrAh/BIekbEy/MvOucAr1w0lxH71p+ybRBx5Bj7G07UGXbL659gm +meMV6nabY4HjQXNMq22POiJBZj+U+rw34br6waljBttxCmmJac1VvgqNsSspXjRy +NbiVQdFjyKSX0NOPcEkwANk15mZbOgJBaYYc8jQCY2G/p8eARVBTLJCy8LEwEU6j +XRv/4eYST79qpBFc7gQQj2FLmh9oppDIvcIVBHwtd1tBoVuehRSud1o8vQRkl/HJ +Mrwp24nO5YYhmVNSFRtBpmWMSu1KknFUwkOebINUNsKXXHebVa7cP4XIQUL8mRT3 +5X9rFJFSQJE01S3NjNMCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B +Af8EBAMCAQYwHQYDVR0OBBYEFHK3FIm7g8dxEIwK9zMAO8EWhRYxMB8GA1UdIwQY +MBaAFEmfqEeF14Nj91ekIpR+sVhCEoAaMA0GCSqGSIb3DQEBCwUAA4IBAQAeMlXT +TnxZo8oz0204gKZ63RzlgDpJ7SqA3qFG+pV+TiqGfSuVkXuIdOskjxJnA9VxUzrr +LdMTCn5e0FK6wCYjZ2GT/CD7oD3vSMkzGbLGNcNJhhDHUq8BOLPkPzz/rwQFPBSb +zr6hsiVXphEt/psGoN7Eu9blPeQaIwMfWnaufAwF664S/3dmCRbNMWSam1qzzz8q +jr0cDOIMa//ZIAcM16cvoBK6pFGnUmuoJYYRtfpY5MmfCWz0sCJxENIX/lxyhd7N +FdRALA1ZP3E//Tn2vQoeFjbKaAba527RE26HgHJ9zZDo1nn8J8J/YwYRJdBWM/3S +LYebNiMtcyB5nIkj +-----END CERTIFICATE----- \ No newline at end of file diff --git a/tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-two.pem b/tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-two.pem new file mode 100644 index 0000000000..39808f885e --- /dev/null +++ b/tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-two.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIIKWCREnNCs+wwDQYJKoZIhvcNAQELBQAwQTELMAkGA1UE +BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxIDAeBgNVBAMTF29uZS5jYS50ZXN0LmFu +ZHJvaWQubmV0MB4XDTE5MDkzMDE4NDQwMloXDTI0MDkyODE4NDQwMlowQTELMAkG +A1UEBhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxIDAeBgNVBAMTF3R3by5jYS50ZXN0 +LmFuZHJvaWQubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxLUa +RqkYl2m7lUmMnkooqO0DNNY1aN9r7mJc3ndYn5gjkpb3yLgOYPDNLcQerV6uWk/u +qKudNHed2dInGonl3oxwwv7++6oUvvtrSWLDZlRg16GsdIE1Y98DSMQWkSxevYy9 +Nh6FGTdlBFQVMpiMa8qHEkrOyKsy85yCW1sgzlpGTIBwbDAqYtwe3rgbwyHwUtfy +0EU++DBcR4ll/pDqB0OQtW5E3AOq2GH1iaGeFLKSUQ5KAbdI8y4/b8IkSDffvxcc +kXig7S54aLrNlL/ZjQ+H4Chgjj2A5wMucd81+Fb60Udej73ICL9PpMPnXQ1+BVYd +MJ/txjLNmrOJG9yEHQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB +/wQEAwIBBjAdBgNVHQ4EFgQUcqSu1uRYT/DLbLoDNUz38nGvCKQwHwYDVR0jBBgw +FoAUcrcUibuDx3EQjAr3MwA7wRaFFjEwDQYJKoZIhvcNAQELBQADggEBADY461GT +Rw0dGnD07xaGJcI0i0pV+WnGSrl1s1PAIdMYihJAqYnh10fXbFXLm2WMWVmv/pxs +FI/xDJno+pd4mCa/sIhm63ar/Nv+lFQmcpIlvSlKnhhV4SLNBeqbVhPBGTCHfrG4 +aIyCwm1KJsnkWbf03crhSskR/2CXIjX6lcAy7K3fE2u1ELpAdH0kMJR7VXkLFLUm +gqe9YCluR0weMpe2sCaOGzdVzQSmMMCzGP5cxeFR5U6K40kMOpiW11JNmQ06xI/m +YVkMNwoiV/ITT0/C/g9FxJmkO0mVSLEqxaLS/hNiQNDlroVM0rbxhzviXLI3R3AO +50VvlOQYGxWed/I= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java index 532be675aa..6fc7cb3634 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java @@ -19,6 +19,7 @@ package android.net.ipsec.ike.cts; import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID; import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_EAP_ONLY_AUTH; import static android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig; +import static android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignLocalConfig; import static android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignRemoteConfig; import static android.net.ipsec.ike.IkeSessionParams.IkeAuthEapConfig; import static android.net.ipsec.ike.IkeSessionParams.IkeAuthPskConfig; @@ -51,9 +52,12 @@ import org.junit.runner.RunWith; import java.net.InetAddress; import java.security.cert.X509Certificate; +import java.security.interfaces.RSAPrivateKey; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -94,10 +98,20 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { createEapOnlySafeMethodsBuilder().build(); private X509Certificate mServerCaCert; + private X509Certificate mClientEndCert; + private X509Certificate mClientIntermediateCaCertOne; + private X509Certificate mClientIntermediateCaCertTwo; + private RSAPrivateKey mClientPrivateKey; @Before public void setUp() throws Exception { mServerCaCert = CertUtils.createCertFromPemFile("server-a-self-signed-ca.pem"); + mClientEndCert = CertUtils.createCertFromPemFile("client-a-end-cert.pem"); + mClientIntermediateCaCertOne = + CertUtils.createCertFromPemFile("client-a-intermediate-ca-one.pem"); + mClientIntermediateCaCertTwo = + CertUtils.createCertFromPemFile("client-a-intermediate-ca-two.pem"); + mClientPrivateKey = CertUtils.createRsaPrivateKeyFromKeyFile("client-a-private-key.key"); } private static EapSessionConfig.Builder createEapOnlySafeMethodsBuilder() { @@ -341,6 +355,51 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { } } - // TODO(b/148689509): Add tests for building IkeSessionParams using digital-signature-based - // authentication + @Test + public void testBuildWithDigitalSignature() throws Exception { + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimumWithoutAuth() + .setAuthDigitalSignature(mServerCaCert, mClientEndCert, mClientPrivateKey) + .build(); + + verifyIkeParamsMinimumWithoutAuth(sessionParams); + + IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig(); + assertTrue(localConfig instanceof IkeAuthDigitalSignLocalConfig); + IkeAuthDigitalSignLocalConfig localSignConfig = (IkeAuthDigitalSignLocalConfig) localConfig; + assertEquals(mClientEndCert, localSignConfig.getClientEndCertificate()); + assertEquals(Collections.EMPTY_LIST, localSignConfig.getIntermediateCertificates()); + assertEquals(mClientPrivateKey, localSignConfig.getPrivateKey()); + + IkeAuthConfig remoteConfig = sessionParams.getRemoteAuthConfig(); + assertTrue(remoteConfig instanceof IkeAuthDigitalSignRemoteConfig); + assertEquals( + mServerCaCert, ((IkeAuthDigitalSignRemoteConfig) remoteConfig).getRemoteCaCert()); + } + + @Test + public void testBuildWithDigitalSignatureAndIntermediateCerts() throws Exception { + List intermediateCerts = + Arrays.asList(mClientIntermediateCaCertOne, mClientIntermediateCaCertTwo); + + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimumWithoutAuth() + .setAuthDigitalSignature( + mServerCaCert, mClientEndCert, intermediateCerts, mClientPrivateKey) + .build(); + + verifyIkeParamsMinimumWithoutAuth(sessionParams); + + IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig(); + assertTrue(localConfig instanceof IkeAuthDigitalSignLocalConfig); + IkeAuthDigitalSignLocalConfig localSignConfig = (IkeAuthDigitalSignLocalConfig) localConfig; + assertEquals(mClientEndCert, localSignConfig.getClientEndCertificate()); + assertEquals(intermediateCerts, localSignConfig.getIntermediateCertificates()); + assertEquals(mClientPrivateKey, localSignConfig.getPrivateKey()); + + IkeAuthConfig remoteConfig = sessionParams.getRemoteAuthConfig(); + assertTrue(remoteConfig instanceof IkeAuthDigitalSignRemoteConfig); + assertEquals( + mServerCaCert, ((IkeAuthDigitalSignRemoteConfig) remoteConfig).getRemoteCaCert()); + } } From 2b2db7a57f6fbcb548ce762e5303f3100fbf556b Mon Sep 17 00:00:00 2001 From: Yan Yan Date: Thu, 23 Apr 2020 23:20:28 +0000 Subject: [PATCH 0933/1109] Make a copy of TunUtils and PacketUtils Temporarily make copies. Eventually will statically include the source files in CtsIkeTestCases Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: I7dd5c8b849f0d987fa6d76bc5a0bc1a7eed49b0d Merged-In: I7dd5c8b849f0d987fa6d76bc5a0bc1a7eed49b0d (cherry picked from commit 52716ec0e6807e7c7c78d9789788a0de2bab8b06) --- .../net/ipsec/ike/cts/PacketUtils.java | 467 ++++++++++++++++++ .../android/net/ipsec/ike/cts/TunUtils.java | 264 ++++++++++ 2 files changed, 731 insertions(+) create mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/PacketUtils.java create mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TunUtils.java diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/PacketUtils.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/PacketUtils.java new file mode 100644 index 0000000000..35e6719fb7 --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/PacketUtils.java @@ -0,0 +1,467 @@ +/* + * 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.ipsec.ike.cts; + +import static android.system.OsConstants.IPPROTO_IPV6; +import static android.system.OsConstants.IPPROTO_UDP; + +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.nio.ByteBuffer; +import java.nio.ShortBuffer; +import java.security.GeneralSecurityException; +import java.security.SecureRandom; +import java.util.Arrays; + +import javax.crypto.Cipher; +import javax.crypto.Mac; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +/** + * This code is a exact copy of {@link PacketUtils} in + * cts/tests/tests/net/src/android/net/cts/PacketUtils.java. + * + *

    TODO(b/148689509): Statically include the PacketUtils source file instead of copying it. + */ +public class PacketUtils { + private static final String TAG = PacketUtils.class.getSimpleName(); + + private static final int DATA_BUFFER_LEN = 4096; + + static final int IP4_HDRLEN = 20; + static final int IP6_HDRLEN = 40; + static final int UDP_HDRLEN = 8; + static final int TCP_HDRLEN = 20; + static final int TCP_HDRLEN_WITH_TIMESTAMP_OPT = TCP_HDRLEN + 12; + + // Not defined in OsConstants + static final int IPPROTO_IPV4 = 4; + static final int IPPROTO_ESP = 50; + + // Encryption parameters + static final int AES_GCM_IV_LEN = 8; + static final int AES_CBC_IV_LEN = 16; + static final int AES_GCM_BLK_SIZE = 4; + static final int AES_CBC_BLK_SIZE = 16; + + // Encryption algorithms + static final String AES = "AES"; + static final String AES_CBC = "AES/CBC/NoPadding"; + static final String HMAC_SHA_256 = "HmacSHA256"; + + public interface Payload { + byte[] getPacketBytes(IpHeader header) throws Exception; + + void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) throws Exception; + + short length(); + + int getProtocolId(); + } + + public abstract static class IpHeader { + + public final byte proto; + public final InetAddress srcAddr; + public final InetAddress dstAddr; + public final Payload payload; + + public IpHeader(int proto, InetAddress src, InetAddress dst, Payload payload) { + this.proto = (byte) proto; + this.srcAddr = src; + this.dstAddr = dst; + this.payload = payload; + } + + public abstract byte[] getPacketBytes() throws Exception; + + public abstract int getProtocolId(); + } + + public static class Ip4Header extends IpHeader { + private short checksum; + + public Ip4Header(int proto, Inet4Address src, Inet4Address dst, Payload payload) { + super(proto, src, dst, payload); + } + + public byte[] getPacketBytes() throws Exception { + ByteBuffer resultBuffer = buildHeader(); + payload.addPacketBytes(this, resultBuffer); + + return getByteArrayFromBuffer(resultBuffer); + } + + public ByteBuffer buildHeader() { + ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN); + + // Version, IHL + bb.put((byte) (0x45)); + + // DCSP, ECN + bb.put((byte) 0); + + // Total Length + bb.putShort((short) (IP4_HDRLEN + payload.length())); + + // Empty for Identification, Flags and Fragment Offset + bb.putShort((short) 0); + bb.put((byte) 0x40); + bb.put((byte) 0x00); + + // TTL + bb.put((byte) 64); + + // Protocol + bb.put(proto); + + // Header Checksum + final int ipChecksumOffset = bb.position(); + bb.putShort((short) 0); + + // Src/Dst addresses + bb.put(srcAddr.getAddress()); + bb.put(dstAddr.getAddress()); + + bb.putShort(ipChecksumOffset, calculateChecksum(bb)); + + return bb; + } + + private short calculateChecksum(ByteBuffer bb) { + int checksum = 0; + + // Calculate sum of 16-bit values, excluding checksum. IPv4 headers are always 32-bit + // aligned, so no special cases needed for unaligned values. + ShortBuffer shortBuffer = ByteBuffer.wrap(getByteArrayFromBuffer(bb)).asShortBuffer(); + while (shortBuffer.hasRemaining()) { + short val = shortBuffer.get(); + + // Wrap as needed + checksum = addAndWrapForChecksum(checksum, val); + } + + return onesComplement(checksum); + } + + public int getProtocolId() { + return IPPROTO_IPV4; + } + } + + public static class Ip6Header extends IpHeader { + public Ip6Header(int nextHeader, Inet6Address src, Inet6Address dst, Payload payload) { + super(nextHeader, src, dst, payload); + } + + public byte[] getPacketBytes() throws Exception { + ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN); + + // Version | Traffic Class (First 4 bits) + bb.put((byte) 0x60); + + // Traffic class (Last 4 bits), Flow Label + bb.put((byte) 0); + bb.put((byte) 0); + bb.put((byte) 0); + + // Payload Length + bb.putShort((short) payload.length()); + + // Next Header + bb.put(proto); + + // Hop Limit + bb.put((byte) 64); + + // Src/Dst addresses + bb.put(srcAddr.getAddress()); + bb.put(dstAddr.getAddress()); + + // Payload + payload.addPacketBytes(this, bb); + + return getByteArrayFromBuffer(bb); + } + + public int getProtocolId() { + return IPPROTO_IPV6; + } + } + + public static class BytePayload implements Payload { + public final byte[] payload; + + public BytePayload(byte[] payload) { + this.payload = payload; + } + + public int getProtocolId() { + return -1; + } + + public byte[] getPacketBytes(IpHeader header) { + ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN); + + addPacketBytes(header, bb); + return getByteArrayFromBuffer(bb); + } + + public void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) { + resultBuffer.put(payload); + } + + public short length() { + return (short) payload.length; + } + } + + public static class UdpHeader implements Payload { + + public final short srcPort; + public final short dstPort; + public final Payload payload; + + public UdpHeader(int srcPort, int dstPort, Payload payload) { + this.srcPort = (short) srcPort; + this.dstPort = (short) dstPort; + this.payload = payload; + } + + public int getProtocolId() { + return IPPROTO_UDP; + } + + public short length() { + return (short) (payload.length() + 8); + } + + public byte[] getPacketBytes(IpHeader header) throws Exception { + ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN); + + addPacketBytes(header, bb); + return getByteArrayFromBuffer(bb); + } + + public void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) throws Exception { + // Source, Destination port + resultBuffer.putShort(srcPort); + resultBuffer.putShort(dstPort); + + // Payload Length + resultBuffer.putShort(length()); + + // Get payload bytes for checksum + payload + ByteBuffer payloadBuffer = ByteBuffer.allocate(DATA_BUFFER_LEN); + payload.addPacketBytes(header, payloadBuffer); + byte[] payloadBytes = getByteArrayFromBuffer(payloadBuffer); + + // Checksum + resultBuffer.putShort(calculateChecksum(header, payloadBytes)); + + // Payload + resultBuffer.put(payloadBytes); + } + + private short calculateChecksum(IpHeader header, byte[] payloadBytes) throws Exception { + int newChecksum = 0; + ShortBuffer srcBuffer = ByteBuffer.wrap(header.srcAddr.getAddress()).asShortBuffer(); + ShortBuffer dstBuffer = ByteBuffer.wrap(header.dstAddr.getAddress()).asShortBuffer(); + + while (srcBuffer.hasRemaining() || dstBuffer.hasRemaining()) { + short val = srcBuffer.hasRemaining() ? srcBuffer.get() : dstBuffer.get(); + + // Wrap as needed + newChecksum = addAndWrapForChecksum(newChecksum, val); + } + + // Add pseudo-header values. Proto is 0-padded, so just use the byte. + newChecksum = addAndWrapForChecksum(newChecksum, header.proto); + newChecksum = addAndWrapForChecksum(newChecksum, length()); + newChecksum = addAndWrapForChecksum(newChecksum, srcPort); + newChecksum = addAndWrapForChecksum(newChecksum, dstPort); + newChecksum = addAndWrapForChecksum(newChecksum, length()); + + ShortBuffer payloadShortBuffer = ByteBuffer.wrap(payloadBytes).asShortBuffer(); + while (payloadShortBuffer.hasRemaining()) { + newChecksum = addAndWrapForChecksum(newChecksum, payloadShortBuffer.get()); + } + if (payload.length() % 2 != 0) { + newChecksum = + addAndWrapForChecksum( + newChecksum, (payloadBytes[payloadBytes.length - 1] << 8)); + } + + return onesComplement(newChecksum); + } + } + + public static class EspHeader implements Payload { + public final int nextHeader; + public final int spi; + public final int seqNum; + public final byte[] key; + public final byte[] payload; + + /** + * Generic constructor for ESP headers. + * + *

    For Tunnel mode, payload will be a full IP header + attached payloads + * + *

    For Transport mode, payload will be only the attached payloads, but with the checksum + * calculated using the pre-encryption IP header + */ + public EspHeader(int nextHeader, int spi, int seqNum, byte[] key, byte[] payload) { + this.nextHeader = nextHeader; + this.spi = spi; + this.seqNum = seqNum; + this.key = key; + this.payload = payload; + } + + public int getProtocolId() { + return IPPROTO_ESP; + } + + public short length() { + // ALWAYS uses AES-CBC, HMAC-SHA256 (128b trunc len) + return (short) + calculateEspPacketSize(payload.length, AES_CBC_IV_LEN, AES_CBC_BLK_SIZE, 128); + } + + public byte[] getPacketBytes(IpHeader header) throws Exception { + ByteBuffer bb = ByteBuffer.allocate(DATA_BUFFER_LEN); + + addPacketBytes(header, bb); + return getByteArrayFromBuffer(bb); + } + + public void addPacketBytes(IpHeader header, ByteBuffer resultBuffer) throws Exception { + ByteBuffer espPayloadBuffer = ByteBuffer.allocate(DATA_BUFFER_LEN); + espPayloadBuffer.putInt(spi); + espPayloadBuffer.putInt(seqNum); + espPayloadBuffer.put(getCiphertext(key)); + + espPayloadBuffer.put(getIcv(getByteArrayFromBuffer(espPayloadBuffer)), 0, 16); + resultBuffer.put(getByteArrayFromBuffer(espPayloadBuffer)); + } + + private byte[] getIcv(byte[] authenticatedSection) throws GeneralSecurityException { + Mac sha256HMAC = Mac.getInstance(HMAC_SHA_256); + SecretKeySpec authKey = new SecretKeySpec(key, HMAC_SHA_256); + sha256HMAC.init(authKey); + + return sha256HMAC.doFinal(authenticatedSection); + } + + /** + * Encrypts and builds ciphertext block. Includes the IV, Padding and Next-Header blocks + * + *

    The ciphertext does NOT include the SPI/Sequence numbers, or the ICV. + */ + private byte[] getCiphertext(byte[] key) throws GeneralSecurityException { + int paddedLen = calculateEspEncryptedLength(payload.length, AES_CBC_BLK_SIZE); + ByteBuffer paddedPayload = ByteBuffer.allocate(paddedLen); + paddedPayload.put(payload); + + // Add padding - consecutive integers from 0x01 + int pad = 1; + while (paddedPayload.position() < paddedPayload.limit()) { + paddedPayload.put((byte) pad++); + } + + paddedPayload.position(paddedPayload.limit() - 2); + paddedPayload.put((byte) (paddedLen - 2 - payload.length)); // Pad length + paddedPayload.put((byte) nextHeader); + + // Generate Initialization Vector + byte[] iv = new byte[AES_CBC_IV_LEN]; + new SecureRandom().nextBytes(iv); + IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); + SecretKeySpec secretKeySpec = new SecretKeySpec(key, AES); + + // Encrypt payload + Cipher cipher = Cipher.getInstance(AES_CBC); + cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); + byte[] encrypted = cipher.doFinal(getByteArrayFromBuffer(paddedPayload)); + + // Build ciphertext + ByteBuffer cipherText = ByteBuffer.allocate(AES_CBC_IV_LEN + encrypted.length); + cipherText.put(iv); + cipherText.put(encrypted); + + return getByteArrayFromBuffer(cipherText); + } + } + + private static int addAndWrapForChecksum(int currentChecksum, int value) { + currentChecksum += value & 0x0000ffff; + + // Wrap anything beyond the first 16 bits, and add to lower order bits + return (currentChecksum >>> 16) + (currentChecksum & 0x0000ffff); + } + + private static short onesComplement(int val) { + val = (val >>> 16) + (val & 0xffff); + + if (val == 0) return 0; + return (short) ((~val) & 0xffff); + } + + public static int calculateEspPacketSize( + int payloadLen, int cryptIvLength, int cryptBlockSize, int authTruncLen) { + final int ESP_HDRLEN = 4 + 4; // SPI + Seq# + final int ICV_LEN = authTruncLen / 8; // Auth trailer; based on truncation length + payloadLen += cryptIvLength; // Initialization Vector + + // Align to block size of encryption algorithm + payloadLen = calculateEspEncryptedLength(payloadLen, cryptBlockSize); + return payloadLen + ESP_HDRLEN + ICV_LEN; + } + + private static int calculateEspEncryptedLength(int payloadLen, int cryptBlockSize) { + payloadLen += 2; // ESP trailer + + // Align to block size of encryption algorithm + return payloadLen + calculateEspPadLen(payloadLen, cryptBlockSize); + } + + private static int calculateEspPadLen(int payloadLen, int cryptBlockSize) { + return (cryptBlockSize - (payloadLen % cryptBlockSize)) % cryptBlockSize; + } + + private static byte[] getByteArrayFromBuffer(ByteBuffer buffer) { + return Arrays.copyOfRange(buffer.array(), 0, buffer.position()); + } + + /* + * Debug printing + */ + private static final char[] hexArray = "0123456789ABCDEF".toCharArray(); + + public static String bytesToHex(byte[] bytes) { + StringBuilder sb = new StringBuilder(); + for (byte b : bytes) { + sb.append(hexArray[b >>> 4]); + sb.append(hexArray[b & 0x0F]); + sb.append(' '); + } + return sb.toString(); + } +} diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TunUtils.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TunUtils.java new file mode 100644 index 0000000000..71450ea9c0 --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TunUtils.java @@ -0,0 +1,264 @@ +/* + * 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.ipsec.ike.cts; + +import static android.net.ipsec.ike.cts.PacketUtils.IP4_HDRLEN; +import static android.net.ipsec.ike.cts.PacketUtils.IP6_HDRLEN; +import static android.net.ipsec.ike.cts.PacketUtils.IPPROTO_ESP; +import static android.net.ipsec.ike.cts.PacketUtils.UDP_HDRLEN; +import static android.system.OsConstants.IPPROTO_UDP; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.fail; + +import android.os.ParcelFileDescriptor; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.function.Predicate; + +/** + * This code is a exact copy of {@link TunUtils} in + * cts/tests/tests/net/src/android/net/cts/TunUtils.java, except the import path of PacketUtils is + * the path to the copy of PacktUtils. + * + *

    TODO(b/148689509): Statically include the TunUtils source file instead of copying it. + */ +public class TunUtils { + private static final String TAG = TunUtils.class.getSimpleName(); + + private static final int DATA_BUFFER_LEN = 4096; + private static final int TIMEOUT = 100; + + private static final int IP4_PROTO_OFFSET = 9; + private static final int IP6_PROTO_OFFSET = 6; + + private static final int IP4_ADDR_OFFSET = 12; + private static final int IP4_ADDR_LEN = 4; + private static final int IP6_ADDR_OFFSET = 8; + private static final int IP6_ADDR_LEN = 16; + + private final ParcelFileDescriptor mTunFd; + private final List mPackets = new ArrayList<>(); + private final Thread mReaderThread; + + public TunUtils(ParcelFileDescriptor tunFd) { + mTunFd = tunFd; + + // Start background reader thread + mReaderThread = + new Thread( + () -> { + try { + // Loop will exit and thread will quit when tunFd is closed. + // Receiving either EOF or an exception will exit this reader loop. + // FileInputStream in uninterruptable, so there's no good way to + // ensure that this thread shuts down except upon FD closure. + while (true) { + byte[] intercepted = receiveFromTun(); + if (intercepted == null) { + // Exit once we've hit EOF + return; + } else if (intercepted.length > 0) { + // Only save packet if we've received any bytes. + synchronized (mPackets) { + mPackets.add(intercepted); + mPackets.notifyAll(); + } + } + } + } catch (IOException ignored) { + // Simply exit this reader thread + return; + } + }); + mReaderThread.start(); + } + + private byte[] receiveFromTun() throws IOException { + FileInputStream in = new FileInputStream(mTunFd.getFileDescriptor()); + byte[] inBytes = new byte[DATA_BUFFER_LEN]; + int bytesRead = in.read(inBytes); + + if (bytesRead < 0) { + return null; // return null for EOF + } else if (bytesRead >= DATA_BUFFER_LEN) { + throw new IllegalStateException("Too big packet. Fragmentation unsupported"); + } + return Arrays.copyOf(inBytes, bytesRead); + } + + private byte[] getFirstMatchingPacket(Predicate verifier, int startIndex) { + synchronized (mPackets) { + for (int i = startIndex; i < mPackets.size(); i++) { + byte[] pkt = mPackets.get(i); + if (verifier.test(pkt)) { + return pkt; + } + } + } + return null; + } + + /** + * Checks if the specified bytes were ever sent in plaintext. + * + *

    Only checks for known plaintext bytes to prevent triggering on ICMP/RA packets or the like + * + * @param plaintext the plaintext bytes to check for + * @param startIndex the index in the list to check for + */ + public boolean hasPlaintextPacket(byte[] plaintext, int startIndex) { + Predicate verifier = + (pkt) -> { + return Collections.indexOfSubList(Arrays.asList(pkt), Arrays.asList(plaintext)) + != -1; + }; + return getFirstMatchingPacket(verifier, startIndex) != null; + } + + public byte[] getEspPacket(int spi, boolean encap, int startIndex) { + return getFirstMatchingPacket( + (pkt) -> { + return isEsp(pkt, spi, encap); + }, + startIndex); + } + + public byte[] awaitEspPacketNoPlaintext( + int spi, byte[] plaintext, boolean useEncap, int expectedPacketSize) throws Exception { + long endTime = System.currentTimeMillis() + TIMEOUT; + int startIndex = 0; + + synchronized (mPackets) { + while (System.currentTimeMillis() < endTime) { + byte[] espPkt = getEspPacket(spi, useEncap, startIndex); + if (espPkt != null) { + // Validate packet size + assertEquals(expectedPacketSize, espPkt.length); + + // Always check plaintext from start + assertFalse(hasPlaintextPacket(plaintext, 0)); + return espPkt; // We've found the packet we're looking for. + } + + startIndex = mPackets.size(); + + // Try to prevent waiting too long. If waitTimeout <= 0, we've already hit timeout + long waitTimeout = endTime - System.currentTimeMillis(); + if (waitTimeout > 0) { + mPackets.wait(waitTimeout); + } + } + + fail("No such ESP packet found with SPI " + spi); + } + return null; + } + + private static boolean isSpiEqual(byte[] pkt, int espOffset, int spi) { + // Check SPI byte by byte. + return pkt[espOffset] == (byte) ((spi >>> 24) & 0xff) + && pkt[espOffset + 1] == (byte) ((spi >>> 16) & 0xff) + && pkt[espOffset + 2] == (byte) ((spi >>> 8) & 0xff) + && pkt[espOffset + 3] == (byte) (spi & 0xff); + } + + private static boolean isEsp(byte[] pkt, int spi, boolean encap) { + if (isIpv6(pkt)) { + // IPv6 UDP encap not supported by kernels; assume non-encap. + return pkt[IP6_PROTO_OFFSET] == IPPROTO_ESP && isSpiEqual(pkt, IP6_HDRLEN, spi); + } else { + // Use default IPv4 header length (assuming no options) + if (encap) { + return pkt[IP4_PROTO_OFFSET] == IPPROTO_UDP + && isSpiEqual(pkt, IP4_HDRLEN + UDP_HDRLEN, spi); + } else { + return pkt[IP4_PROTO_OFFSET] == IPPROTO_ESP && isSpiEqual(pkt, IP4_HDRLEN, spi); + } + } + } + + private static boolean isIpv6(byte[] pkt) { + // First nibble shows IP version. 0x60 for IPv6 + return (pkt[0] & (byte) 0xF0) == (byte) 0x60; + } + + private static byte[] getReflectedPacket(byte[] pkt) { + byte[] reflected = Arrays.copyOf(pkt, pkt.length); + + if (isIpv6(pkt)) { + // Set reflected packet's dst to that of the original's src + System.arraycopy( + pkt, // src + IP6_ADDR_OFFSET + IP6_ADDR_LEN, // src offset + reflected, // dst + IP6_ADDR_OFFSET, // dst offset + IP6_ADDR_LEN); // len + // Set reflected packet's src IP to that of the original's dst IP + System.arraycopy( + pkt, // src + IP6_ADDR_OFFSET, // src offset + reflected, // dst + IP6_ADDR_OFFSET + IP6_ADDR_LEN, // dst offset + IP6_ADDR_LEN); // len + } else { + // Set reflected packet's dst to that of the original's src + System.arraycopy( + pkt, // src + IP4_ADDR_OFFSET + IP4_ADDR_LEN, // src offset + reflected, // dst + IP4_ADDR_OFFSET, // dst offset + IP4_ADDR_LEN); // len + // Set reflected packet's src IP to that of the original's dst IP + System.arraycopy( + pkt, // src + IP4_ADDR_OFFSET, // src offset + reflected, // dst + IP4_ADDR_OFFSET + IP4_ADDR_LEN, // dst offset + IP4_ADDR_LEN); // len + } + return reflected; + } + + /** Takes all captured packets, flips the src/dst, and re-injects them. */ + public void reflectPackets() throws IOException { + synchronized (mPackets) { + for (byte[] pkt : mPackets) { + injectPacket(getReflectedPacket(pkt)); + } + } + } + + public void injectPacket(byte[] pkt) throws IOException { + FileOutputStream out = new FileOutputStream(mTunFd.getFileDescriptor()); + out.write(pkt); + out.flush(); + } + + /** Resets the intercepted packets. */ + public void reset() throws IOException { + synchronized (mPackets) { + mPackets.clear(); + } + } +} From 5d8b8a1f7128dce20e724e8568462b182ea11433 Mon Sep 17 00:00:00 2001 From: Yan Yan Date: Sat, 25 Apr 2020 03:08:19 +0000 Subject: [PATCH 0934/1109] Add initial CTS test for IkeSessionParams This commit adds tests for building IkeSessionParams with PSK. It also tests configuring SA lifetimes, retransmissions and PCSCF server requests Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: I16fdc1ff9a22acb82b376211e0f187c4ead4cae5 Merged-In: I16fdc1ff9a22acb82b376211e0f187c4ead4cae5 (cherry picked from commit c98c75308fae272eb4c9f539bed22c1a91aab2a4) --- .../ipsec/ike/cts/IkeSessionParamsTest.java | 262 ++++++++++++++++++ .../net/ipsec/ike/cts/IkeTestBase.java | 13 + 2 files changed, 275 insertions(+) create mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java new file mode 100644 index 0000000000..91ef7789e3 --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java @@ -0,0 +1,262 @@ +/* + * 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.ipsec.ike.cts; + +import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID; +import static android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig; +import static android.net.ipsec.ike.IkeSessionParams.IkeAuthPskConfig; +import static android.system.OsConstants.AF_INET; +import static android.system.OsConstants.AF_INET6; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.net.ipsec.ike.IkeFqdnIdentification; +import android.net.ipsec.ike.IkeIdentification; +import android.net.ipsec.ike.IkeSaProposal; +import android.net.ipsec.ike.IkeSessionParams; +import android.net.ipsec.ike.IkeSessionParams.ConfigRequestIpv4PcscfServer; +import android.net.ipsec.ike.IkeSessionParams.ConfigRequestIpv6PcscfServer; +import android.net.ipsec.ike.IkeSessionParams.IkeConfigRequest; + +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.net.InetAddress; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +@RunWith(AndroidJUnit4.class) +public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { + private static final int HARD_LIFETIME_SECONDS = (int) TimeUnit.HOURS.toSeconds(20L); + private static final int SOFT_LIFETIME_SECONDS = (int) TimeUnit.HOURS.toSeconds(10L); + private static final int DPD_DELAY_SECONDS = (int) TimeUnit.MINUTES.toSeconds(10L); + private static final int[] RETRANS_TIMEOUT_MS_LIST = new int[] {500, 500, 500, 500, 500, 500}; + + private static final Map, Integer> EXPECTED_REQ_COUNT = + new HashMap<>(); + private static final HashSet EXPECTED_PCSCF_SERVERS = new HashSet<>(); + + static { + EXPECTED_REQ_COUNT.put(ConfigRequestIpv4PcscfServer.class, 3); + EXPECTED_REQ_COUNT.put(ConfigRequestIpv6PcscfServer.class, 3); + + EXPECTED_PCSCF_SERVERS.add(PCSCF_IPV4_ADDRESS_1); + EXPECTED_PCSCF_SERVERS.add(PCSCF_IPV4_ADDRESS_2); + EXPECTED_PCSCF_SERVERS.add(PCSCF_IPV6_ADDRESS_1); + EXPECTED_PCSCF_SERVERS.add(PCSCF_IPV6_ADDRESS_2); + } + + // Arbitrary proposal and remote ID. Local ID is chosen to match the client end cert in the + // following CL + private static final IkeSaProposal SA_PROPOSAL = + SaProposalTest.buildIkeSaProposalWithNormalModeCipher(); + private static final IkeIdentification LOCAL_ID = new IkeFqdnIdentification(LOCAL_HOSTNAME); + private static final IkeIdentification REMOTE_ID = new IkeFqdnIdentification(REMOTE_HOSTNAME); + + /** + * Create a Builder that has minimum configurations to build an IkeSessionParams. + * + *

    Authentication method is arbitrarily selected. Using other method (e.g. setAuthEap) also + * works. + */ + private IkeSessionParams.Builder createIkeParamsBuilderMinimum() { + return new IkeSessionParams.Builder(sContext) + .setNetwork(sTunNetwork) + .setServerHostname(IPV4_ADDRESS_REMOTE.getHostAddress()) + .addSaProposal(SA_PROPOSAL) + .setLocalIdentification(LOCAL_ID) + .setRemoteIdentification(REMOTE_ID) + .setAuthPsk(IKE_PSK); + } + + /** + * Verify the minimum configurations to build an IkeSessionParams. + * + * @see #createIkeParamsBuilderMinimum + */ + private void verifyIkeParamsMinimum(IkeSessionParams sessionParams) { + assertEquals(sTunNetwork, sessionParams.getNetwork()); + assertEquals(IPV4_ADDRESS_REMOTE.getHostAddress(), sessionParams.getServerHostname()); + assertEquals(Arrays.asList(SA_PROPOSAL), sessionParams.getSaProposals()); + assertEquals(LOCAL_ID, sessionParams.getLocalIdentification()); + assertEquals(REMOTE_ID, sessionParams.getRemoteIdentification()); + + IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig(); + assertTrue(localConfig instanceof IkeAuthPskConfig); + assertArrayEquals(IKE_PSK, ((IkeAuthPskConfig) localConfig).getPsk()); + IkeAuthConfig remoteConfig = sessionParams.getRemoteAuthConfig(); + assertTrue(remoteConfig instanceof IkeAuthPskConfig); + assertArrayEquals(IKE_PSK, ((IkeAuthPskConfig) remoteConfig).getPsk()); + } + + private void verifySpecificPcscfConfigReqs( + HashSet expectedAddresses, IkeSessionParams sessionParams) { + Set resultAddresses = new HashSet<>(); + + for (IkeConfigRequest req : sessionParams.getConfigurationRequests()) { + if (req instanceof ConfigRequestIpv4PcscfServer + && ((ConfigRequestIpv4PcscfServer) req).getAddress() != null) { + resultAddresses.add(((ConfigRequestIpv4PcscfServer) req).getAddress()); + } else if (req instanceof ConfigRequestIpv6PcscfServer + && ((ConfigRequestIpv6PcscfServer) req).getAddress() != null) { + resultAddresses.add(((ConfigRequestIpv6PcscfServer) req).getAddress()); + } + } + + assertEquals(expectedAddresses, resultAddresses); + } + + @Test + public void testBuildWithMinimumSet() throws Exception { + IkeSessionParams sessionParams = createIkeParamsBuilderMinimum().build(); + + verifyIkeParamsMinimum(sessionParams); + + // Verify default values that do not need explicit configuration. Do not do assertEquals + // to be avoid being a change-detector test + assertTrue(sessionParams.getHardLifetimeSeconds() > sessionParams.getSoftLifetimeSeconds()); + assertTrue(sessionParams.getSoftLifetimeSeconds() > 0); + assertTrue(sessionParams.getDpdDelaySeconds() > 0); + assertTrue(sessionParams.getRetransmissionTimeoutsMillis().length > 0); + for (int timeout : sessionParams.getRetransmissionTimeoutsMillis()) { + assertTrue(timeout > 0); + } + assertTrue(sessionParams.getConfigurationRequests().isEmpty()); + assertFalse(sessionParams.hasIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID)); + } + + @Test + public void testSetLifetimes() throws Exception { + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimum() + .setLifetimeSeconds(HARD_LIFETIME_SECONDS, SOFT_LIFETIME_SECONDS) + .build(); + + verifyIkeParamsMinimum(sessionParams); + assertEquals(HARD_LIFETIME_SECONDS, sessionParams.getHardLifetimeSeconds()); + assertEquals(SOFT_LIFETIME_SECONDS, sessionParams.getSoftLifetimeSeconds()); + } + + @Test + public void testSetDpdDelay() throws Exception { + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimum().setDpdDelaySeconds(DPD_DELAY_SECONDS).build(); + + verifyIkeParamsMinimum(sessionParams); + assertEquals(DPD_DELAY_SECONDS, sessionParams.getDpdDelaySeconds()); + } + + @Test + public void testSetRetransmissionTimeouts() throws Exception { + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimum() + .setRetransmissionTimeoutsMillis(RETRANS_TIMEOUT_MS_LIST) + .build(); + + verifyIkeParamsMinimum(sessionParams); + assertArrayEquals(RETRANS_TIMEOUT_MS_LIST, sessionParams.getRetransmissionTimeoutsMillis()); + } + + @Test + public void testSetPcscfConfigRequests() throws Exception { + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimum() + .setRetransmissionTimeoutsMillis(RETRANS_TIMEOUT_MS_LIST) + .addPcscfServerRequest(AF_INET) + .addPcscfServerRequest(PCSCF_IPV4_ADDRESS_1) + .addPcscfServerRequest(PCSCF_IPV6_ADDRESS_1) + .addPcscfServerRequest(AF_INET6) + .addPcscfServerRequest(PCSCF_IPV4_ADDRESS_2) + .addPcscfServerRequest(PCSCF_IPV6_ADDRESS_2) + .build(); + + verifyIkeParamsMinimum(sessionParams); + verifyConfigRequestTypes(EXPECTED_REQ_COUNT, sessionParams.getConfigurationRequests()); + + Set resultAddresses = new HashSet<>(); + for (IkeConfigRequest req : sessionParams.getConfigurationRequests()) { + if (req instanceof ConfigRequestIpv4PcscfServer + && ((ConfigRequestIpv4PcscfServer) req).getAddress() != null) { + resultAddresses.add(((ConfigRequestIpv4PcscfServer) req).getAddress()); + } else if (req instanceof ConfigRequestIpv6PcscfServer + && ((ConfigRequestIpv6PcscfServer) req).getAddress() != null) { + resultAddresses.add(((ConfigRequestIpv6PcscfServer) req).getAddress()); + } + } + assertEquals(EXPECTED_PCSCF_SERVERS, resultAddresses); + } + + @Test + public void testAddIkeOption() throws Exception { + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimum() + .addIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID) + .build(); + + verifyIkeParamsMinimum(sessionParams); + assertTrue(sessionParams.hasIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID)); + } + + @Test + public void testRemoveIkeOption() throws Exception { + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimum() + .addIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID) + .removeIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID) + .build(); + + verifyIkeParamsMinimum(sessionParams); + assertFalse(sessionParams.hasIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID)); + } + + @Test + public void testBuildWithPsk() throws Exception { + IkeSessionParams sessionParams = + new IkeSessionParams.Builder(sContext) + .setNetwork(sTunNetwork) + .setServerHostname(IPV4_ADDRESS_REMOTE.getHostAddress()) + .addSaProposal(SA_PROPOSAL) + .setLocalIdentification(LOCAL_ID) + .setRemoteIdentification(REMOTE_ID) + .setAuthPsk(IKE_PSK) + .build(); + assertEquals(sTunNetwork, sessionParams.getNetwork()); + assertEquals(IPV4_ADDRESS_REMOTE.getHostAddress(), sessionParams.getServerHostname()); + assertEquals(Arrays.asList(SA_PROPOSAL), sessionParams.getSaProposals()); + assertEquals(LOCAL_ID, sessionParams.getLocalIdentification()); + assertEquals(REMOTE_ID, sessionParams.getRemoteIdentification()); + + IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig(); + assertTrue(localConfig instanceof IkeAuthPskConfig); + assertArrayEquals(IKE_PSK, ((IkeAuthPskConfig) localConfig).getPsk()); + IkeAuthConfig remoteConfig = sessionParams.getRemoteAuthConfig(); + assertTrue(remoteConfig instanceof IkeAuthPskConfig); + assertArrayEquals(IKE_PSK, ((IkeAuthPskConfig) remoteConfig).getPsk()); + } + + // TODO(b/148689509): Add tests for building IkeSessionParams using EAP and + // digital-signature-based authentication +} diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java index d3aa8d03d5..5f608df137 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java @@ -24,6 +24,7 @@ import android.net.ipsec.ike.IkeTrafficSelector; import java.net.Inet4Address; import java.net.Inet6Address; +import java.net.InetAddress; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -40,6 +41,11 @@ abstract class IkeTestBase { static final int IP4_PREFIX_LEN = 32; static final int IP6_PREFIX_LEN = 64; + static final byte[] IKE_PSK = "ikeAndroidPsk".getBytes(); + + static final String LOCAL_HOSTNAME = "client.test.ike.android.net"; + static final String REMOTE_HOSTNAME = "server.test.ike.android.net"; + static final Inet4Address IPV4_ADDRESS_LOCAL = (Inet4Address) (InetAddresses.parseNumericAddress("192.0.2.100")); static final Inet4Address IPV4_ADDRESS_REMOTE = @@ -49,6 +55,13 @@ abstract class IkeTestBase { static final Inet6Address IPV6_ADDRESS_REMOTE = (Inet6Address) (InetAddresses.parseNumericAddress("2001:db8:255::100")); + static final InetAddress PCSCF_IPV4_ADDRESS_1 = InetAddresses.parseNumericAddress("192.0.2.1"); + static final InetAddress PCSCF_IPV4_ADDRESS_2 = InetAddresses.parseNumericAddress("192.0.2.2"); + static final InetAddress PCSCF_IPV6_ADDRESS_1 = + InetAddresses.parseNumericAddress("2001:DB8::1"); + static final InetAddress PCSCF_IPV6_ADDRESS_2 = + InetAddresses.parseNumericAddress("2001:DB8::2"); + static final IkeTrafficSelector DEFAULT_V4_TS = new IkeTrafficSelector( MIN_PORT, From 913ce19d40b07d49d8b10f35e8f676299ccf7c1a Mon Sep 17 00:00:00 2001 From: Yan Yan Date: Sun, 26 Apr 2020 22:34:31 +0000 Subject: [PATCH 0935/1109] Test building IkeSessionParams with EAP Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: Iea7f4d14502f4b204c7a0d7357e1aaec99954e1f Merged-In: Iea7f4d14502f4b204c7a0d7357e1aaec99954e1f (cherry picked from commit 5ad4adaff63b06c66ce9466387118a077331f0c3) --- tests/cts/net/ipsec/Android.bp | 1 + .../assets/pem/server-a-self-signed-ca.pem | 20 +++ .../ipsec/ike/cts/IkeSessionParamsTest.java | 144 ++++++++++++++---- .../net/ipsec/ike/cts/IkeTestBase.java | 6 + 4 files changed, 141 insertions(+), 30 deletions(-) create mode 100644 tests/cts/net/ipsec/assets/pem/server-a-self-signed-ca.pem diff --git a/tests/cts/net/ipsec/Android.bp b/tests/cts/net/ipsec/Android.bp index 86969c31ae..1d9128b7fe 100644 --- a/tests/cts/net/ipsec/Android.bp +++ b/tests/cts/net/ipsec/Android.bp @@ -26,6 +26,7 @@ android_test { srcs: [ "src/**/*.java", + ":ike-test-utils", ], static_libs: [ diff --git a/tests/cts/net/ipsec/assets/pem/server-a-self-signed-ca.pem b/tests/cts/net/ipsec/assets/pem/server-a-self-signed-ca.pem new file mode 100644 index 0000000000..972fd55372 --- /dev/null +++ b/tests/cts/net/ipsec/assets/pem/server-a-self-signed-ca.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDSDCCAjCgAwIBAgIITJQJ6HC1rjwwDQYJKoZIhvcNAQELBQAwQjELMAkGA1UE +BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxITAfBgNVBAMTGHJvb3QuY2EudGVzdC5h +bmRyb2lkLm5ldDAeFw0xOTA5MzAxNzU1NTJaFw0yOTA5MjcxNzU1NTJaMEIxCzAJ +BgNVBAYTAlVTMRAwDgYDVQQKEwdBbmRyb2lkMSEwHwYDVQQDExhyb290LmNhLnRl +c3QuYW5kcm9pZC5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCT +q3hGF+JvLaB1xW7KGKmaxiQ7BxX2Sn7cbp7ggoVYXsFlBUuPPv3+Vg5PfPCPhsJ8 +/7w4HyKo3uc/vHs5HpQ7rSd9blhAkfmJci2ULLq73FB8Mix4CzPwMx29RrN1X9bU +z4G0vJMczIBGxbZ0uw7n8bKcXBV7AIeax+J8lseEZ3k8iSuBkUJqGIpPFKTqByFZ +A1Lvt47xkON5SZh6c/Oe+o6291wXaCOJUSAKv6PAWZkq9HeD2fqKA/ck9dBaz1M3 +YvzQ9V/7so3/dECjAfKia388h1I6XSGNUM+d5hpxMXpAFgG42eUXHpJ10OjDvSwd +7ZSC91/kRQewUomEKBK1AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P +AQH/BAQDAgEGMB0GA1UdDgQWBBRJn6hHhdeDY/dXpCKUfrFYQhKAGjANBgkqhkiG +9w0BAQsFAAOCAQEAig/94aGfHBhZuvbbhwAK4rUNpizmR567u0ZJ+QUEKyAlo9lT +ZWYHSm7qTAZYvPEjzTQIptnAlxCHePXh3Cfwgo+r82lhG2rcdI03iRyvHWjM8gyk +BXCJTi0Q08JHHpTP6GnAqpz58qEIFkk8P766zNXdhYrGPOydF+p7MFcb1Zv1gum3 +zmRLt0XUAMfjPUv1Bl8kTKFxH5lkMBLR1E0jnoJoTTfgRPrf9CuFSoh48n7YhoBT +KV75xZY8b8+SuB0v6BvQmkpKZGoxBjuVsShyG7q1+4JTAtwhiP7BlkDvVkaBEi7t +WIMFp2r2ZDisHgastNaeYFyzHYz9g1FCCrHQ4w== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java index 91ef7789e3..532be675aa 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java @@ -17,16 +17,22 @@ package android.net.ipsec.ike.cts; import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID; +import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_EAP_ONLY_AUTH; import static android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig; +import static android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignRemoteConfig; +import static android.net.ipsec.ike.IkeSessionParams.IkeAuthEapConfig; import static android.net.ipsec.ike.IkeSessionParams.IkeAuthPskConfig; import static android.system.OsConstants.AF_INET; import static android.system.OsConstants.AF_INET6; +import static android.telephony.TelephonyManager.APPTYPE_USIM; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import android.net.eap.EapSessionConfig; import android.net.ipsec.ike.IkeFqdnIdentification; import android.net.ipsec.ike.IkeIdentification; import android.net.ipsec.ike.IkeSaProposal; @@ -37,10 +43,14 @@ import android.net.ipsec.ike.IkeSessionParams.IkeConfigRequest; import androidx.test.ext.junit.runners.AndroidJUnit4; +import com.android.internal.net.ipsec.ike.testutils.CertUtils; + +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.net.InetAddress; +import java.security.cert.X509Certificate; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; @@ -76,6 +86,29 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { private static final IkeIdentification LOCAL_ID = new IkeFqdnIdentification(LOCAL_HOSTNAME); private static final IkeIdentification REMOTE_ID = new IkeFqdnIdentification(REMOTE_HOSTNAME); + private static final EapSessionConfig EAP_ALL_METHODS_CONFIG = + createEapOnlySafeMethodsBuilder() + .setEapMsChapV2Config(EAP_MSCHAPV2_USERNAME, EAP_MSCHAPV2_PASSWORD) + .build(); + private static final EapSessionConfig EAP_ONLY_SAFE_METHODS_CONFIG = + createEapOnlySafeMethodsBuilder().build(); + + private X509Certificate mServerCaCert; + + @Before + public void setUp() throws Exception { + mServerCaCert = CertUtils.createCertFromPemFile("server-a-self-signed-ca.pem"); + } + + private static EapSessionConfig.Builder createEapOnlySafeMethodsBuilder() { + return new EapSessionConfig.Builder() + .setEapIdentity(EAP_IDENTITY) + .setEapSimConfig(SUB_ID, APPTYPE_USIM) + .setEapAkaConfig(SUB_ID, APPTYPE_USIM) + .setEapAkaPrimeConfig( + SUB_ID, APPTYPE_USIM, NETWORK_NAME, true /* allowMismatchedNetworkNames */); + } + /** * Create a Builder that has minimum configurations to build an IkeSessionParams. * @@ -112,23 +145,6 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { assertArrayEquals(IKE_PSK, ((IkeAuthPskConfig) remoteConfig).getPsk()); } - private void verifySpecificPcscfConfigReqs( - HashSet expectedAddresses, IkeSessionParams sessionParams) { - Set resultAddresses = new HashSet<>(); - - for (IkeConfigRequest req : sessionParams.getConfigurationRequests()) { - if (req instanceof ConfigRequestIpv4PcscfServer - && ((ConfigRequestIpv4PcscfServer) req).getAddress() != null) { - resultAddresses.add(((ConfigRequestIpv4PcscfServer) req).getAddress()); - } else if (req instanceof ConfigRequestIpv6PcscfServer - && ((ConfigRequestIpv6PcscfServer) req).getAddress() != null) { - resultAddresses.add(((ConfigRequestIpv6PcscfServer) req).getAddress()); - } - } - - assertEquals(expectedAddresses, resultAddresses); - } - @Test public void testBuildWithMinimumSet() throws Exception { IkeSessionParams sessionParams = createIkeParamsBuilderMinimum().build(); @@ -232,22 +248,39 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { assertFalse(sessionParams.hasIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID)); } - @Test - public void testBuildWithPsk() throws Exception { - IkeSessionParams sessionParams = - new IkeSessionParams.Builder(sContext) - .setNetwork(sTunNetwork) - .setServerHostname(IPV4_ADDRESS_REMOTE.getHostAddress()) - .addSaProposal(SA_PROPOSAL) - .setLocalIdentification(LOCAL_ID) - .setRemoteIdentification(REMOTE_ID) - .setAuthPsk(IKE_PSK) - .build(); + /** + * Create a Builder that has minimum configurations to build an IkeSessionParams, except for + * authentication method. + */ + private IkeSessionParams.Builder createIkeParamsBuilderMinimumWithoutAuth() { + return new IkeSessionParams.Builder(sContext) + .setNetwork(sTunNetwork) + .setServerHostname(IPV4_ADDRESS_REMOTE.getHostAddress()) + .addSaProposal(SA_PROPOSAL) + .setLocalIdentification(LOCAL_ID) + .setRemoteIdentification(REMOTE_ID); + } + + /** + * Verify the minimum configurations to build an IkeSessionParams, except for authentication + * method. + * + * @see #createIkeParamsBuilderMinimumWithoutAuth + */ + private void verifyIkeParamsMinimumWithoutAuth(IkeSessionParams sessionParams) { assertEquals(sTunNetwork, sessionParams.getNetwork()); assertEquals(IPV4_ADDRESS_REMOTE.getHostAddress(), sessionParams.getServerHostname()); assertEquals(Arrays.asList(SA_PROPOSAL), sessionParams.getSaProposals()); assertEquals(LOCAL_ID, sessionParams.getLocalIdentification()); assertEquals(REMOTE_ID, sessionParams.getRemoteIdentification()); + } + + @Test + public void testBuildWithPsk() throws Exception { + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimumWithoutAuth().setAuthPsk(IKE_PSK).build(); + + verifyIkeParamsMinimumWithoutAuth(sessionParams); IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig(); assertTrue(localConfig instanceof IkeAuthPskConfig); @@ -257,6 +290,57 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { assertArrayEquals(IKE_PSK, ((IkeAuthPskConfig) remoteConfig).getPsk()); } - // TODO(b/148689509): Add tests for building IkeSessionParams using EAP and - // digital-signature-based authentication + @Test + public void testBuildWithEap() throws Exception { + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimumWithoutAuth() + .setAuthEap(mServerCaCert, EAP_ALL_METHODS_CONFIG) + .build(); + + verifyIkeParamsMinimumWithoutAuth(sessionParams); + + IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig(); + assertTrue(localConfig instanceof IkeAuthEapConfig); + assertEquals(EAP_ALL_METHODS_CONFIG, ((IkeAuthEapConfig) localConfig).getEapConfig()); + IkeAuthConfig remoteConfig = sessionParams.getRemoteAuthConfig(); + assertTrue(remoteConfig instanceof IkeAuthDigitalSignRemoteConfig); + assertEquals( + mServerCaCert, ((IkeAuthDigitalSignRemoteConfig) remoteConfig).getRemoteCaCert()); + } + + @Test + public void testBuildWithEapOnlyAuth() throws Exception { + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimumWithoutAuth() + .setAuthEap(mServerCaCert, EAP_ONLY_SAFE_METHODS_CONFIG) + .addIkeOption(IKE_OPTION_EAP_ONLY_AUTH) + .build(); + + assertTrue(sessionParams.hasIkeOption(IKE_OPTION_EAP_ONLY_AUTH)); + verifyIkeParamsMinimumWithoutAuth(sessionParams); + + IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig(); + assertTrue(localConfig instanceof IkeAuthEapConfig); + assertEquals(EAP_ONLY_SAFE_METHODS_CONFIG, ((IkeAuthEapConfig) localConfig).getEapConfig()); + IkeAuthConfig remoteConfig = sessionParams.getRemoteAuthConfig(); + assertTrue(remoteConfig instanceof IkeAuthDigitalSignRemoteConfig); + assertEquals( + mServerCaCert, ((IkeAuthDigitalSignRemoteConfig) remoteConfig).getRemoteCaCert()); + } + + @Test + public void testThrowBuildEapOnlyAuthWithUnsafeMethod() throws Exception { + try { + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimumWithoutAuth() + .setAuthEap(mServerCaCert, EAP_ALL_METHODS_CONFIG) + .addIkeOption(IKE_OPTION_EAP_ONLY_AUTH) + .build(); + fail("Expected to fail because EAP only unsafe method is proposed"); + } catch (IllegalArgumentException expected) { + } + } + + // TODO(b/148689509): Add tests for building IkeSessionParams using digital-signature-based + // authentication } diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java index 5f608df137..54c28e3a92 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java @@ -46,6 +46,12 @@ abstract class IkeTestBase { static final String LOCAL_HOSTNAME = "client.test.ike.android.net"; static final String REMOTE_HOSTNAME = "server.test.ike.android.net"; + static final int SUB_ID = 1; + static final byte[] EAP_IDENTITY = "test@android.net".getBytes(); + static final String NETWORK_NAME = "android.net"; + static final String EAP_MSCHAPV2_USERNAME = "username"; + static final String EAP_MSCHAPV2_PASSWORD = "password"; + static final Inet4Address IPV4_ADDRESS_LOCAL = (Inet4Address) (InetAddresses.parseNumericAddress("192.0.2.100")); static final Inet4Address IPV4_ADDRESS_REMOTE = From fe6c2565dac3d81d20294de01c221f7d125f7448 Mon Sep 17 00:00:00 2001 From: Yan Yan Date: Mon, 27 Apr 2020 03:28:29 +0000 Subject: [PATCH 0936/1109] Test configuring digital-signature-based auth Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: Ieaceaadf116cb2885cbf22ae48579cec88268416 Merged-In: Ieaceaadf116cb2885cbf22ae48579cec88268416 (cherry picked from commit ca5515626ce03bde9116603485ec0e85f476ecd3) --- .../ipsec/assets/key/client-a-private-key.key | 28 +++++++++ .../ipsec/assets/pem/client-a-end-cert.pem | 21 +++++++ .../pem/client-a-intermediate-ca-one.pem | 21 +++++++ .../pem/client-a-intermediate-ca-two.pem | 21 +++++++ .../ipsec/ike/cts/IkeSessionParamsTest.java | 63 ++++++++++++++++++- 5 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 tests/cts/net/ipsec/assets/key/client-a-private-key.key create mode 100644 tests/cts/net/ipsec/assets/pem/client-a-end-cert.pem create mode 100644 tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-one.pem create mode 100644 tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-two.pem diff --git a/tests/cts/net/ipsec/assets/key/client-a-private-key.key b/tests/cts/net/ipsec/assets/key/client-a-private-key.key new file mode 100644 index 0000000000..22736e98e0 --- /dev/null +++ b/tests/cts/net/ipsec/assets/key/client-a-private-key.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCv3CvrCGokJSWL +8ufg6u9LCW4EezztbktqpC0T+1m98+Ujb8/eJ0L2UaxZ9QBSBAqXxEoeZFBeoCXu +7ezUd5qUPfIhKLAkQTAyU/KgfhHh4i+MJK5ghPbGDE8r2gKUXOkM6M5//ZCpmu0K +Y/9uQL6D5bkxEaoWegEO+wSXm+hTTgKDtQKHvRibgdcZkcY0cA9JsLrC/nIkP+7i +pbBT+VTuV6gAnKIV0nq8zvI3A/Z3nAb5Gt0g3qaqs59StDT0QtuXzJkuZEo3XSrS +jon+8NjSNzqVbJj95B7+uiH+91VEbMtJYFz2MipKvJQDK7Zlxke7LxRj2xJfksJK +a92/ncxfAgMBAAECggEAQztaMvW5lm35J8LKsWs/5qEJRX9T8LWs8W0oqq36Riub +G2wgvR6ndAIPcSjAYZqX7iOl7m6NZ0+0kN63HxdGqovwKIskpAekBGmhpYftED1n +zh0r6UyMB3UnQ22KdOv8UOokIDxxdNX8728BdUYdT9Ggdkj5jLRB+VcwD0IUlNvo +zzTpURV9HEd87uiLqd4AAHXSI0lIHI5U43z24HI/J6/YbYHT3Rlh6CIa/LuwO6vL +gFkgqg0/oy6yJtjrHtzNVA67F0UaH62hR4YFgbC0d955SJnDidWOv/0j2DMpfdCc +9kFAcPwUSyykvUSLnGIKWSG4D+6gzIeAeUx4oO7kMQKBgQDVNRkX8AGTHyLg+NXf +spUWWcodwVioXl30Q7h6+4bt8OI61UbhQ7wX61wvJ1cySpa2KOYa2UdagQVhGhhL +ADu363R77uXF/jZgzVfmjjyJ2nfDqRgHWRTlSkuq/jCOQCz7VIPHRZg5WL/9D4ms +TAqMjpzqeMfFZI+w4/+xpcJIuQKBgQDTKBy+ZuerWrVT9icWKvLU58o5EVj/2yFy +GJvKm+wRAAX2WzjNnR4HVd4DmMREVz1BPYby0j5gqjvtDsxYYu39+NT7JvMioLLK +QPj+7k5geYgNqVgCxB1vP89RhY2X1RLrN9sTXOodgFPeXOQWNYITkGp3eQpx4nTJ ++K/al3oB1wKBgAjnc8nVIyuyxDEjE0OJYMKTM2a0uXAmqMPXxC+Wq5bqVXhhidlE +i+lv0eTCPtkB1nN7F8kNQ/aaps/cWCFhvBy9P5shagUvzbOTP9WIIS0cq53HRRKh +fMbqqGhWv05hjb9dUzeSR341n6cA7B3++v3Nwu3j52vt/DZF/1q68nc5AoGAS0SU +ImbKE/GsizZGLoe2sZ/CHN+LKwCwhlwxRGKaHmE0vuE7eUeVSaYZEo0lAPtb8WJ+ +NRYueASWgeTxgFwbW5mUScZTirdfo+rPFwhZVdhcYApKPgosN9i2DOgfVcz1BnWN +mPRY25U/0BaqkyQVruWeneG+kGPZn5kPDktKiVcCgYEAkzwU9vCGhm7ZVALvx/zR +wARz2zsL9ImBc0P4DK1ld8g90FEnHrEgeI9JEwz0zFHOCMLwlk7kG0Xev7vfjZ7G +xSqtQYOH33Qp6rtBOgdt8hSyDFvakvDl6bqhAw52gelO3MTpAB1+ZsfZ5gFx13Jf +idNFcaIrC52PtZIH7QCzdDY= +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/tests/cts/net/ipsec/assets/pem/client-a-end-cert.pem b/tests/cts/net/ipsec/assets/pem/client-a-end-cert.pem new file mode 100644 index 0000000000..e82da85c50 --- /dev/null +++ b/tests/cts/net/ipsec/assets/pem/client-a-end-cert.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDaDCCAlCgAwIBAgIIcorRI3n29E4wDQYJKoZIhvcNAQELBQAwQTELMAkGA1UE +BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxIDAeBgNVBAMTF3R3by5jYS50ZXN0LmFu +ZHJvaWQubmV0MB4XDTIwMDQxNDA1MDM0OVoXDTIzMDQxNDA1MDM0OVowRTELMAkG +A1UEBhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxJDAiBgNVBAMTG2NsaWVudC50ZXN0 +LmlrZS5hbmRyb2lkLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AK/cK+sIaiQlJYvy5+Dq70sJbgR7PO1uS2qkLRP7Wb3z5SNvz94nQvZRrFn1AFIE +CpfESh5kUF6gJe7t7NR3mpQ98iEosCRBMDJT8qB+EeHiL4wkrmCE9sYMTyvaApRc +6Qzozn/9kKma7Qpj/25AvoPluTERqhZ6AQ77BJeb6FNOAoO1Aoe9GJuB1xmRxjRw +D0mwusL+ciQ/7uKlsFP5VO5XqACcohXSerzO8jcD9necBvka3SDepqqzn1K0NPRC +25fMmS5kSjddKtKOif7w2NI3OpVsmP3kHv66If73VURsy0lgXPYyKkq8lAMrtmXG +R7svFGPbEl+Swkpr3b+dzF8CAwEAAaNgMF4wHwYDVR0jBBgwFoAUcqSu1uRYT/DL +bLoDNUz38nGvCKQwJgYDVR0RBB8wHYIbY2xpZW50LnRlc3QuaWtlLmFuZHJvaWQu +bmV0MBMGA1UdJQQMMAoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQCa53tK +I9RM9/MutZ5KNG2Gfs2cqaPyv8ZRhs90HDWZhkFVu7prywJAxOd2hxxHPsvgurio +4bKAxnT4EXevgz5YoCbj2TPIL9TdFYh59zZ97XXMxk+SRdypgF70M6ETqKPs3hDP +ZRMMoHvvYaqaPvp4StSBX9A44gSyjHxVYJkrjDZ0uffKg5lFL5IPvqfdmSRSpGab +SyGTP4OLTy0QiNV3pBsJGdl0h5BzuTPR9OTl4xgeqqBQy2bDjmfJBuiYyCSCkPi7 +T3ohDYCymhuSkuktHPNG1aKllUJaw0tuZuNydlgdAveXPYfM36uvK0sfd9qr9pAy +rmkYV2MAWguFeckh +-----END CERTIFICATE----- \ No newline at end of file diff --git a/tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-one.pem b/tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-one.pem new file mode 100644 index 0000000000..707e575bc3 --- /dev/null +++ b/tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-one.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDaDCCAlCgAwIBAgIIIbjMyRn2770wDQYJKoZIhvcNAQELBQAwQjELMAkGA1UE +BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxITAfBgNVBAMTGHJvb3QuY2EudGVzdC5h +bmRyb2lkLm5ldDAeFw0xOTA5MzAxODQzMThaFw0yNDA5MjgxODQzMThaMEExCzAJ +BgNVBAYTAlVTMRAwDgYDVQQKEwdBbmRyb2lkMSAwHgYDVQQDExdvbmUuY2EudGVz +dC5hbmRyb2lkLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNN +sRr5Z30rAEw2jrAh/BIekbEy/MvOucAr1w0lxH71p+ybRBx5Bj7G07UGXbL659gm +meMV6nabY4HjQXNMq22POiJBZj+U+rw34br6waljBttxCmmJac1VvgqNsSspXjRy +NbiVQdFjyKSX0NOPcEkwANk15mZbOgJBaYYc8jQCY2G/p8eARVBTLJCy8LEwEU6j +XRv/4eYST79qpBFc7gQQj2FLmh9oppDIvcIVBHwtd1tBoVuehRSud1o8vQRkl/HJ +Mrwp24nO5YYhmVNSFRtBpmWMSu1KknFUwkOebINUNsKXXHebVa7cP4XIQUL8mRT3 +5X9rFJFSQJE01S3NjNMCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B +Af8EBAMCAQYwHQYDVR0OBBYEFHK3FIm7g8dxEIwK9zMAO8EWhRYxMB8GA1UdIwQY +MBaAFEmfqEeF14Nj91ekIpR+sVhCEoAaMA0GCSqGSIb3DQEBCwUAA4IBAQAeMlXT +TnxZo8oz0204gKZ63RzlgDpJ7SqA3qFG+pV+TiqGfSuVkXuIdOskjxJnA9VxUzrr +LdMTCn5e0FK6wCYjZ2GT/CD7oD3vSMkzGbLGNcNJhhDHUq8BOLPkPzz/rwQFPBSb +zr6hsiVXphEt/psGoN7Eu9blPeQaIwMfWnaufAwF664S/3dmCRbNMWSam1qzzz8q +jr0cDOIMa//ZIAcM16cvoBK6pFGnUmuoJYYRtfpY5MmfCWz0sCJxENIX/lxyhd7N +FdRALA1ZP3E//Tn2vQoeFjbKaAba527RE26HgHJ9zZDo1nn8J8J/YwYRJdBWM/3S +LYebNiMtcyB5nIkj +-----END CERTIFICATE----- \ No newline at end of file diff --git a/tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-two.pem b/tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-two.pem new file mode 100644 index 0000000000..39808f885e --- /dev/null +++ b/tests/cts/net/ipsec/assets/pem/client-a-intermediate-ca-two.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIIKWCREnNCs+wwDQYJKoZIhvcNAQELBQAwQTELMAkGA1UE +BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxIDAeBgNVBAMTF29uZS5jYS50ZXN0LmFu +ZHJvaWQubmV0MB4XDTE5MDkzMDE4NDQwMloXDTI0MDkyODE4NDQwMlowQTELMAkG +A1UEBhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxIDAeBgNVBAMTF3R3by5jYS50ZXN0 +LmFuZHJvaWQubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxLUa +RqkYl2m7lUmMnkooqO0DNNY1aN9r7mJc3ndYn5gjkpb3yLgOYPDNLcQerV6uWk/u +qKudNHed2dInGonl3oxwwv7++6oUvvtrSWLDZlRg16GsdIE1Y98DSMQWkSxevYy9 +Nh6FGTdlBFQVMpiMa8qHEkrOyKsy85yCW1sgzlpGTIBwbDAqYtwe3rgbwyHwUtfy +0EU++DBcR4ll/pDqB0OQtW5E3AOq2GH1iaGeFLKSUQ5KAbdI8y4/b8IkSDffvxcc +kXig7S54aLrNlL/ZjQ+H4Chgjj2A5wMucd81+Fb60Udej73ICL9PpMPnXQ1+BVYd +MJ/txjLNmrOJG9yEHQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB +/wQEAwIBBjAdBgNVHQ4EFgQUcqSu1uRYT/DLbLoDNUz38nGvCKQwHwYDVR0jBBgw +FoAUcrcUibuDx3EQjAr3MwA7wRaFFjEwDQYJKoZIhvcNAQELBQADggEBADY461GT +Rw0dGnD07xaGJcI0i0pV+WnGSrl1s1PAIdMYihJAqYnh10fXbFXLm2WMWVmv/pxs +FI/xDJno+pd4mCa/sIhm63ar/Nv+lFQmcpIlvSlKnhhV4SLNBeqbVhPBGTCHfrG4 +aIyCwm1KJsnkWbf03crhSskR/2CXIjX6lcAy7K3fE2u1ELpAdH0kMJR7VXkLFLUm +gqe9YCluR0weMpe2sCaOGzdVzQSmMMCzGP5cxeFR5U6K40kMOpiW11JNmQ06xI/m +YVkMNwoiV/ITT0/C/g9FxJmkO0mVSLEqxaLS/hNiQNDlroVM0rbxhzviXLI3R3AO +50VvlOQYGxWed/I= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java index 532be675aa..6fc7cb3634 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java @@ -19,6 +19,7 @@ package android.net.ipsec.ike.cts; import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID; import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_EAP_ONLY_AUTH; import static android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig; +import static android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignLocalConfig; import static android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignRemoteConfig; import static android.net.ipsec.ike.IkeSessionParams.IkeAuthEapConfig; import static android.net.ipsec.ike.IkeSessionParams.IkeAuthPskConfig; @@ -51,9 +52,12 @@ import org.junit.runner.RunWith; import java.net.InetAddress; import java.security.cert.X509Certificate; +import java.security.interfaces.RSAPrivateKey; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -94,10 +98,20 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { createEapOnlySafeMethodsBuilder().build(); private X509Certificate mServerCaCert; + private X509Certificate mClientEndCert; + private X509Certificate mClientIntermediateCaCertOne; + private X509Certificate mClientIntermediateCaCertTwo; + private RSAPrivateKey mClientPrivateKey; @Before public void setUp() throws Exception { mServerCaCert = CertUtils.createCertFromPemFile("server-a-self-signed-ca.pem"); + mClientEndCert = CertUtils.createCertFromPemFile("client-a-end-cert.pem"); + mClientIntermediateCaCertOne = + CertUtils.createCertFromPemFile("client-a-intermediate-ca-one.pem"); + mClientIntermediateCaCertTwo = + CertUtils.createCertFromPemFile("client-a-intermediate-ca-two.pem"); + mClientPrivateKey = CertUtils.createRsaPrivateKeyFromKeyFile("client-a-private-key.key"); } private static EapSessionConfig.Builder createEapOnlySafeMethodsBuilder() { @@ -341,6 +355,51 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { } } - // TODO(b/148689509): Add tests for building IkeSessionParams using digital-signature-based - // authentication + @Test + public void testBuildWithDigitalSignature() throws Exception { + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimumWithoutAuth() + .setAuthDigitalSignature(mServerCaCert, mClientEndCert, mClientPrivateKey) + .build(); + + verifyIkeParamsMinimumWithoutAuth(sessionParams); + + IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig(); + assertTrue(localConfig instanceof IkeAuthDigitalSignLocalConfig); + IkeAuthDigitalSignLocalConfig localSignConfig = (IkeAuthDigitalSignLocalConfig) localConfig; + assertEquals(mClientEndCert, localSignConfig.getClientEndCertificate()); + assertEquals(Collections.EMPTY_LIST, localSignConfig.getIntermediateCertificates()); + assertEquals(mClientPrivateKey, localSignConfig.getPrivateKey()); + + IkeAuthConfig remoteConfig = sessionParams.getRemoteAuthConfig(); + assertTrue(remoteConfig instanceof IkeAuthDigitalSignRemoteConfig); + assertEquals( + mServerCaCert, ((IkeAuthDigitalSignRemoteConfig) remoteConfig).getRemoteCaCert()); + } + + @Test + public void testBuildWithDigitalSignatureAndIntermediateCerts() throws Exception { + List intermediateCerts = + Arrays.asList(mClientIntermediateCaCertOne, mClientIntermediateCaCertTwo); + + IkeSessionParams sessionParams = + createIkeParamsBuilderMinimumWithoutAuth() + .setAuthDigitalSignature( + mServerCaCert, mClientEndCert, intermediateCerts, mClientPrivateKey) + .build(); + + verifyIkeParamsMinimumWithoutAuth(sessionParams); + + IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig(); + assertTrue(localConfig instanceof IkeAuthDigitalSignLocalConfig); + IkeAuthDigitalSignLocalConfig localSignConfig = (IkeAuthDigitalSignLocalConfig) localConfig; + assertEquals(mClientEndCert, localSignConfig.getClientEndCertificate()); + assertEquals(intermediateCerts, localSignConfig.getIntermediateCertificates()); + assertEquals(mClientPrivateKey, localSignConfig.getPrivateKey()); + + IkeAuthConfig remoteConfig = sessionParams.getRemoteAuthConfig(); + assertTrue(remoteConfig instanceof IkeAuthDigitalSignRemoteConfig); + assertEquals( + mServerCaCert, ((IkeAuthDigitalSignRemoteConfig) remoteConfig).getRemoteCaCert()); + } } From ecb661016ff964d78fc7616ed8c0c546a2cc22fc Mon Sep 17 00:00:00 2001 From: Remi NGUYEN VAN Date: Tue, 24 Mar 2020 18:40:42 +0900 Subject: [PATCH 0937/1109] Add test for internet availability on portals Add a test verifying that when the device has detected a captive portal, or when the user is trying to login to a captive portal, the captive portal network does not become the default network if another network can provide internet access. This follows R CDD requirements. Test: atest CtsNetTestCases:android.net.cts.CaptivePortalTest Bug: 152280218 Change-Id: I6a97ed26dba665efdc67abb2371e0fc30ede020c --- tests/cts/net/Android.bp | 1 + .../src/android/net/cts/CaptivePortalTest.kt | 254 ++++++++++++++++++ 2 files changed, 255 insertions(+) create mode 100644 tests/cts/net/src/android/net/cts/CaptivePortalTest.kt diff --git a/tests/cts/net/Android.bp b/tests/cts/net/Android.bp index 76bb27e448..46fae33b9b 100644 --- a/tests/cts/net/Android.bp +++ b/tests/cts/net/Android.bp @@ -47,6 +47,7 @@ java_defaults { "mockwebserver", "junit", "junit-params", + "libnanohttpd", "truth-prebuilt", ], diff --git a/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt b/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt new file mode 100644 index 0000000000..4418e1740e --- /dev/null +++ b/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt @@ -0,0 +1,254 @@ +/* + * 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.cts + +import android.Manifest.permission.NETWORK_SETTINGS +import android.Manifest.permission.READ_DEVICE_CONFIG +import android.Manifest.permission.WRITE_DEVICE_CONFIG +import android.content.pm.PackageManager.FEATURE_TELEPHONY +import android.content.pm.PackageManager.FEATURE_WIFI +import android.net.ConnectivityManager +import android.net.ConnectivityManager.NetworkCallback +import android.net.Network +import android.net.NetworkCapabilities +import android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL +import android.net.NetworkCapabilities.TRANSPORT_WIFI +import android.net.NetworkRequest +import android.net.Uri +import android.net.cts.util.CtsNetUtils +import android.net.wifi.WifiManager +import android.os.ConditionVariable +import android.platform.test.annotations.AppModeFull +import android.provider.DeviceConfig +import android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY +import android.text.TextUtils +import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation +import androidx.test.runner.AndroidJUnit4 +import com.android.compatibility.common.util.SystemUtil +import fi.iki.elonen.NanoHTTPD +import fi.iki.elonen.NanoHTTPD.Response.IStatus +import fi.iki.elonen.NanoHTTPD.Response.Status +import junit.framework.AssertionFailedError +import org.junit.After +import org.junit.Assume.assumeTrue +import org.junit.Before +import org.junit.runner.RunWith +import java.util.concurrent.CompletableFuture +import java.util.concurrent.TimeUnit +import java.util.concurrent.TimeoutException +import kotlin.test.Test +import kotlin.test.assertNotEquals +import kotlin.test.assertTrue + +private const val TEST_CAPTIVE_PORTAL_HTTPS_URL_SETTING = "test_captive_portal_https_url" +private const val TEST_CAPTIVE_PORTAL_HTTP_URL_SETTING = "test_captive_portal_http_url" +private const val TEST_URL_EXPIRATION_TIME = "test_url_expiration_time" + +private const val TEST_HTTPS_URL_PATH = "https_path" +private const val TEST_HTTP_URL_PATH = "http_path" +private const val TEST_PORTAL_URL_PATH = "portal_path" + +private const val LOCALHOST_HOSTNAME = "localhost" + +// Re-connecting to the AP, obtaining an IP address, revalidating can take a long time +private const val WIFI_CONNECT_TIMEOUT_MS = 120_000L +private const val TEST_TIMEOUT_MS = 10_000L + +private fun CompletableFuture.assertGet(timeoutMs: Long, message: String): T { + try { + return get(timeoutMs, TimeUnit.MILLISECONDS) + } catch (e: TimeoutException) { + throw AssertionFailedError(message) + } +} + +@AppModeFull(reason = "WRITE_DEVICE_CONFIG permission can't be granted to instant apps") +@RunWith(AndroidJUnit4::class) +class CaptivePortalTest { + private val context: android.content.Context by lazy { getInstrumentation().context } + private val wm by lazy { context.getSystemService(WifiManager::class.java) } + private val cm by lazy { context.getSystemService(ConnectivityManager::class.java) } + private val pm by lazy { context.packageManager } + private val utils by lazy { CtsNetUtils(context) } + + private val server = HttpServer() + + @Before + fun setUp() { + doAsShell(READ_DEVICE_CONFIG) { + // Verify that the test URLs are not normally set on the device, but do not fail if the + // test URLs are set to what this test uses (URLs on localhost), in case the test was + // interrupted manually and rerun. + assertEmptyOrLocalhostUrl(TEST_CAPTIVE_PORTAL_HTTPS_URL_SETTING) + assertEmptyOrLocalhostUrl(TEST_CAPTIVE_PORTAL_HTTP_URL_SETTING) + } + clearTestUrls() + server.start() + } + + @After + fun tearDown() { + clearTestUrls() + server.stop() + } + + private fun assertEmptyOrLocalhostUrl(urlKey: String) { + val url = DeviceConfig.getProperty(NAMESPACE_CONNECTIVITY, urlKey) + assertTrue(TextUtils.isEmpty(url) || LOCALHOST_HOSTNAME == Uri.parse(url).host, + "$urlKey must not be set in production scenarios (current value: $url)") + } + + private fun clearTestUrls() { + setHttpsUrl(null) + setHttpUrl(null) + setUrlExpiration(null) + } + + @Test + fun testCaptivePortalIsNotDefaultNetwork() { + assumeTrue(pm.hasSystemFeature(FEATURE_TELEPHONY)) + assumeTrue(pm.hasSystemFeature(FEATURE_WIFI)) + utils.connectToWifi() + utils.connectToCell() + + // Have network validation use a local server that serves a HTTPS error / HTTP redirect + server.addResponse(TEST_PORTAL_URL_PATH, Status.OK, + content = "Test captive portal content") + server.addResponse(TEST_HTTPS_URL_PATH, Status.INTERNAL_ERROR) + server.addResponse(TEST_HTTP_URL_PATH, Status.REDIRECT, + locationHeader = server.makeUrl(TEST_PORTAL_URL_PATH)) + setHttpsUrl(server.makeUrl(TEST_HTTPS_URL_PATH)) + setHttpUrl(server.makeUrl(TEST_HTTP_URL_PATH)) + // URL expiration needs to be in the next 10 minutes + setUrlExpiration(System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(9)) + + // Expect the portal content to be fetched at some point after detecting the portal. + // Some implementations may fetch the URL before startCaptivePortalApp is called. + val portalContentRequestCv = server.addExpectRequestCv(TEST_PORTAL_URL_PATH) + + // Wait for a captive portal to be detected on the network + val wifiNetworkFuture = CompletableFuture() + val wifiCb = object : NetworkCallback() { + override fun onCapabilitiesChanged( + network: Network, + nc: NetworkCapabilities + ) { + if (nc.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) { + wifiNetworkFuture.complete(network) + } + } + } + cm.requestNetwork(NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(), wifiCb) + + try { + reconnectWifi() + val network = wifiNetworkFuture.assertGet(WIFI_CONNECT_TIMEOUT_MS, + "Captive portal not detected after ${WIFI_CONNECT_TIMEOUT_MS}ms") + + val wifiDefaultMessage = "Wifi should not be the default network when a captive " + + "portal was detected and another network (mobile data) can provide internet " + + "access." + assertNotEquals(network, cm.activeNetwork, wifiDefaultMessage) + + doAsShell(NETWORK_SETTINGS) { cm.startCaptivePortalApp(network) } + assertTrue(portalContentRequestCv.block(TEST_TIMEOUT_MS), "The captive portal login " + + "page was still not fetched ${TEST_TIMEOUT_MS}ms after startCaptivePortalApp.") + + assertNotEquals(network, cm.activeNetwork, wifiDefaultMessage) + } finally { + cm.unregisterNetworkCallback(wifiCb) + server.stop() + // disconnectFromCell should be called after connectToCell + utils.disconnectFromCell() + } + + clearTestUrls() + reconnectWifi() + } + + private fun setHttpsUrl(url: String?) = setConfig(TEST_CAPTIVE_PORTAL_HTTPS_URL_SETTING, url) + private fun setHttpUrl(url: String?) = setConfig(TEST_CAPTIVE_PORTAL_HTTP_URL_SETTING, url) + private fun setUrlExpiration(timestamp: Long?) = setConfig(TEST_URL_EXPIRATION_TIME, + timestamp?.toString()) + + private fun setConfig(configKey: String, value: String?) { + doAsShell(WRITE_DEVICE_CONFIG) { + DeviceConfig.setProperty( + NAMESPACE_CONNECTIVITY, configKey, value, false /* makeDefault */) + } + } + + private fun doAsShell(vararg permissions: String, action: () -> Unit) { + // Wrap the below call to allow for more kotlin-like syntax + SystemUtil.runWithShellPermissionIdentity(action, permissions) + } + + private fun reconnectWifi() { + doAsShell(NETWORK_SETTINGS) { + assertTrue(wm.disconnect()) + assertTrue(wm.reconnect()) + } + } + + /** + * A minimal HTTP server running on localhost (loopback), on a random available port. + */ + private class HttpServer : NanoHTTPD("localhost", 0 /* auto-select the port */) { + // Map of URL path -> HTTP response code + private val responses = HashMap() + + // Map of path -> CV to open as soon as a request to the path is received + private val waitForRequestCv = HashMap() + + /** + * Create a URL string that, when fetched, will hit this server with the given URL [path]. + */ + fun makeUrl(path: String): String { + return Uri.Builder() + .scheme("http") + .encodedAuthority("localhost:$listeningPort") + .query(path) + .build() + .toString() + } + + fun addResponse( + path: String, + statusCode: IStatus, + locationHeader: String? = null, + content: String = "" + ) { + val response = newFixedLengthResponse(statusCode, "text/plain", content) + locationHeader?.let { response.addHeader("Location", it) } + responses[path] = response + } + + /** + * Create a [ConditionVariable] that will open when a request to [path] is received. + */ + fun addExpectRequestCv(path: String): ConditionVariable { + return ConditionVariable().apply { waitForRequestCv[path] = this } + } + + override fun serve(session: IHTTPSession): Response { + waitForRequestCv[session.queryParameterString]?.open() + return responses[session.queryParameterString] + // Default response is a 404 + ?: super.serve(session) + } + } +} \ No newline at end of file From 71cfc79527c812fcd334ca688477c0536f1fbee0 Mon Sep 17 00:00:00 2001 From: Remi NGUYEN VAN Date: Mon, 27 Apr 2020 22:40:11 +0900 Subject: [PATCH 0938/1109] Force reconnect in connectToWifi There is no guarantee that Wifi will automatically reconnect after enabling, especially in cases where no internet access was detected on the access point the last time it was connected. Use WifiManager#reconnect to force wifi to reconnect to the access point. The API is deprecated for general use, but system apps are documented as exempted from the deprecation. Bug: 152280218 Test: atest --rerun-until-failure 200 CtsNetTestCases:CaptivePortalTest Change-Id: Ia7d83337ee0ffad9414031711cf7e937b14f968d --- tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java | 3 +++ 1 file changed, 3 insertions(+) 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 6214f89e98..824146fedf 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 @@ -16,6 +16,7 @@ package android.net.cts.util; +import static android.Manifest.permission.NETWORK_SETTINGS; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; @@ -107,6 +108,8 @@ public final class CtsNetUtils { boolean connected = false; try { SystemUtil.runShellCommand("svc wifi enable"); + SystemUtil.runWithShellPermissionIdentity(() -> mWifiManager.reconnect(), + NETWORK_SETTINGS); // Ensure we get both an onAvailable callback and a CONNECTIVITY_ACTION. wifiNetwork = callback.waitForAvailable(); assertNotNull(wifiNetwork); From b921f9ead690959bf0570ca9831cd754fa4f448e Mon Sep 17 00:00:00 2001 From: Yan Yan Date: Sat, 25 Apr 2020 03:08:38 +0000 Subject: [PATCH 0939/1109] Add test for IkeIdentification Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: Ieda584446c37d121fc16a212e2c6c60b934b0f53 Merged-In: Ieda584446c37d121fc16a212e2c6c60b934b0f53 (cherry picked from commit 923f59a282367a668f151873860f8f4ff5ba352d) --- .../ipsec/ike/cts/IkeIdentificationTest.java | 75 +++++++++++++++++++ .../net/ipsec/ike/cts/IkeTestBase.java | 3 + 2 files changed, 78 insertions(+) create mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeIdentificationTest.java diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeIdentificationTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeIdentificationTest.java new file mode 100644 index 0000000000..0317def92e --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeIdentificationTest.java @@ -0,0 +1,75 @@ +/* + * 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.ipsec.ike.cts; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +import android.net.ipsec.ike.IkeDerAsn1DnIdentification; +import android.net.ipsec.ike.IkeFqdnIdentification; +import android.net.ipsec.ike.IkeIpv4AddrIdentification; +import android.net.ipsec.ike.IkeIpv6AddrIdentification; +import android.net.ipsec.ike.IkeKeyIdIdentification; +import android.net.ipsec.ike.IkeRfc822AddrIdentification; + +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import javax.security.auth.x500.X500Principal; + +@RunWith(AndroidJUnit4.class) +public final class IkeIdentificationTest extends IkeTestBase { + @Test + public void testIkeDerAsn1DnIdentification() throws Exception { + X500Principal asn1Dn = new X500Principal(LOCAL_ASN1_DN_STRING); + + IkeDerAsn1DnIdentification ikeId = new IkeDerAsn1DnIdentification(asn1Dn); + assertEquals(asn1Dn, ikeId.derAsn1Dn); + } + + @Test + public void testIkeFqdnIdentification() throws Exception { + IkeFqdnIdentification ikeId = new IkeFqdnIdentification(LOCAL_HOSTNAME); + assertEquals(LOCAL_HOSTNAME, ikeId.fqdn); + } + + @Test + public void testIkeIpv4AddrIdentification() throws Exception { + IkeIpv4AddrIdentification ikeId = new IkeIpv4AddrIdentification(IPV4_ADDRESS_LOCAL); + assertEquals(IPV4_ADDRESS_LOCAL, ikeId.ipv4Address); + } + + @Test + public void testIkeIpv6AddrIdentification() throws Exception { + IkeIpv6AddrIdentification ikeId = new IkeIpv6AddrIdentification(IPV6_ADDRESS_LOCAL); + assertEquals(IPV6_ADDRESS_LOCAL, ikeId.ipv6Address); + } + + @Test + public void testIkeKeyIdIdentification() throws Exception { + IkeKeyIdIdentification ikeId = new IkeKeyIdIdentification(LOCAL_KEY_ID); + assertArrayEquals(LOCAL_KEY_ID, ikeId.keyId); + } + + @Test + public void testIkeRfc822AddrIdentification() throws Exception { + IkeRfc822AddrIdentification ikeId = new IkeRfc822AddrIdentification(LOCAL_RFC822_NAME); + assertEquals(LOCAL_RFC822_NAME, ikeId.rfc822Name); + } +} diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java index 5f608df137..08477446d2 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java @@ -45,6 +45,9 @@ abstract class IkeTestBase { static final String LOCAL_HOSTNAME = "client.test.ike.android.net"; static final String REMOTE_HOSTNAME = "server.test.ike.android.net"; + static final String LOCAL_ASN1_DN_STRING = "CN=client.test.ike.android.net, O=Android, C=US"; + static final String LOCAL_RFC822_NAME = "client.test.ike@example.com"; + static final byte[] LOCAL_KEY_ID = "Local Key ID".getBytes(); static final Inet4Address IPV4_ADDRESS_LOCAL = (Inet4Address) (InetAddresses.parseNumericAddress("192.0.2.100")); From 388f7240c7e4dfd9830311cfc50a267f685fc2a0 Mon Sep 17 00:00:00 2001 From: Remi NGUYEN VAN Date: Tue, 28 Apr 2020 06:16:55 +0000 Subject: [PATCH 0940/1109] Add test for internet availability on portals Add a test verifying that when the device has detected a captive portal, or when the user is trying to login to a captive portal, the captive portal network does not become the default network if another network can provide internet access. This follows R CDD requirements. Test: atest CtsNetTestCases:android.net.cts.CaptivePortalTest Bug: 152280218 Merged-In: I6a97ed26dba665efdc67abb2371e0fc30ede020c Change-Id: I6a97ed26dba665efdc67abb2371e0fc30ede020c --- tests/cts/net/Android.bp | 1 + .../src/android/net/cts/CaptivePortalTest.kt | 254 ++++++++++++++++++ 2 files changed, 255 insertions(+) create mode 100644 tests/cts/net/src/android/net/cts/CaptivePortalTest.kt diff --git a/tests/cts/net/Android.bp b/tests/cts/net/Android.bp index 76bb27e448..46fae33b9b 100644 --- a/tests/cts/net/Android.bp +++ b/tests/cts/net/Android.bp @@ -47,6 +47,7 @@ java_defaults { "mockwebserver", "junit", "junit-params", + "libnanohttpd", "truth-prebuilt", ], diff --git a/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt b/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt new file mode 100644 index 0000000000..4418e1740e --- /dev/null +++ b/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt @@ -0,0 +1,254 @@ +/* + * 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.cts + +import android.Manifest.permission.NETWORK_SETTINGS +import android.Manifest.permission.READ_DEVICE_CONFIG +import android.Manifest.permission.WRITE_DEVICE_CONFIG +import android.content.pm.PackageManager.FEATURE_TELEPHONY +import android.content.pm.PackageManager.FEATURE_WIFI +import android.net.ConnectivityManager +import android.net.ConnectivityManager.NetworkCallback +import android.net.Network +import android.net.NetworkCapabilities +import android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL +import android.net.NetworkCapabilities.TRANSPORT_WIFI +import android.net.NetworkRequest +import android.net.Uri +import android.net.cts.util.CtsNetUtils +import android.net.wifi.WifiManager +import android.os.ConditionVariable +import android.platform.test.annotations.AppModeFull +import android.provider.DeviceConfig +import android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY +import android.text.TextUtils +import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation +import androidx.test.runner.AndroidJUnit4 +import com.android.compatibility.common.util.SystemUtil +import fi.iki.elonen.NanoHTTPD +import fi.iki.elonen.NanoHTTPD.Response.IStatus +import fi.iki.elonen.NanoHTTPD.Response.Status +import junit.framework.AssertionFailedError +import org.junit.After +import org.junit.Assume.assumeTrue +import org.junit.Before +import org.junit.runner.RunWith +import java.util.concurrent.CompletableFuture +import java.util.concurrent.TimeUnit +import java.util.concurrent.TimeoutException +import kotlin.test.Test +import kotlin.test.assertNotEquals +import kotlin.test.assertTrue + +private const val TEST_CAPTIVE_PORTAL_HTTPS_URL_SETTING = "test_captive_portal_https_url" +private const val TEST_CAPTIVE_PORTAL_HTTP_URL_SETTING = "test_captive_portal_http_url" +private const val TEST_URL_EXPIRATION_TIME = "test_url_expiration_time" + +private const val TEST_HTTPS_URL_PATH = "https_path" +private const val TEST_HTTP_URL_PATH = "http_path" +private const val TEST_PORTAL_URL_PATH = "portal_path" + +private const val LOCALHOST_HOSTNAME = "localhost" + +// Re-connecting to the AP, obtaining an IP address, revalidating can take a long time +private const val WIFI_CONNECT_TIMEOUT_MS = 120_000L +private const val TEST_TIMEOUT_MS = 10_000L + +private fun CompletableFuture.assertGet(timeoutMs: Long, message: String): T { + try { + return get(timeoutMs, TimeUnit.MILLISECONDS) + } catch (e: TimeoutException) { + throw AssertionFailedError(message) + } +} + +@AppModeFull(reason = "WRITE_DEVICE_CONFIG permission can't be granted to instant apps") +@RunWith(AndroidJUnit4::class) +class CaptivePortalTest { + private val context: android.content.Context by lazy { getInstrumentation().context } + private val wm by lazy { context.getSystemService(WifiManager::class.java) } + private val cm by lazy { context.getSystemService(ConnectivityManager::class.java) } + private val pm by lazy { context.packageManager } + private val utils by lazy { CtsNetUtils(context) } + + private val server = HttpServer() + + @Before + fun setUp() { + doAsShell(READ_DEVICE_CONFIG) { + // Verify that the test URLs are not normally set on the device, but do not fail if the + // test URLs are set to what this test uses (URLs on localhost), in case the test was + // interrupted manually and rerun. + assertEmptyOrLocalhostUrl(TEST_CAPTIVE_PORTAL_HTTPS_URL_SETTING) + assertEmptyOrLocalhostUrl(TEST_CAPTIVE_PORTAL_HTTP_URL_SETTING) + } + clearTestUrls() + server.start() + } + + @After + fun tearDown() { + clearTestUrls() + server.stop() + } + + private fun assertEmptyOrLocalhostUrl(urlKey: String) { + val url = DeviceConfig.getProperty(NAMESPACE_CONNECTIVITY, urlKey) + assertTrue(TextUtils.isEmpty(url) || LOCALHOST_HOSTNAME == Uri.parse(url).host, + "$urlKey must not be set in production scenarios (current value: $url)") + } + + private fun clearTestUrls() { + setHttpsUrl(null) + setHttpUrl(null) + setUrlExpiration(null) + } + + @Test + fun testCaptivePortalIsNotDefaultNetwork() { + assumeTrue(pm.hasSystemFeature(FEATURE_TELEPHONY)) + assumeTrue(pm.hasSystemFeature(FEATURE_WIFI)) + utils.connectToWifi() + utils.connectToCell() + + // Have network validation use a local server that serves a HTTPS error / HTTP redirect + server.addResponse(TEST_PORTAL_URL_PATH, Status.OK, + content = "Test captive portal content") + server.addResponse(TEST_HTTPS_URL_PATH, Status.INTERNAL_ERROR) + server.addResponse(TEST_HTTP_URL_PATH, Status.REDIRECT, + locationHeader = server.makeUrl(TEST_PORTAL_URL_PATH)) + setHttpsUrl(server.makeUrl(TEST_HTTPS_URL_PATH)) + setHttpUrl(server.makeUrl(TEST_HTTP_URL_PATH)) + // URL expiration needs to be in the next 10 minutes + setUrlExpiration(System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(9)) + + // Expect the portal content to be fetched at some point after detecting the portal. + // Some implementations may fetch the URL before startCaptivePortalApp is called. + val portalContentRequestCv = server.addExpectRequestCv(TEST_PORTAL_URL_PATH) + + // Wait for a captive portal to be detected on the network + val wifiNetworkFuture = CompletableFuture() + val wifiCb = object : NetworkCallback() { + override fun onCapabilitiesChanged( + network: Network, + nc: NetworkCapabilities + ) { + if (nc.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) { + wifiNetworkFuture.complete(network) + } + } + } + cm.requestNetwork(NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI).build(), wifiCb) + + try { + reconnectWifi() + val network = wifiNetworkFuture.assertGet(WIFI_CONNECT_TIMEOUT_MS, + "Captive portal not detected after ${WIFI_CONNECT_TIMEOUT_MS}ms") + + val wifiDefaultMessage = "Wifi should not be the default network when a captive " + + "portal was detected and another network (mobile data) can provide internet " + + "access." + assertNotEquals(network, cm.activeNetwork, wifiDefaultMessage) + + doAsShell(NETWORK_SETTINGS) { cm.startCaptivePortalApp(network) } + assertTrue(portalContentRequestCv.block(TEST_TIMEOUT_MS), "The captive portal login " + + "page was still not fetched ${TEST_TIMEOUT_MS}ms after startCaptivePortalApp.") + + assertNotEquals(network, cm.activeNetwork, wifiDefaultMessage) + } finally { + cm.unregisterNetworkCallback(wifiCb) + server.stop() + // disconnectFromCell should be called after connectToCell + utils.disconnectFromCell() + } + + clearTestUrls() + reconnectWifi() + } + + private fun setHttpsUrl(url: String?) = setConfig(TEST_CAPTIVE_PORTAL_HTTPS_URL_SETTING, url) + private fun setHttpUrl(url: String?) = setConfig(TEST_CAPTIVE_PORTAL_HTTP_URL_SETTING, url) + private fun setUrlExpiration(timestamp: Long?) = setConfig(TEST_URL_EXPIRATION_TIME, + timestamp?.toString()) + + private fun setConfig(configKey: String, value: String?) { + doAsShell(WRITE_DEVICE_CONFIG) { + DeviceConfig.setProperty( + NAMESPACE_CONNECTIVITY, configKey, value, false /* makeDefault */) + } + } + + private fun doAsShell(vararg permissions: String, action: () -> Unit) { + // Wrap the below call to allow for more kotlin-like syntax + SystemUtil.runWithShellPermissionIdentity(action, permissions) + } + + private fun reconnectWifi() { + doAsShell(NETWORK_SETTINGS) { + assertTrue(wm.disconnect()) + assertTrue(wm.reconnect()) + } + } + + /** + * A minimal HTTP server running on localhost (loopback), on a random available port. + */ + private class HttpServer : NanoHTTPD("localhost", 0 /* auto-select the port */) { + // Map of URL path -> HTTP response code + private val responses = HashMap() + + // Map of path -> CV to open as soon as a request to the path is received + private val waitForRequestCv = HashMap() + + /** + * Create a URL string that, when fetched, will hit this server with the given URL [path]. + */ + fun makeUrl(path: String): String { + return Uri.Builder() + .scheme("http") + .encodedAuthority("localhost:$listeningPort") + .query(path) + .build() + .toString() + } + + fun addResponse( + path: String, + statusCode: IStatus, + locationHeader: String? = null, + content: String = "" + ) { + val response = newFixedLengthResponse(statusCode, "text/plain", content) + locationHeader?.let { response.addHeader("Location", it) } + responses[path] = response + } + + /** + * Create a [ConditionVariable] that will open when a request to [path] is received. + */ + fun addExpectRequestCv(path: String): ConditionVariable { + return ConditionVariable().apply { waitForRequestCv[path] = this } + } + + override fun serve(session: IHTTPSession): Response { + waitForRequestCv[session.queryParameterString]?.open() + return responses[session.queryParameterString] + // Default response is a 404 + ?: super.serve(session) + } + } +} \ No newline at end of file From cae5079d9d070cea3649c9f3e8e29ee30765948d Mon Sep 17 00:00:00 2001 From: Dominic Lemire Date: Wed, 15 Apr 2020 19:20:48 -0700 Subject: [PATCH 0941/1109] Fix error message in RestrictBackgroundNetworkTest Fixed the error message when the expected number of broadcasts is exceeded. Bug: 147139427 Change-Id: I7e69dca81abdb29a9eb7d110266edbe483e17a01 --- .../hostside/AbstractRestrictBackgroundNetworkTestCase.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index c8fe624e5e..638dabd979 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -30,6 +30,7 @@ import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isDozeModeSupp import static com.android.cts.net.hostside.NetworkPolicyTestUtils.restrictBackgroundValueToString; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -188,7 +189,9 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase { do { attempts++; count = getNumberBroadcastsReceived(receiverName, ACTION_RESTRICT_BACKGROUND_CHANGED); - if (count >= expectedCount) { + assertFalse("Expected count " + expectedCount + " but actual is " + count, + count > expectedCount); + if (count == expectedCount) { break; } Log.d(TAG, "Expecting count " + expectedCount + " but actual is " + count + " after " From 70285ea6d98dd7f7029f6cb5c68d6a40533dec56 Mon Sep 17 00:00:00 2001 From: Chenbo Feng Date: Fri, 21 Jun 2019 14:02:53 -0700 Subject: [PATCH 0942/1109] Add a test to check getUidStats binder call Check the apps cannot get the per uid stats of another uid by directly calling the getUidStats binder interface call provided by networkStatsService. Bug: 129151407 Test: NetworkStatsBinderTest Change-Id: Iabca53a8b37b259cf7e232d603676dbc9887084c --- .../net/cts/NetworkStatsBinderTest.java | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 tests/cts/net/src/android/net/cts/NetworkStatsBinderTest.java diff --git a/tests/cts/net/src/android/net/cts/NetworkStatsBinderTest.java b/tests/cts/net/src/android/net/cts/NetworkStatsBinderTest.java new file mode 100644 index 0000000000..1f3162fdd1 --- /dev/null +++ b/tests/cts/net/src/android/net/cts/NetworkStatsBinderTest.java @@ -0,0 +1,130 @@ +/* + * 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.cts; + +import static android.os.Process.INVALID_UID; + +import android.annotation.NonNull; +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.net.INetworkStatsService; +import android.net.TrafficStats; +import android.os.IBinder; +import android.os.Process; +import android.os.RemoteException; +import android.test.AndroidTestCase; +import android.util.SparseArray; + +import androidx.test.InstrumentationRegistry; + +import com.android.internal.util.CollectionUtils; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; +import java.util.function.Predicate; + +public class NetworkStatsBinderTest extends AndroidTestCase { + // NOTE: These are shamelessly copied from TrafficStats. + private static final int TYPE_RX_BYTES = 0; + private static final int TYPE_RX_PACKETS = 1; + private static final int TYPE_TX_BYTES = 2; + private static final int TYPE_TX_PACKETS = 3; + + private final SparseArray> mUidStatsQueryOpArray = new SparseArray<>(); + + @Override + protected void setUp() throws Exception { + mUidStatsQueryOpArray.put(TYPE_RX_BYTES, uid -> TrafficStats.getUidRxBytes(uid)); + mUidStatsQueryOpArray.put(TYPE_RX_PACKETS, uid -> TrafficStats.getUidRxPackets(uid)); + mUidStatsQueryOpArray.put(TYPE_TX_BYTES, uid -> TrafficStats.getUidTxBytes(uid)); + mUidStatsQueryOpArray.put(TYPE_TX_PACKETS, uid -> TrafficStats.getUidTxPackets(uid)); + } + + private long getUidStatsFromBinder(int uid, int type) throws Exception { + Method getServiceMethod = Class.forName("android.os.ServiceManager") + .getDeclaredMethod("getService", new Class[]{String.class}); + IBinder binder = (IBinder) getServiceMethod.invoke(null, Context.NETWORK_STATS_SERVICE); + INetworkStatsService nss = INetworkStatsService.Stub.asInterface(binder); + return nss.getUidStats(uid, type); + } + + private int getFirstAppUidThat(@NonNull Predicate predicate) { + PackageManager pm = InstrumentationRegistry.getContext().getPackageManager(); + List apps = pm.getInstalledPackages(0 /* flags */); + final PackageInfo match = CollectionUtils.find(apps, + it -> it.applicationInfo != null && predicate.test(it.applicationInfo.uid)); + if (match != null) return match.applicationInfo.uid; + return INVALID_UID; + } + + public void testAccessUidStatsFromBinder() throws Exception { + final int myUid = Process.myUid(); + final List testUidList = new ArrayList<>(); + + // Prepare uid list for testing. + testUidList.add(INVALID_UID); + testUidList.add(Process.ROOT_UID); + testUidList.add(Process.SYSTEM_UID); + testUidList.add(myUid); + testUidList.add(Process.LAST_APPLICATION_UID); + testUidList.add(Process.LAST_APPLICATION_UID + 1); + // If available, pick another existing uid for testing that is not already contained + // in the list above. + final int notMyUid = getFirstAppUidThat(uid -> uid >= 0 && !testUidList.contains(uid)); + if (notMyUid != INVALID_UID) testUidList.add(notMyUid); + + for (final int uid : testUidList) { + for (int i = 0; i < mUidStatsQueryOpArray.size(); i++) { + final int type = mUidStatsQueryOpArray.keyAt(i); + try { + final long uidStatsFromBinder = getUidStatsFromBinder(uid, type); + final long uidTrafficStats = mUidStatsQueryOpArray.get(type).apply(uid); + + // Verify that UNSUPPORTED is returned if the uid is not current app uid. + if (uid != myUid) { + assertEquals(uidStatsFromBinder, TrafficStats.UNSUPPORTED); + } + // Verify that returned result is the same with the result get from + // TrafficStats. + // TODO: If the test is flaky then it should instead assert that the values + // are approximately similar. + assertEquals("uidStats is not matched for query type " + type + + ", uid=" + uid + ", myUid=" + myUid, uidTrafficStats, + uidStatsFromBinder); + } catch (IllegalAccessException e) { + /* Java language access prevents exploitation. */ + return; + } catch (InvocationTargetException e) { + /* Underlying method has been changed. */ + return; + } catch (ClassNotFoundException e) { + /* not vulnerable if hidden API no longer available */ + return; + } catch (NoSuchMethodException e) { + /* not vulnerable if hidden API no longer available */ + return; + } catch (RemoteException e) { + return; + } + } + } + } +} From 33a88fbf5f5260700c835656f19b5fd2806b6f66 Mon Sep 17 00:00:00 2001 From: Remi NGUYEN VAN Date: Tue, 28 Apr 2020 08:25:34 +0000 Subject: [PATCH 0943/1109] Force reconnect in connectToWifi There is no guarantee that Wifi will automatically reconnect after enabling, especially in cases where no internet access was detected on the access point the last time it was connected. Use WifiManager#reconnect to force wifi to reconnect to the access point. The API is deprecated for general use, but system apps are documented as exempted from the deprecation. Bug: 152280218 Test: atest --rerun-until-failure 200 CtsNetTestCases:CaptivePortalTest Merged-In: Ia7d83337ee0ffad9414031711cf7e937b14f968d Change-Id: Ia7d83337ee0ffad9414031711cf7e937b14f968d --- tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java | 3 +++ 1 file changed, 3 insertions(+) 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 6214f89e98..824146fedf 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 @@ -16,6 +16,7 @@ package android.net.cts.util; +import static android.Manifest.permission.NETWORK_SETTINGS; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; @@ -107,6 +108,8 @@ public final class CtsNetUtils { boolean connected = false; try { SystemUtil.runShellCommand("svc wifi enable"); + SystemUtil.runWithShellPermissionIdentity(() -> mWifiManager.reconnect(), + NETWORK_SETTINGS); // Ensure we get both an onAvailable callback and a CONNECTIVITY_ACTION. wifiNetwork = callback.waitForAvailable(); assertNotNull(wifiNetwork); From 653d7ebb447e00753779634090381ba1fde5077e Mon Sep 17 00:00:00 2001 From: evitayan Date: Tue, 7 Apr 2020 15:16:08 -0700 Subject: [PATCH 0944/1109] Initial CL for testing IkeSession creation This commit: -Extend TunUtils for processing IKE packets -Add IkeSessionBaseTest containing common functionality for all IkeSession tests -Add end-to-end test for IKEv2 PSK verifying creating IKE SA, creating child SAs and closing sessions -Add basic tests for error scenarios Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: Ie6c18591ffcc883abbf0484d9a59dfda61b33257 --- tests/cts/net/ipsec/Android.bp | 1 + .../ipsec/ike/cts/IkeSessionParamsTest.java | 19 +- .../ike/cts/IkeSessionParamsTestBase.java | 85 ---- .../net/ipsec/ike/cts/IkeSessionPskTest.java | 258 ++++++++++++ .../net/ipsec/ike/cts/IkeSessionTestBase.java | 374 ++++++++++++++++++ .../net/ipsec/ike/cts/IkeTestBase.java | 6 +- .../net/ipsec/ike/cts/IkeTunUtils.java | 243 ++++++++++++ .../android/net/ipsec/ike/cts/TunUtils.java | 20 +- 8 files changed, 904 insertions(+), 102 deletions(-) delete mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTestBase.java create mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java create mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java create mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTunUtils.java diff --git a/tests/cts/net/ipsec/Android.bp b/tests/cts/net/ipsec/Android.bp index f1f120b32b..16bdb0548a 100644 --- a/tests/cts/net/ipsec/Android.bp +++ b/tests/cts/net/ipsec/Android.bp @@ -33,6 +33,7 @@ android_test { "androidx.test.ext.junit", "compatibility-device-util-axt", "ctstestrunner-axt", + "net-tests-utils", ], platform_apis: true, diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java index 6fc7cb3634..c767b78120 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java @@ -46,6 +46,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; import com.android.internal.net.ipsec.ike.testutils.CertUtils; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -63,7 +64,7 @@ import java.util.Set; import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) -public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { +public final class IkeSessionParamsTest extends IkeSessionTestBase { private static final int HARD_LIFETIME_SECONDS = (int) TimeUnit.HOURS.toSeconds(20L); private static final int SOFT_LIFETIME_SECONDS = (int) TimeUnit.HOURS.toSeconds(10L); private static final int DPD_DELAY_SECONDS = (int) TimeUnit.MINUTES.toSeconds(10L); @@ -105,6 +106,9 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { @Before public void setUp() throws Exception { + // This address is never used except for setting up the test network + setUpTestNetwork(IPV4_ADDRESS_LOCAL); + mServerCaCert = CertUtils.createCertFromPemFile("server-a-self-signed-ca.pem"); mClientEndCert = CertUtils.createCertFromPemFile("client-a-end-cert.pem"); mClientIntermediateCaCertOne = @@ -114,6 +118,11 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { mClientPrivateKey = CertUtils.createRsaPrivateKeyFromKeyFile("client-a-private-key.key"); } + @After + public void tearDown() throws Exception { + tearDownTestNetwork(); + } + private static EapSessionConfig.Builder createEapOnlySafeMethodsBuilder() { return new EapSessionConfig.Builder() .setEapIdentity(EAP_IDENTITY) @@ -131,7 +140,7 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { */ private IkeSessionParams.Builder createIkeParamsBuilderMinimum() { return new IkeSessionParams.Builder(sContext) - .setNetwork(sTunNetwork) + .setNetwork(mTunNetwork) .setServerHostname(IPV4_ADDRESS_REMOTE.getHostAddress()) .addSaProposal(SA_PROPOSAL) .setLocalIdentification(LOCAL_ID) @@ -145,7 +154,7 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { * @see #createIkeParamsBuilderMinimum */ private void verifyIkeParamsMinimum(IkeSessionParams sessionParams) { - assertEquals(sTunNetwork, sessionParams.getNetwork()); + assertEquals(mTunNetwork, sessionParams.getNetwork()); assertEquals(IPV4_ADDRESS_REMOTE.getHostAddress(), sessionParams.getServerHostname()); assertEquals(Arrays.asList(SA_PROPOSAL), sessionParams.getSaProposals()); assertEquals(LOCAL_ID, sessionParams.getLocalIdentification()); @@ -268,7 +277,7 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { */ private IkeSessionParams.Builder createIkeParamsBuilderMinimumWithoutAuth() { return new IkeSessionParams.Builder(sContext) - .setNetwork(sTunNetwork) + .setNetwork(mTunNetwork) .setServerHostname(IPV4_ADDRESS_REMOTE.getHostAddress()) .addSaProposal(SA_PROPOSAL) .setLocalIdentification(LOCAL_ID) @@ -282,7 +291,7 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { * @see #createIkeParamsBuilderMinimumWithoutAuth */ private void verifyIkeParamsMinimumWithoutAuth(IkeSessionParams sessionParams) { - assertEquals(sTunNetwork, sessionParams.getNetwork()); + assertEquals(mTunNetwork, sessionParams.getNetwork()); assertEquals(IPV4_ADDRESS_REMOTE.getHostAddress(), sessionParams.getServerHostname()); assertEquals(Arrays.asList(SA_PROPOSAL), sessionParams.getSaProposals()); assertEquals(LOCAL_ID, sessionParams.getLocalIdentification()); diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTestBase.java deleted file mode 100644 index c3e3ba353c..0000000000 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTestBase.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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.ipsec.ike.cts; - -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.LinkAddress; -import android.net.Network; -import android.net.TestNetworkInterface; -import android.net.TestNetworkManager; -import android.net.ipsec.ike.cts.TestNetworkUtils.TestNetworkCallback; -import android.os.Binder; -import android.os.IBinder; -import android.os.ParcelFileDescriptor; -import android.platform.test.annotations.AppModeFull; - -import androidx.test.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@AppModeFull(reason = "MANAGE_TEST_NETWORKS permission can't be granted to instant apps") -abstract class IkeSessionParamsTestBase extends IkeTestBase { - // Static state to reduce setup/teardown - static ConnectivityManager sCM; - static TestNetworkManager sTNM; - static ParcelFileDescriptor sTunFd; - static TestNetworkCallback sTunNetworkCallback; - static Network sTunNetwork; - - static Context sContext = InstrumentationRegistry.getContext(); - static IBinder sBinder = new Binder(); - - // This method is guaranteed to run in subclasses and will run before subclasses' @BeforeClass - // methods. - @BeforeClass - public static void setUpTestNetworkBeforeClass() throws Exception { - InstrumentationRegistry.getInstrumentation() - .getUiAutomation() - .adoptShellPermissionIdentity(); - sCM = (ConnectivityManager) sContext.getSystemService(Context.CONNECTIVITY_SERVICE); - sTNM = (TestNetworkManager) sContext.getSystemService(Context.TEST_NETWORK_SERVICE); - - TestNetworkInterface testIface = - sTNM.createTunInterface( - new LinkAddress[] {new LinkAddress(IPV4_ADDRESS_LOCAL, IP4_PREFIX_LEN)}); - - sTunFd = testIface.getFileDescriptor(); - sTunNetworkCallback = - TestNetworkUtils.setupAndGetTestNetwork( - sCM, sTNM, testIface.getInterfaceName(), sBinder); - sTunNetwork = sTunNetworkCallback.getNetworkBlocking(); - } - - // This method is guaranteed to run in subclasses and will run after subclasses' @AfterClass - // methods. - @AfterClass - public static void tearDownTestNetworkAfterClass() throws Exception { - sCM.unregisterNetworkCallback(sTunNetworkCallback); - - sTNM.teardownTestNetwork(sTunNetwork); - sTunFd.close(); - - InstrumentationRegistry.getInstrumentation() - .getUiAutomation() - .dropShellPermissionIdentity(); - } -} 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 new file mode 100644 index 0000000000..ed67dd1bd7 --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java @@ -0,0 +1,258 @@ +/* + * 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.ipsec.ike.cts; + +import static android.net.ipsec.ike.IkeSessionConfiguration.EXTENSION_TYPE_FRAGMENTATION; +import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN; +import static android.system.OsConstants.AF_INET; +import static android.system.OsConstants.AF_INET6; + +import static com.android.internal.util.HexDump.hexStringToByteArray; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import android.net.ipsec.ike.ChildSessionConfiguration; +import android.net.ipsec.ike.IkeFqdnIdentification; +import android.net.ipsec.ike.IkeSession; +import android.net.ipsec.ike.IkeSessionConfiguration; +import android.net.ipsec.ike.IkeSessionConnectionInfo; +import android.net.ipsec.ike.IkeSessionParams; +import android.net.ipsec.ike.TunnelModeChildSessionParams; +import android.net.ipsec.ike.exceptions.IkeException; +import android.net.ipsec.ike.exceptions.IkeProtocolException; +import android.platform.test.annotations.AppModeFull; + +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.net.InetAddress; +import java.util.Arrays; + +@RunWith(AndroidJUnit4.class) +@AppModeFull(reason = "MANAGE_TEST_NETWORKS permission can't be granted to instant apps") +public class IkeSessionPskTest extends IkeSessionTestBase { + // Test vectors for success workflow + private static final String SUCCESS_IKE_INIT_RESP = + "46B8ECA1E0D72A18B45427679F9245D421202220000000000000015022000030" + + "0000002C010100040300000C0100000C800E0080030000080300000203000008" + + "0200000200000008040000022800008800020000A7AA3435D088EC1A2B7C2A47" + + "1FA1B85F1066C9B2006E7C353FB5B5FDBC2A88347ED2C6F5B7A265D03AE34039" + + "6AAC0145CFCC93F8BDB219DDFF22A603B8856A5DC59B6FAB7F17C5660CF38670" + + "8794FC72F273ADEB7A4F316519794AED6F8AB61F95DFB360FAF18C6C8CABE471" + + "6E18FE215348C2E582171A57FC41146B16C4AFE429000024A634B61C0E5C90C6" + + "8D8818B0955B125A9B1DF47BBD18775710792E651083105C2900001C00004004" + + "406FA3C5685A16B9B72C7F2EEE9993462C619ABE2900001C00004005AF905A87" + + "0A32222AA284A7070585601208A282F0290000080000402E290000100000402F" + + "00020003000400050000000800004014"; + private static final String SUCCESS_IKE_AUTH_RESP = + "46B8ECA1E0D72A18B45427679F9245D42E20232000000001000000EC240000D0" + + "0D06D37198F3F0962DE8170D66F1A9008267F98CDD956D984BDCED2FC7FAF84A" + + "A6664EF25049B46B93C9ED420488E0C172AA6635BF4011C49792EF2B88FE7190" + + "E8859FEEF51724FD20C46E7B9A9C3DC4708EF7005707A18AB747C903ABCEAC5C" + + "6ECF5A5FC13633DCE3844A920ED10EF202F115DBFBB5D6D2D7AB1F34EB08DE7C" + + "A54DCE0A3A582753345CA2D05A0EFDB9DC61E81B2483B7D13EEE0A815D37252C" + + "23D2F29E9C30658227D2BB0C9E1A481EAA80BC6BE9006BEDC13E925A755A0290" + + "AEC4164D29997F52ED7DCC2E"; + private static final String SUCCESS_CREATE_CHILD_RESP = + "46B8ECA1E0D72A18B45427679F9245D42E20242000000002000000CC210000B0" + + "484565D4AF6546274674A8DE339E9C9584EE2326AB9260F41C4D0B6C5B02D1D" + + "2E8394E3CDE3094895F2ACCABCDCA8E82960E5196E9622BD13745FC8D6A2BED" + + "E561FF5D9975421BC463C959A3CBA3478256B6D278159D99B512DDF56AC1658" + + "63C65A986F395FE8B1476124B91F83FD7865304EB95B22CA4DD9601DA7A2533" + + "ABF4B36EB1B8CD09522F6A600032316C74E562E6756D9D49D945854E2ABDC4C" + + "3AF36305353D60D40B58BE44ABF82"; + private static final String SUCCESS_DELETE_CHILD_RESP = + "46B8ECA1E0D72A18B45427679F9245D42E202520000000030000004C2A000030" + + "0C5CEB882DBCA65CE32F4C53909335F1365C91C555316C5E9D9FB553F7AA916" + + "EF3A1D93460B7FABAF0B4B854"; + private static final String SUCCESS_DELETE_IKE_RESP = + "46B8ECA1E0D72A18B45427679F9245D42E202520000000040000004C00000030" + + "9352D71100777B00ABCC6BD7DBEA697827FFAAA48DF9A54D1D68161939F5DC8" + + "6743A7CEB2BE34AC00095A5B8"; + + private static final long IKE_INIT_SPI = Long.parseLong("46B8ECA1E0D72A18", 16); + + private static final TunnelModeChildSessionParams CHILD_PARAMS = + new TunnelModeChildSessionParams.Builder() + .addSaProposal(SaProposalTest.buildChildSaProposalWithNormalModeCipher()) + .addSaProposal(SaProposalTest.buildChildSaProposalWithCombinedModeCipher()) + .addInternalAddressRequest(AF_INET) + .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) { + return new IkeSession( + sContext, + ikeParams, + CHILD_PARAMS, + mUserCbExecutor, + mIkeSessionCallback, + mFirstChildSessionCallback); + } + + @Test + public void testIkeSessionSetupAndManageChildSas() throws Exception { + // Open IKE Session + IkeSession ikeSession = openIkeSession(createIkeSessionParams(mRemoteAddress)); + int expectedMsgId = 0; + mTunUtils.awaitReqAndInjectResp( + IKE_INIT_SPI, + expectedMsgId++, + false /* expectedUseEncap */, + hexStringToByteArray(SUCCESS_IKE_INIT_RESP)); + + mTunUtils.awaitReqAndInjectResp( + IKE_INIT_SPI, + expectedMsgId++, + true /* expectedUseEncap */, + hexStringToByteArray(SUCCESS_IKE_AUTH_RESP)); + + // Verify opening IKE Session + IkeSessionConfiguration ikeConfig = mIkeSessionCallback.awaitIkeConfig(); + assertNotNull(ikeConfig); + assertEquals(EXPECTED_REMOTE_APP_VERSION_EMPTY, ikeConfig.getRemoteApplicationVersion()); + assertTrue(ikeConfig.getRemoteVendorIds().isEmpty()); + assertTrue(ikeConfig.getPcscfServers().isEmpty()); + assertTrue(ikeConfig.isIkeExtensionEnabled(EXTENSION_TYPE_FRAGMENTATION)); + + IkeSessionConnectionInfo ikeConnectInfo = ikeConfig.getIkeSessionConnectionInfo(); + assertNotNull(ikeConnectInfo); + assertEquals(mLocalAddress, ikeConnectInfo.getLocalAddress()); + assertEquals(mRemoteAddress, ikeConnectInfo.getRemoteAddress()); + assertEquals(mTunNetwork, ikeConnectInfo.getNetwork()); + + // Verify opening first Child Session + ChildSessionConfiguration firstChildConfig = mFirstChildSessionCallback.awaitChildConfig(); + assertNotNull(firstChildConfig); + assertEquals( + Arrays.asList(EXPECTED_INBOUND_TS), firstChildConfig.getInboundTrafficSelectors()); + assertEquals(Arrays.asList(DEFAULT_V4_TS), firstChildConfig.getOutboundTrafficSelectors()); + assertEquals( + Arrays.asList(EXPECTED_INTERNAL_LINK_ADDR), + firstChildConfig.getInternalAddresses()); + assertTrue(firstChildConfig.getInternalSubnets().isEmpty()); + assertTrue(firstChildConfig.getInternalDnsServers().isEmpty()); + assertTrue(firstChildConfig.getInternalDhcpServers().isEmpty()); + + // Open additional Child Session + TestChildSessionCallback additionalChildCb = new TestChildSessionCallback(); + ikeSession.openChildSession(CHILD_PARAMS, additionalChildCb); + mTunUtils.awaitReqAndInjectResp( + IKE_INIT_SPI, + expectedMsgId++, + true /* expectedUseEncap */, + hexStringToByteArray(SUCCESS_CREATE_CHILD_RESP)); + + // Verify opening additional Child Session + ChildSessionConfiguration additionalChildConfig = additionalChildCb.awaitChildConfig(); + assertNotNull(additionalChildConfig); + assertEquals( + 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()); + + // Close additional Child Session + ikeSession.closeChildSession(additionalChildCb); + mTunUtils.awaitReqAndInjectResp( + IKE_INIT_SPI, + expectedMsgId++, + true /* expectedUseEncap */, + hexStringToByteArray(SUCCESS_DELETE_CHILD_RESP)); + + additionalChildCb.awaitOnClosed(); + + // Close IKE Session + ikeSession.close(); + mTunUtils.awaitReqAndInjectResp( + IKE_INIT_SPI, + expectedMsgId++, + true /* expectedUseEncap */, + hexStringToByteArray(SUCCESS_DELETE_IKE_RESP)); + + mFirstChildSessionCallback.awaitOnClosed(); + mIkeSessionCallback.awaitOnClosed(); + + // TODO: verify IpSecTransform pair is created and deleted + } + + @Test + public void testIkeSessionKill() throws Exception { + // Open IKE Session + IkeSession ikeSession = openIkeSession(createIkeSessionParams(mRemoteAddress)); + int expectedMsgId = 0; + mTunUtils.awaitReqAndInjectResp( + IKE_INIT_SPI, + expectedMsgId++, + false /* expectedUseEncap */, + hexStringToByteArray(SUCCESS_IKE_INIT_RESP)); + + mTunUtils.awaitReqAndInjectResp( + IKE_INIT_SPI, + expectedMsgId++, + true /* expectedUseEncap */, + hexStringToByteArray(SUCCESS_IKE_AUTH_RESP)); + + ikeSession.kill(); + + mFirstChildSessionCallback.awaitOnClosed(); + mIkeSessionCallback.awaitOnClosed(); + } + + @Test + public void testIkeInitFail() throws Exception { + String ikeInitFailRespHex = + "46B8ECA1E0D72A180000000000000000292022200000000000000024000000080000000E"; + + // Open IKE Session + IkeSession ikeSession = openIkeSession(createIkeSessionParams(mRemoteAddress)); + int expectedMsgId = 0; + mTunUtils.awaitReqAndInjectResp( + IKE_INIT_SPI, + expectedMsgId++, + false /* expectedUseEncap */, + hexStringToByteArray(ikeInitFailRespHex)); + + IkeException exception = mIkeSessionCallback.awaitOnClosedException(); + assertNotNull(exception); + assertTrue(exception instanceof IkeProtocolException); + IkeProtocolException protocolException = (IkeProtocolException) exception; + assertEquals(ERROR_TYPE_NO_PROPOSAL_CHOSEN, protocolException.getErrorType()); + assertArrayEquals(EXPECTED_PROTOCOL_ERROR_DATA_NONE, protocolException.getErrorData()); + } + + // TODO(b/148689509): Verify rekey process and handling IKE_AUTH failure +} 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 new file mode 100644 index 0000000000..deba8fd985 --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java @@ -0,0 +1,374 @@ +/* + * 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 + * + * 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.ipsec.ike.cts; + +import static android.app.AppOpsManager.OP_MANAGE_IPSEC_TUNNELS; + +import android.annotation.NonNull; +import android.app.AppOpsManager; +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.InetAddresses; +import android.net.IpSecTransform; +import android.net.LinkAddress; +import android.net.Network; +import android.net.TestNetworkInterface; +import android.net.TestNetworkManager; +import android.net.annotations.PolicyDirection; +import android.net.ipsec.ike.ChildSessionCallback; +import android.net.ipsec.ike.ChildSessionConfiguration; +import android.net.ipsec.ike.IkeSessionCallback; +import android.net.ipsec.ike.IkeSessionConfiguration; +import android.net.ipsec.ike.IkeTrafficSelector; +import android.net.ipsec.ike.cts.TestNetworkUtils.TestNetworkCallback; +import android.net.ipsec.ike.exceptions.IkeException; +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; + +import com.android.compatibility.common.util.SystemUtil; +import com.android.testutils.ArrayTrackRecord; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.runner.RunWith; + +import java.net.Inet4Address; +import java.net.InetAddress; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +/** + * Package private base class for testing IkeSessionParams and IKE exchanges. + * + *

    Subclasses MUST explicitly call #setUpTestNetwork and #tearDownTestNetwork to be able to use + * the test network + */ +@RunWith(AndroidJUnit4.class) +@AppModeFull(reason = "MANAGE_TEST_NETWORKS permission can't be granted to instant apps") +abstract class IkeSessionTestBase extends IkeTestBase { + // Package-wide common expected results that will be shared by all IKE/Child SA creation tests + static final String EXPECTED_REMOTE_APP_VERSION_EMPTY = ""; + static final byte[] EXPECTED_PROTOCOL_ERROR_DATA_NONE = new byte[0]; + static final InetAddress EXPECTED_INTERNAL_ADDR = + InetAddresses.parseNumericAddress("198.51.100.10"); + static final LinkAddress EXPECTED_INTERNAL_LINK_ADDR = + new LinkAddress(EXPECTED_INTERNAL_ADDR, IP4_PREFIX_LEN); + static final IkeTrafficSelector EXPECTED_INBOUND_TS = + new IkeTrafficSelector( + MIN_PORT, MAX_PORT, EXPECTED_INTERNAL_ADDR, EXPECTED_INTERNAL_ADDR); + + // Static state to reduce setup/teardown + static Context sContext = InstrumentationRegistry.getContext(); + static ConnectivityManager sCM = + (ConnectivityManager) sContext.getSystemService(Context.CONNECTIVITY_SERVICE); + static TestNetworkManager sTNM; + + private static final int TIMEOUT_MS = 500; + + // Constants to be used for providing different IP addresses for each tests + private static final byte IP_ADDR_LAST_BYTE_MAX = (byte) 100; + private static final byte[] INITIAL_AVAILABLE_IP4_ADDR_LOCAL = + InetAddresses.parseNumericAddress("192.0.2.1").getAddress(); + private static final byte[] INITIAL_AVAILABLE_IP4_ADDR_REMOTE = + InetAddresses.parseNumericAddress("198.51.100.1").getAddress(); + private static final byte[] NEXT_AVAILABLE_IP4_ADDR_LOCAL = INITIAL_AVAILABLE_IP4_ADDR_LOCAL; + private static final byte[] NEXT_AVAILABLE_IP4_ADDR_REMOTE = INITIAL_AVAILABLE_IP4_ADDR_REMOTE; + + ParcelFileDescriptor mTunFd; + TestNetworkCallback mTunNetworkCallback; + Network mTunNetwork; + IkeTunUtils mTunUtils; + + InetAddress mLocalAddress; + InetAddress mRemoteAddress; + + Executor mUserCbExecutor; + TestIkeSessionCallback mIkeSessionCallback; + TestChildSessionCallback mFirstChildSessionCallback; + + // This method is guaranteed to run in subclasses and will run before subclasses' @BeforeClass + // methods. + @BeforeClass + public static void setUpPermissionBeforeClass() throws Exception { + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .adoptShellPermissionIdentity(); + sTNM = (TestNetworkManager) sContext.getSystemService(Context.TEST_NETWORK_SERVICE); + + // 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 + // right appop permissions. + setAppOp(OP_MANAGE_IPSEC_TUNNELS, true); + } + + // This method is guaranteed to run in subclasses and will run after subclasses' @AfterClass + // methods. + @AfterClass + public static void tearDownPermissionAfterClass() throws Exception { + setAppOp(OP_MANAGE_IPSEC_TUNNELS, false); + + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .dropShellPermissionIdentity(); + } + + @Before + public void setUp() throws Exception { + mLocalAddress = getNextAvailableIpv4AddressLocal(); + mRemoteAddress = getNextAvailableIpv4AddressRemote(); + setUpTestNetwork(mLocalAddress); + + mUserCbExecutor = Executors.newSingleThreadExecutor(); + mIkeSessionCallback = new TestIkeSessionCallback(); + mFirstChildSessionCallback = new TestChildSessionCallback(); + } + + @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 { + int prefixLen = localAddr instanceof Inet4Address ? IP4_PREFIX_LEN : IP4_PREFIX_LEN; + + TestNetworkInterface testIface = + sTNM.createTunInterface(new LinkAddress[] {new LinkAddress(localAddr, prefixLen)}); + + mTunFd = testIface.getFileDescriptor(); + mTunNetworkCallback = + TestNetworkUtils.setupAndGetTestNetwork( + sCM, sTNM, testIface.getInterfaceName(), new Binder()); + mTunNetwork = mTunNetworkCallback.getNetworkBlocking(); + mTunUtils = new IkeTunUtils(mTunFd); + } + + void tearDownTestNetwork() throws Exception { + sCM.unregisterNetworkCallback(mTunNetworkCallback); + + sTNM.teardownTestNetwork(mTunNetwork); + mTunFd.close(); + } + + private static void setAppOp(int appop, boolean allow) { + String opName = AppOpsManager.opToName(appop); + for (String pkg : new String[] {"com.android.shell", sContext.getPackageName()}) { + String cmd = + String.format( + "appops set %s %s %s", + pkg, // Package name + opName, // Appop + (allow ? "allow" : "deny")); // Action + Log.d("IKE", "CTS setAppOp cmd " + cmd); + + String result = SystemUtil.runShellCommand(cmd); + } + } + + Inet4Address getNextAvailableIpv4AddressLocal() throws Exception { + return (Inet4Address) + getNextAvailableAddress( + NEXT_AVAILABLE_IP4_ADDR_LOCAL, + INITIAL_AVAILABLE_IP4_ADDR_LOCAL, + false /* isIp6 */); + } + + Inet4Address getNextAvailableIpv4AddressRemote() throws Exception { + return (Inet4Address) + getNextAvailableAddress( + NEXT_AVAILABLE_IP4_ADDR_REMOTE, + INITIAL_AVAILABLE_IP4_ADDR_REMOTE, + false /* isIp6 */); + } + + InetAddress getNextAvailableAddress( + byte[] nextAddressBytes, byte[] initialAddressBytes, boolean isIp6) throws Exception { + int addressLen = isIp6 ? IP6_ADDRESS_LEN : IP4_ADDRESS_LEN; + + synchronized (nextAddressBytes) { + if (nextAddressBytes[addressLen - 1] == IP_ADDR_LAST_BYTE_MAX) { + resetNextAvailableAddress(nextAddressBytes, initialAddressBytes); + } + + InetAddress address = InetAddress.getByAddress(nextAddressBytes); + nextAddressBytes[addressLen - 1]++; + return address; + } + } + + private void resetNextAvailableAddress(byte[] nextAddressBytes, byte[] initialAddressBytes) { + synchronized (nextAddressBytes) { + System.arraycopy( + nextAddressBytes, 0, initialAddressBytes, 0, initialAddressBytes.length); + } + } + + static class TestIkeSessionCallback implements IkeSessionCallback { + private CompletableFuture mFutureIkeConfig = + new CompletableFuture<>(); + private CompletableFuture mFutureOnClosedCall = new CompletableFuture<>(); + private CompletableFuture mFutureOnClosedException = + new CompletableFuture<>(); + + private int mOnErrorExceptionsCount = 0; + private ArrayTrackRecord mOnErrorExceptionsTrackRecord = + new ArrayTrackRecord<>(); + + @Override + public void onOpened(@NonNull IkeSessionConfiguration sessionConfiguration) { + mFutureIkeConfig.complete(sessionConfiguration); + } + + @Override + public void onClosed() { + mFutureOnClosedCall.complete(true /* unused */); + } + + @Override + public void onClosedExceptionally(@NonNull IkeException exception) { + mFutureOnClosedException.complete(exception); + } + + @Override + public void onError(@NonNull IkeProtocolException exception) { + mOnErrorExceptionsTrackRecord.add(exception); + } + + public IkeSessionConfiguration awaitIkeConfig() throws Exception { + return mFutureIkeConfig.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); + } + + public IkeException awaitOnClosedException() throws Exception { + return mFutureOnClosedException.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); + } + + public IkeProtocolException awaitNextOnErrorException() { + return mOnErrorExceptionsTrackRecord.poll( + (long) TIMEOUT_MS, + mOnErrorExceptionsCount++, + (transform) -> { + return true; + }); + } + + public void awaitOnClosed() throws Exception { + mFutureOnClosedCall.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); + } + } + + static class TestChildSessionCallback implements ChildSessionCallback { + private CompletableFuture mFutureChildConfig = + new CompletableFuture<>(); + private CompletableFuture mFutureOnClosedCall = new CompletableFuture<>(); + private CompletableFuture mFutureOnClosedException = + new CompletableFuture<>(); + + private int mCreatedIpSecTransformCount = 0; + private int mDeletedIpSecTransformCount = 0; + private ArrayTrackRecord mCreatedIpSecTransformsTrackRecord = + new ArrayTrackRecord<>(); + private ArrayTrackRecord mDeletedIpSecTransformsTrackRecord = + new ArrayTrackRecord<>(); + + @Override + public void onOpened(@NonNull ChildSessionConfiguration sessionConfiguration) { + mFutureChildConfig.complete(sessionConfiguration); + } + + @Override + public void onClosed() { + mFutureOnClosedCall.complete(true /* unused */); + } + + @Override + public void onClosedExceptionally(@NonNull IkeException exception) { + mFutureOnClosedException.complete(exception); + } + + @Override + public void onIpSecTransformCreated(@NonNull IpSecTransform ipSecTransform, int direction) { + mCreatedIpSecTransformsTrackRecord.add( + new IpSecTransformCallRecord(ipSecTransform, direction)); + } + + @Override + public void onIpSecTransformDeleted(@NonNull IpSecTransform ipSecTransform, int direction) { + mDeletedIpSecTransformsTrackRecord.add( + new IpSecTransformCallRecord(ipSecTransform, direction)); + } + + public ChildSessionConfiguration awaitChildConfig() throws Exception { + return mFutureChildConfig.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); + } + + public IkeException awaitOnClosedException() throws Exception { + return mFutureOnClosedException.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); + } + + public IpSecTransformCallRecord awaitNextCreatedIpSecTransform() { + return mCreatedIpSecTransformsTrackRecord.poll( + (long) TIMEOUT_MS, + mCreatedIpSecTransformCount++, + (transform) -> { + return true; + }); + } + + public IpSecTransformCallRecord awaitNextDeletedIpSecTransform() { + return mDeletedIpSecTransformsTrackRecord.poll( + (long) TIMEOUT_MS, + mDeletedIpSecTransformCount++, + (transform) -> { + return true; + }); + } + + public void awaitOnClosed() throws Exception { + mFutureOnClosedCall.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); + } + } + + /** + * This class represents a created or deleted IpSecTransfrom that is provided by + * ChildSessionCallback + */ + static class IpSecTransformCallRecord { + public final IpSecTransform ipSecTransform; + public final int direction; + + IpSecTransformCallRecord(IpSecTransform ipSecTransform, @PolicyDirection int direction) { + this.ipSecTransform = ipSecTransform; + this.direction = direction; + } + } + + // TODO(b/148689509): Verify IKE Session setup using EAP and digital-signature-based auth + + // TODO(b/148689509): Verify hostname based creation +} diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java index bc2bec665f..f07c710ba9 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java @@ -31,13 +31,15 @@ import java.util.Map; /** Shared parameters and util methods for testing different components of IKE */ abstract class IkeTestBase { - private static final int MIN_PORT = 0; - private static final int MAX_PORT = 65535; + static final int MIN_PORT = 0; + static final int MAX_PORT = 65535; private static final int INBOUND_TS_START_PORT = MIN_PORT; private static final int INBOUND_TS_END_PORT = 65520; private static final int OUTBOUND_TS_START_PORT = 16; private static final int OUTBOUND_TS_END_PORT = MAX_PORT; + static final int IP4_ADDRESS_LEN = 4; + static final int IP6_ADDRESS_LEN = 16; static final int IP4_PREFIX_LEN = 32; static final int IP6_PREFIX_LEN = 64; 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 new file mode 100644 index 0000000000..5a8258d57b --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTunUtils.java @@ -0,0 +1,243 @@ +/* + * 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.ipsec.ike.cts; + +import static android.net.ipsec.ike.cts.PacketUtils.BytePayload; +import static android.net.ipsec.ike.cts.PacketUtils.IP4_HDRLEN; +import static android.net.ipsec.ike.cts.PacketUtils.IP6_HDRLEN; +import static android.net.ipsec.ike.cts.PacketUtils.Ip4Header; +import static android.net.ipsec.ike.cts.PacketUtils.Ip6Header; +import static android.net.ipsec.ike.cts.PacketUtils.IpHeader; +import static android.net.ipsec.ike.cts.PacketUtils.Payload; +import static android.net.ipsec.ike.cts.PacketUtils.UDP_HDRLEN; +import static android.net.ipsec.ike.cts.PacketUtils.UdpHeader; +import static android.system.OsConstants.IPPROTO_UDP; + +import static org.junit.Assert.fail; + +import android.os.ParcelFileDescriptor; + +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.nio.ByteBuffer; +import java.util.Arrays; + +public class IkeTunUtils extends TunUtils { + private static final int PORT_LEN = 2; + + private static final int NON_ESP_MARKER_LEN = 4; + private static final byte[] NON_ESP_MARKER = new byte[NON_ESP_MARKER_LEN]; + + private static final int IKE_HEADER_LEN = 28; + private static final int IKE_INIT_SPI_OFFSET = 0; + private static final int IKE_IS_RESP_BYTE_OFFSET = 19; + private static final int IKE_MSG_ID_OFFSET = 20; + + public IkeTunUtils(ParcelFileDescriptor tunFd) { + super(tunFd); + } + + /** + * Await the expected IKE request and inject an IKE response. + * + * @param respIkePkt IKE response packet without IP/UDP headers or NON ESP MARKER. + */ + public byte[] awaitReqAndInjectResp( + long expectedInitIkeSpi, int expectedMsgId, boolean expectedUseEncap, byte[] respIkePkt) + throws Exception { + byte[] request = + awaitIkePacket( + expectedInitIkeSpi, + expectedMsgId, + false /* expectedResp */, + expectedUseEncap); + + // Build response header by flipping address and port + InetAddress srcAddr = getAddress(request, false /* shouldGetSource */); + InetAddress dstAddr = getAddress(request, true /* shouldGetSource */); + int srcPort = getPort(request, false /* shouldGetSource */); + int dstPort = getPort(request, true /* shouldGetSource */); + + byte[] response = + buildIkePacket(srcAddr, dstAddr, srcPort, dstPort, expectedUseEncap, respIkePkt); + injectPacket(response); + return request; + } + + private byte[] awaitIkePacket( + long expectedInitIkeSpi, + int expectedMsgId, + boolean expectedResp, + boolean expectedUseEncap) + throws Exception { + long endTime = System.currentTimeMillis() + TIMEOUT; + int startIndex = 0; + synchronized (mPackets) { + while (System.currentTimeMillis() < endTime) { + byte[] ikePkt = + getFirstMatchingPacket( + (pkt) -> { + return isIke( + pkt, + expectedInitIkeSpi, + expectedMsgId, + expectedResp, + expectedUseEncap); + }, + startIndex); + if (ikePkt != null) { + return ikePkt; // We've found the packet we're looking for. + } + + startIndex = mPackets.size(); + + // Try to prevent waiting too long. If waitTimeout <= 0, we've already hit timeout + long waitTimeout = endTime - System.currentTimeMillis(); + if (waitTimeout > 0) { + mPackets.wait(waitTimeout); + } + } + + String direction = expectedResp ? "response" : "request"; + fail( + "No such IKE " + + direction + + " found with Initiator SPI " + + expectedInitIkeSpi + + " and message ID " + + expectedMsgId); + } + return null; + } + + private static boolean isIke( + byte[] pkt, + long expectedInitIkeSpi, + int expectedMsgId, + boolean expectedResp, + boolean expectedUseEncap) { + int ipProtocolOffset = 0; + int ikeOffset = 0; + if (isIpv6(pkt)) { + // IPv6 UDP expectedUseEncap not supported by kernels; assume non-expectedUseEncap. + ipProtocolOffset = IP6_PROTO_OFFSET; + ikeOffset = IP6_HDRLEN + UDP_HDRLEN; + } else { + // Use default IPv4 header length (assuming no options) + ipProtocolOffset = IP4_PROTO_OFFSET; + ikeOffset = IP4_HDRLEN + UDP_HDRLEN; + + if (expectedUseEncap) { + if (hasNonEspMarker(pkt)) { + ikeOffset += NON_ESP_MARKER_LEN; + } else { + return false; + } + } + } + + return pkt[ipProtocolOffset] == IPPROTO_UDP + && areSpiAndMsgIdEqual( + pkt, ikeOffset, expectedInitIkeSpi, expectedMsgId, expectedResp); + } + + private static boolean hasNonEspMarker(byte[] pkt) { + ByteBuffer buffer = ByteBuffer.wrap(pkt); + int ikeOffset = IP4_HDRLEN + UDP_HDRLEN; + if (buffer.remaining() < ikeOffset) return false; + + buffer.get(new byte[ikeOffset]); // Skip IP and UDP header + byte[] nonEspMarker = new byte[NON_ESP_MARKER_LEN]; + if (buffer.remaining() < NON_ESP_MARKER_LEN) return false; + + buffer.get(nonEspMarker); + return Arrays.equals(NON_ESP_MARKER, nonEspMarker); + } + + private static boolean areSpiAndMsgIdEqual( + byte[] pkt, + int ikeOffset, + long expectedIkeInitSpi, + int expectedMsgId, + boolean expectedResp) { + if (pkt.length <= ikeOffset + IKE_HEADER_LEN) return false; + + ByteBuffer buffer = ByteBuffer.wrap(pkt); + buffer.get(new byte[ikeOffset]); // Skip IP, UDP header (and NON_ESP_MARKER) + + // Check message ID. + buffer.get(new byte[IKE_MSG_ID_OFFSET]); + int msgId = buffer.getInt(); + return expectedMsgId == msgId; + + // TODO: Check SPI and packet direction + } + + private static InetAddress getAddress(byte[] pkt, boolean shouldGetSource) throws Exception { + int ipLen = isIpv6(pkt) ? IP6_ADDR_LEN : IP4_ADDR_LEN; + int srcIpOffset = isIpv6(pkt) ? IP6_ADDR_OFFSET : IP4_ADDR_OFFSET; + int ipOffset = shouldGetSource ? srcIpOffset : srcIpOffset + ipLen; + + ByteBuffer buffer = ByteBuffer.wrap(pkt); + buffer.get(new byte[ipOffset]); + byte[] ipAddrBytes = new byte[ipLen]; + buffer.get(ipAddrBytes); + return InetAddress.getByAddress(ipAddrBytes); + } + + private static int getPort(byte[] pkt, boolean shouldGetSource) { + ByteBuffer buffer = ByteBuffer.wrap(pkt); + int srcPortOffset = isIpv6(pkt) ? IP6_HDRLEN : IP4_HDRLEN; + int portOffset = shouldGetSource ? srcPortOffset : srcPortOffset + PORT_LEN; + + buffer.get(new byte[portOffset]); + return Short.toUnsignedInt(buffer.getShort()); + } + + private static byte[] buildIkePacket( + InetAddress srcAddr, + InetAddress dstAddr, + int srcPort, + int dstPort, + boolean useEncap, + byte[] ikePacket) + throws Exception { + if (useEncap) { + ByteBuffer buffer = ByteBuffer.allocate(NON_ESP_MARKER_LEN + ikePacket.length); + buffer.put(NON_ESP_MARKER); + buffer.put(ikePacket); + ikePacket = buffer.array(); + } + + UdpHeader udpPkt = new UdpHeader(srcPort, dstPort, new BytePayload(ikePacket)); + IpHeader ipPkt = getIpHeader(udpPkt.getProtocolId(), srcAddr, dstAddr, udpPkt); + return ipPkt.getPacketBytes(); + } + + private static IpHeader getIpHeader( + int protocol, InetAddress src, InetAddress dst, Payload payload) { + if ((src instanceof Inet6Address) != (dst instanceof Inet6Address)) { + throw new IllegalArgumentException("Invalid src/dst address combination"); + } + + if (src instanceof Inet6Address) { + return new Ip6Header(protocol, (Inet6Address) src, (Inet6Address) dst, payload); + } else { + return new Ip4Header(protocol, (Inet4Address) src, (Inet4Address) dst, payload); + } + } +} diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TunUtils.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TunUtils.java index 71450ea9c0..cb1d8269d7 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TunUtils.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TunUtils.java @@ -47,18 +47,18 @@ public class TunUtils { private static final String TAG = TunUtils.class.getSimpleName(); private static final int DATA_BUFFER_LEN = 4096; - private static final int TIMEOUT = 100; + static final int TIMEOUT = 100; - private static final int IP4_PROTO_OFFSET = 9; - private static final int IP6_PROTO_OFFSET = 6; + static final int IP4_PROTO_OFFSET = 9; + static final int IP6_PROTO_OFFSET = 6; - private static final int IP4_ADDR_OFFSET = 12; - private static final int IP4_ADDR_LEN = 4; - private static final int IP6_ADDR_OFFSET = 8; - private static final int IP6_ADDR_LEN = 16; + static final int IP4_ADDR_OFFSET = 12; + static final int IP4_ADDR_LEN = 4; + static final int IP6_ADDR_OFFSET = 8; + static final int IP6_ADDR_LEN = 16; + final List mPackets = new ArrayList<>(); private final ParcelFileDescriptor mTunFd; - private final List mPackets = new ArrayList<>(); private final Thread mReaderThread; public TunUtils(ParcelFileDescriptor tunFd) { @@ -107,7 +107,7 @@ public class TunUtils { return Arrays.copyOf(inBytes, bytesRead); } - private byte[] getFirstMatchingPacket(Predicate verifier, int startIndex) { + byte[] getFirstMatchingPacket(Predicate verifier, int startIndex) { synchronized (mPackets) { for (int i = startIndex; i < mPackets.size(); i++) { byte[] pkt = mPackets.get(i); @@ -198,7 +198,7 @@ public class TunUtils { } } - private static boolean isIpv6(byte[] pkt) { + static boolean isIpv6(byte[] pkt) { // First nibble shows IP version. 0x60 for IPv6 return (pkt[0] & (byte) 0xF0) == (byte) 0x60; } From e4a9287bfee4cf4dc15d5b9dc8a6b0a782a5b9ed Mon Sep 17 00:00:00 2001 From: Dominic Lemire Date: Wed, 15 Apr 2020 19:20:48 -0700 Subject: [PATCH 0945/1109] Fix error message in RestrictBackgroundNetworkTest Fixed the error message when the expected number of broadcasts is exceeded. Bug: 147139427 Test: atest hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java Change-Id: I7e69dca81abdb29a9eb7d110266edbe483e17a01 Merged-In: I7e69dca81abdb29a9eb7d110266edbe483e17a01 --- .../hostside/AbstractRestrictBackgroundNetworkTestCase.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java index 29ba68c4cf..1db0417fc9 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java @@ -30,6 +30,7 @@ import static com.android.cts.net.hostside.NetworkPolicyTestUtils.isDozeModeSupp import static com.android.cts.net.hostside.NetworkPolicyTestUtils.restrictBackgroundValueToString; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -177,7 +178,9 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase { do { attempts++; count = getNumberBroadcastsReceived(receiverName, ACTION_RESTRICT_BACKGROUND_CHANGED); - if (count >= expectedCount) { + assertFalse("Expected count " + expectedCount + " but actual is " + count, + count > expectedCount); + if (count == expectedCount) { break; } Log.d(TAG, "Expecting count " + expectedCount + " but actual is " + count + " after " From 120a7db874068c0cc9c3b3f5a288f3f2093b5c35 Mon Sep 17 00:00:00 2001 From: evitayan Date: Tue, 7 Apr 2020 15:16:08 -0700 Subject: [PATCH 0946/1109] Initial CL for testing IkeSession creation This commit: -Extend TunUtils for processing IKE packets -Add IkeSessionBaseTest containing common functionality for all IkeSession tests -Add end-to-end test for IKEv2 PSK verifying creating IKE SA, creating child SAs and closing sessions -Add basic tests for error scenarios Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: Ie6c18591ffcc883abbf0484d9a59dfda61b33257 Merged-In: Ie6c18591ffcc883abbf0484d9a59dfda61b33257 --- tests/cts/net/ipsec/Android.bp | 1 + .../ipsec/ike/cts/IkeSessionParamsTest.java | 19 +- .../ike/cts/IkeSessionParamsTestBase.java | 85 ---- .../net/ipsec/ike/cts/IkeSessionPskTest.java | 258 ++++++++++++ .../net/ipsec/ike/cts/IkeSessionTestBase.java | 374 ++++++++++++++++++ .../net/ipsec/ike/cts/IkeTestBase.java | 6 +- .../net/ipsec/ike/cts/IkeTunUtils.java | 243 ++++++++++++ .../android/net/ipsec/ike/cts/TunUtils.java | 20 +- 8 files changed, 904 insertions(+), 102 deletions(-) delete mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTestBase.java create mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java create mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java create mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTunUtils.java diff --git a/tests/cts/net/ipsec/Android.bp b/tests/cts/net/ipsec/Android.bp index 1d9128b7fe..124e93c650 100644 --- a/tests/cts/net/ipsec/Android.bp +++ b/tests/cts/net/ipsec/Android.bp @@ -33,6 +33,7 @@ android_test { "androidx.test.ext.junit", "compatibility-device-util-axt", "ctstestrunner-axt", + "net-tests-utils", ], platform_apis: true, diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java index 6fc7cb3634..c767b78120 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTest.java @@ -46,6 +46,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; import com.android.internal.net.ipsec.ike.testutils.CertUtils; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -63,7 +64,7 @@ import java.util.Set; import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) -public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { +public final class IkeSessionParamsTest extends IkeSessionTestBase { private static final int HARD_LIFETIME_SECONDS = (int) TimeUnit.HOURS.toSeconds(20L); private static final int SOFT_LIFETIME_SECONDS = (int) TimeUnit.HOURS.toSeconds(10L); private static final int DPD_DELAY_SECONDS = (int) TimeUnit.MINUTES.toSeconds(10L); @@ -105,6 +106,9 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { @Before public void setUp() throws Exception { + // This address is never used except for setting up the test network + setUpTestNetwork(IPV4_ADDRESS_LOCAL); + mServerCaCert = CertUtils.createCertFromPemFile("server-a-self-signed-ca.pem"); mClientEndCert = CertUtils.createCertFromPemFile("client-a-end-cert.pem"); mClientIntermediateCaCertOne = @@ -114,6 +118,11 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { mClientPrivateKey = CertUtils.createRsaPrivateKeyFromKeyFile("client-a-private-key.key"); } + @After + public void tearDown() throws Exception { + tearDownTestNetwork(); + } + private static EapSessionConfig.Builder createEapOnlySafeMethodsBuilder() { return new EapSessionConfig.Builder() .setEapIdentity(EAP_IDENTITY) @@ -131,7 +140,7 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { */ private IkeSessionParams.Builder createIkeParamsBuilderMinimum() { return new IkeSessionParams.Builder(sContext) - .setNetwork(sTunNetwork) + .setNetwork(mTunNetwork) .setServerHostname(IPV4_ADDRESS_REMOTE.getHostAddress()) .addSaProposal(SA_PROPOSAL) .setLocalIdentification(LOCAL_ID) @@ -145,7 +154,7 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { * @see #createIkeParamsBuilderMinimum */ private void verifyIkeParamsMinimum(IkeSessionParams sessionParams) { - assertEquals(sTunNetwork, sessionParams.getNetwork()); + assertEquals(mTunNetwork, sessionParams.getNetwork()); assertEquals(IPV4_ADDRESS_REMOTE.getHostAddress(), sessionParams.getServerHostname()); assertEquals(Arrays.asList(SA_PROPOSAL), sessionParams.getSaProposals()); assertEquals(LOCAL_ID, sessionParams.getLocalIdentification()); @@ -268,7 +277,7 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { */ private IkeSessionParams.Builder createIkeParamsBuilderMinimumWithoutAuth() { return new IkeSessionParams.Builder(sContext) - .setNetwork(sTunNetwork) + .setNetwork(mTunNetwork) .setServerHostname(IPV4_ADDRESS_REMOTE.getHostAddress()) .addSaProposal(SA_PROPOSAL) .setLocalIdentification(LOCAL_ID) @@ -282,7 +291,7 @@ public final class IkeSessionParamsTest extends IkeSessionParamsTestBase { * @see #createIkeParamsBuilderMinimumWithoutAuth */ private void verifyIkeParamsMinimumWithoutAuth(IkeSessionParams sessionParams) { - assertEquals(sTunNetwork, sessionParams.getNetwork()); + assertEquals(mTunNetwork, sessionParams.getNetwork()); assertEquals(IPV4_ADDRESS_REMOTE.getHostAddress(), sessionParams.getServerHostname()); assertEquals(Arrays.asList(SA_PROPOSAL), sessionParams.getSaProposals()); assertEquals(LOCAL_ID, sessionParams.getLocalIdentification()); diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTestBase.java deleted file mode 100644 index c3e3ba353c..0000000000 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionParamsTestBase.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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.ipsec.ike.cts; - -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.LinkAddress; -import android.net.Network; -import android.net.TestNetworkInterface; -import android.net.TestNetworkManager; -import android.net.ipsec.ike.cts.TestNetworkUtils.TestNetworkCallback; -import android.os.Binder; -import android.os.IBinder; -import android.os.ParcelFileDescriptor; -import android.platform.test.annotations.AppModeFull; - -import androidx.test.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@AppModeFull(reason = "MANAGE_TEST_NETWORKS permission can't be granted to instant apps") -abstract class IkeSessionParamsTestBase extends IkeTestBase { - // Static state to reduce setup/teardown - static ConnectivityManager sCM; - static TestNetworkManager sTNM; - static ParcelFileDescriptor sTunFd; - static TestNetworkCallback sTunNetworkCallback; - static Network sTunNetwork; - - static Context sContext = InstrumentationRegistry.getContext(); - static IBinder sBinder = new Binder(); - - // This method is guaranteed to run in subclasses and will run before subclasses' @BeforeClass - // methods. - @BeforeClass - public static void setUpTestNetworkBeforeClass() throws Exception { - InstrumentationRegistry.getInstrumentation() - .getUiAutomation() - .adoptShellPermissionIdentity(); - sCM = (ConnectivityManager) sContext.getSystemService(Context.CONNECTIVITY_SERVICE); - sTNM = (TestNetworkManager) sContext.getSystemService(Context.TEST_NETWORK_SERVICE); - - TestNetworkInterface testIface = - sTNM.createTunInterface( - new LinkAddress[] {new LinkAddress(IPV4_ADDRESS_LOCAL, IP4_PREFIX_LEN)}); - - sTunFd = testIface.getFileDescriptor(); - sTunNetworkCallback = - TestNetworkUtils.setupAndGetTestNetwork( - sCM, sTNM, testIface.getInterfaceName(), sBinder); - sTunNetwork = sTunNetworkCallback.getNetworkBlocking(); - } - - // This method is guaranteed to run in subclasses and will run after subclasses' @AfterClass - // methods. - @AfterClass - public static void tearDownTestNetworkAfterClass() throws Exception { - sCM.unregisterNetworkCallback(sTunNetworkCallback); - - sTNM.teardownTestNetwork(sTunNetwork); - sTunFd.close(); - - InstrumentationRegistry.getInstrumentation() - .getUiAutomation() - .dropShellPermissionIdentity(); - } -} 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 new file mode 100644 index 0000000000..ed67dd1bd7 --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java @@ -0,0 +1,258 @@ +/* + * 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.ipsec.ike.cts; + +import static android.net.ipsec.ike.IkeSessionConfiguration.EXTENSION_TYPE_FRAGMENTATION; +import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN; +import static android.system.OsConstants.AF_INET; +import static android.system.OsConstants.AF_INET6; + +import static com.android.internal.util.HexDump.hexStringToByteArray; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import android.net.ipsec.ike.ChildSessionConfiguration; +import android.net.ipsec.ike.IkeFqdnIdentification; +import android.net.ipsec.ike.IkeSession; +import android.net.ipsec.ike.IkeSessionConfiguration; +import android.net.ipsec.ike.IkeSessionConnectionInfo; +import android.net.ipsec.ike.IkeSessionParams; +import android.net.ipsec.ike.TunnelModeChildSessionParams; +import android.net.ipsec.ike.exceptions.IkeException; +import android.net.ipsec.ike.exceptions.IkeProtocolException; +import android.platform.test.annotations.AppModeFull; + +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.net.InetAddress; +import java.util.Arrays; + +@RunWith(AndroidJUnit4.class) +@AppModeFull(reason = "MANAGE_TEST_NETWORKS permission can't be granted to instant apps") +public class IkeSessionPskTest extends IkeSessionTestBase { + // Test vectors for success workflow + private static final String SUCCESS_IKE_INIT_RESP = + "46B8ECA1E0D72A18B45427679F9245D421202220000000000000015022000030" + + "0000002C010100040300000C0100000C800E0080030000080300000203000008" + + "0200000200000008040000022800008800020000A7AA3435D088EC1A2B7C2A47" + + "1FA1B85F1066C9B2006E7C353FB5B5FDBC2A88347ED2C6F5B7A265D03AE34039" + + "6AAC0145CFCC93F8BDB219DDFF22A603B8856A5DC59B6FAB7F17C5660CF38670" + + "8794FC72F273ADEB7A4F316519794AED6F8AB61F95DFB360FAF18C6C8CABE471" + + "6E18FE215348C2E582171A57FC41146B16C4AFE429000024A634B61C0E5C90C6" + + "8D8818B0955B125A9B1DF47BBD18775710792E651083105C2900001C00004004" + + "406FA3C5685A16B9B72C7F2EEE9993462C619ABE2900001C00004005AF905A87" + + "0A32222AA284A7070585601208A282F0290000080000402E290000100000402F" + + "00020003000400050000000800004014"; + private static final String SUCCESS_IKE_AUTH_RESP = + "46B8ECA1E0D72A18B45427679F9245D42E20232000000001000000EC240000D0" + + "0D06D37198F3F0962DE8170D66F1A9008267F98CDD956D984BDCED2FC7FAF84A" + + "A6664EF25049B46B93C9ED420488E0C172AA6635BF4011C49792EF2B88FE7190" + + "E8859FEEF51724FD20C46E7B9A9C3DC4708EF7005707A18AB747C903ABCEAC5C" + + "6ECF5A5FC13633DCE3844A920ED10EF202F115DBFBB5D6D2D7AB1F34EB08DE7C" + + "A54DCE0A3A582753345CA2D05A0EFDB9DC61E81B2483B7D13EEE0A815D37252C" + + "23D2F29E9C30658227D2BB0C9E1A481EAA80BC6BE9006BEDC13E925A755A0290" + + "AEC4164D29997F52ED7DCC2E"; + private static final String SUCCESS_CREATE_CHILD_RESP = + "46B8ECA1E0D72A18B45427679F9245D42E20242000000002000000CC210000B0" + + "484565D4AF6546274674A8DE339E9C9584EE2326AB9260F41C4D0B6C5B02D1D" + + "2E8394E3CDE3094895F2ACCABCDCA8E82960E5196E9622BD13745FC8D6A2BED" + + "E561FF5D9975421BC463C959A3CBA3478256B6D278159D99B512DDF56AC1658" + + "63C65A986F395FE8B1476124B91F83FD7865304EB95B22CA4DD9601DA7A2533" + + "ABF4B36EB1B8CD09522F6A600032316C74E562E6756D9D49D945854E2ABDC4C" + + "3AF36305353D60D40B58BE44ABF82"; + private static final String SUCCESS_DELETE_CHILD_RESP = + "46B8ECA1E0D72A18B45427679F9245D42E202520000000030000004C2A000030" + + "0C5CEB882DBCA65CE32F4C53909335F1365C91C555316C5E9D9FB553F7AA916" + + "EF3A1D93460B7FABAF0B4B854"; + private static final String SUCCESS_DELETE_IKE_RESP = + "46B8ECA1E0D72A18B45427679F9245D42E202520000000040000004C00000030" + + "9352D71100777B00ABCC6BD7DBEA697827FFAAA48DF9A54D1D68161939F5DC8" + + "6743A7CEB2BE34AC00095A5B8"; + + private static final long IKE_INIT_SPI = Long.parseLong("46B8ECA1E0D72A18", 16); + + private static final TunnelModeChildSessionParams CHILD_PARAMS = + new TunnelModeChildSessionParams.Builder() + .addSaProposal(SaProposalTest.buildChildSaProposalWithNormalModeCipher()) + .addSaProposal(SaProposalTest.buildChildSaProposalWithCombinedModeCipher()) + .addInternalAddressRequest(AF_INET) + .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) { + return new IkeSession( + sContext, + ikeParams, + CHILD_PARAMS, + mUserCbExecutor, + mIkeSessionCallback, + mFirstChildSessionCallback); + } + + @Test + public void testIkeSessionSetupAndManageChildSas() throws Exception { + // Open IKE Session + IkeSession ikeSession = openIkeSession(createIkeSessionParams(mRemoteAddress)); + int expectedMsgId = 0; + mTunUtils.awaitReqAndInjectResp( + IKE_INIT_SPI, + expectedMsgId++, + false /* expectedUseEncap */, + hexStringToByteArray(SUCCESS_IKE_INIT_RESP)); + + mTunUtils.awaitReqAndInjectResp( + IKE_INIT_SPI, + expectedMsgId++, + true /* expectedUseEncap */, + hexStringToByteArray(SUCCESS_IKE_AUTH_RESP)); + + // Verify opening IKE Session + IkeSessionConfiguration ikeConfig = mIkeSessionCallback.awaitIkeConfig(); + assertNotNull(ikeConfig); + assertEquals(EXPECTED_REMOTE_APP_VERSION_EMPTY, ikeConfig.getRemoteApplicationVersion()); + assertTrue(ikeConfig.getRemoteVendorIds().isEmpty()); + assertTrue(ikeConfig.getPcscfServers().isEmpty()); + assertTrue(ikeConfig.isIkeExtensionEnabled(EXTENSION_TYPE_FRAGMENTATION)); + + IkeSessionConnectionInfo ikeConnectInfo = ikeConfig.getIkeSessionConnectionInfo(); + assertNotNull(ikeConnectInfo); + assertEquals(mLocalAddress, ikeConnectInfo.getLocalAddress()); + assertEquals(mRemoteAddress, ikeConnectInfo.getRemoteAddress()); + assertEquals(mTunNetwork, ikeConnectInfo.getNetwork()); + + // Verify opening first Child Session + ChildSessionConfiguration firstChildConfig = mFirstChildSessionCallback.awaitChildConfig(); + assertNotNull(firstChildConfig); + assertEquals( + Arrays.asList(EXPECTED_INBOUND_TS), firstChildConfig.getInboundTrafficSelectors()); + assertEquals(Arrays.asList(DEFAULT_V4_TS), firstChildConfig.getOutboundTrafficSelectors()); + assertEquals( + Arrays.asList(EXPECTED_INTERNAL_LINK_ADDR), + firstChildConfig.getInternalAddresses()); + assertTrue(firstChildConfig.getInternalSubnets().isEmpty()); + assertTrue(firstChildConfig.getInternalDnsServers().isEmpty()); + assertTrue(firstChildConfig.getInternalDhcpServers().isEmpty()); + + // Open additional Child Session + TestChildSessionCallback additionalChildCb = new TestChildSessionCallback(); + ikeSession.openChildSession(CHILD_PARAMS, additionalChildCb); + mTunUtils.awaitReqAndInjectResp( + IKE_INIT_SPI, + expectedMsgId++, + true /* expectedUseEncap */, + hexStringToByteArray(SUCCESS_CREATE_CHILD_RESP)); + + // Verify opening additional Child Session + ChildSessionConfiguration additionalChildConfig = additionalChildCb.awaitChildConfig(); + assertNotNull(additionalChildConfig); + assertEquals( + 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()); + + // Close additional Child Session + ikeSession.closeChildSession(additionalChildCb); + mTunUtils.awaitReqAndInjectResp( + IKE_INIT_SPI, + expectedMsgId++, + true /* expectedUseEncap */, + hexStringToByteArray(SUCCESS_DELETE_CHILD_RESP)); + + additionalChildCb.awaitOnClosed(); + + // Close IKE Session + ikeSession.close(); + mTunUtils.awaitReqAndInjectResp( + IKE_INIT_SPI, + expectedMsgId++, + true /* expectedUseEncap */, + hexStringToByteArray(SUCCESS_DELETE_IKE_RESP)); + + mFirstChildSessionCallback.awaitOnClosed(); + mIkeSessionCallback.awaitOnClosed(); + + // TODO: verify IpSecTransform pair is created and deleted + } + + @Test + public void testIkeSessionKill() throws Exception { + // Open IKE Session + IkeSession ikeSession = openIkeSession(createIkeSessionParams(mRemoteAddress)); + int expectedMsgId = 0; + mTunUtils.awaitReqAndInjectResp( + IKE_INIT_SPI, + expectedMsgId++, + false /* expectedUseEncap */, + hexStringToByteArray(SUCCESS_IKE_INIT_RESP)); + + mTunUtils.awaitReqAndInjectResp( + IKE_INIT_SPI, + expectedMsgId++, + true /* expectedUseEncap */, + hexStringToByteArray(SUCCESS_IKE_AUTH_RESP)); + + ikeSession.kill(); + + mFirstChildSessionCallback.awaitOnClosed(); + mIkeSessionCallback.awaitOnClosed(); + } + + @Test + public void testIkeInitFail() throws Exception { + String ikeInitFailRespHex = + "46B8ECA1E0D72A180000000000000000292022200000000000000024000000080000000E"; + + // Open IKE Session + IkeSession ikeSession = openIkeSession(createIkeSessionParams(mRemoteAddress)); + int expectedMsgId = 0; + mTunUtils.awaitReqAndInjectResp( + IKE_INIT_SPI, + expectedMsgId++, + false /* expectedUseEncap */, + hexStringToByteArray(ikeInitFailRespHex)); + + IkeException exception = mIkeSessionCallback.awaitOnClosedException(); + assertNotNull(exception); + assertTrue(exception instanceof IkeProtocolException); + IkeProtocolException protocolException = (IkeProtocolException) exception; + assertEquals(ERROR_TYPE_NO_PROPOSAL_CHOSEN, protocolException.getErrorType()); + assertArrayEquals(EXPECTED_PROTOCOL_ERROR_DATA_NONE, protocolException.getErrorData()); + } + + // TODO(b/148689509): Verify rekey process and handling IKE_AUTH failure +} 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 new file mode 100644 index 0000000000..deba8fd985 --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java @@ -0,0 +1,374 @@ +/* + * 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 + * + * 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.ipsec.ike.cts; + +import static android.app.AppOpsManager.OP_MANAGE_IPSEC_TUNNELS; + +import android.annotation.NonNull; +import android.app.AppOpsManager; +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.InetAddresses; +import android.net.IpSecTransform; +import android.net.LinkAddress; +import android.net.Network; +import android.net.TestNetworkInterface; +import android.net.TestNetworkManager; +import android.net.annotations.PolicyDirection; +import android.net.ipsec.ike.ChildSessionCallback; +import android.net.ipsec.ike.ChildSessionConfiguration; +import android.net.ipsec.ike.IkeSessionCallback; +import android.net.ipsec.ike.IkeSessionConfiguration; +import android.net.ipsec.ike.IkeTrafficSelector; +import android.net.ipsec.ike.cts.TestNetworkUtils.TestNetworkCallback; +import android.net.ipsec.ike.exceptions.IkeException; +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; + +import com.android.compatibility.common.util.SystemUtil; +import com.android.testutils.ArrayTrackRecord; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.runner.RunWith; + +import java.net.Inet4Address; +import java.net.InetAddress; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +/** + * Package private base class for testing IkeSessionParams and IKE exchanges. + * + *

    Subclasses MUST explicitly call #setUpTestNetwork and #tearDownTestNetwork to be able to use + * the test network + */ +@RunWith(AndroidJUnit4.class) +@AppModeFull(reason = "MANAGE_TEST_NETWORKS permission can't be granted to instant apps") +abstract class IkeSessionTestBase extends IkeTestBase { + // Package-wide common expected results that will be shared by all IKE/Child SA creation tests + static final String EXPECTED_REMOTE_APP_VERSION_EMPTY = ""; + static final byte[] EXPECTED_PROTOCOL_ERROR_DATA_NONE = new byte[0]; + static final InetAddress EXPECTED_INTERNAL_ADDR = + InetAddresses.parseNumericAddress("198.51.100.10"); + static final LinkAddress EXPECTED_INTERNAL_LINK_ADDR = + new LinkAddress(EXPECTED_INTERNAL_ADDR, IP4_PREFIX_LEN); + static final IkeTrafficSelector EXPECTED_INBOUND_TS = + new IkeTrafficSelector( + MIN_PORT, MAX_PORT, EXPECTED_INTERNAL_ADDR, EXPECTED_INTERNAL_ADDR); + + // Static state to reduce setup/teardown + static Context sContext = InstrumentationRegistry.getContext(); + static ConnectivityManager sCM = + (ConnectivityManager) sContext.getSystemService(Context.CONNECTIVITY_SERVICE); + static TestNetworkManager sTNM; + + private static final int TIMEOUT_MS = 500; + + // Constants to be used for providing different IP addresses for each tests + private static final byte IP_ADDR_LAST_BYTE_MAX = (byte) 100; + private static final byte[] INITIAL_AVAILABLE_IP4_ADDR_LOCAL = + InetAddresses.parseNumericAddress("192.0.2.1").getAddress(); + private static final byte[] INITIAL_AVAILABLE_IP4_ADDR_REMOTE = + InetAddresses.parseNumericAddress("198.51.100.1").getAddress(); + private static final byte[] NEXT_AVAILABLE_IP4_ADDR_LOCAL = INITIAL_AVAILABLE_IP4_ADDR_LOCAL; + private static final byte[] NEXT_AVAILABLE_IP4_ADDR_REMOTE = INITIAL_AVAILABLE_IP4_ADDR_REMOTE; + + ParcelFileDescriptor mTunFd; + TestNetworkCallback mTunNetworkCallback; + Network mTunNetwork; + IkeTunUtils mTunUtils; + + InetAddress mLocalAddress; + InetAddress mRemoteAddress; + + Executor mUserCbExecutor; + TestIkeSessionCallback mIkeSessionCallback; + TestChildSessionCallback mFirstChildSessionCallback; + + // This method is guaranteed to run in subclasses and will run before subclasses' @BeforeClass + // methods. + @BeforeClass + public static void setUpPermissionBeforeClass() throws Exception { + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .adoptShellPermissionIdentity(); + sTNM = (TestNetworkManager) sContext.getSystemService(Context.TEST_NETWORK_SERVICE); + + // 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 + // right appop permissions. + setAppOp(OP_MANAGE_IPSEC_TUNNELS, true); + } + + // This method is guaranteed to run in subclasses and will run after subclasses' @AfterClass + // methods. + @AfterClass + public static void tearDownPermissionAfterClass() throws Exception { + setAppOp(OP_MANAGE_IPSEC_TUNNELS, false); + + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .dropShellPermissionIdentity(); + } + + @Before + public void setUp() throws Exception { + mLocalAddress = getNextAvailableIpv4AddressLocal(); + mRemoteAddress = getNextAvailableIpv4AddressRemote(); + setUpTestNetwork(mLocalAddress); + + mUserCbExecutor = Executors.newSingleThreadExecutor(); + mIkeSessionCallback = new TestIkeSessionCallback(); + mFirstChildSessionCallback = new TestChildSessionCallback(); + } + + @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 { + int prefixLen = localAddr instanceof Inet4Address ? IP4_PREFIX_LEN : IP4_PREFIX_LEN; + + TestNetworkInterface testIface = + sTNM.createTunInterface(new LinkAddress[] {new LinkAddress(localAddr, prefixLen)}); + + mTunFd = testIface.getFileDescriptor(); + mTunNetworkCallback = + TestNetworkUtils.setupAndGetTestNetwork( + sCM, sTNM, testIface.getInterfaceName(), new Binder()); + mTunNetwork = mTunNetworkCallback.getNetworkBlocking(); + mTunUtils = new IkeTunUtils(mTunFd); + } + + void tearDownTestNetwork() throws Exception { + sCM.unregisterNetworkCallback(mTunNetworkCallback); + + sTNM.teardownTestNetwork(mTunNetwork); + mTunFd.close(); + } + + private static void setAppOp(int appop, boolean allow) { + String opName = AppOpsManager.opToName(appop); + for (String pkg : new String[] {"com.android.shell", sContext.getPackageName()}) { + String cmd = + String.format( + "appops set %s %s %s", + pkg, // Package name + opName, // Appop + (allow ? "allow" : "deny")); // Action + Log.d("IKE", "CTS setAppOp cmd " + cmd); + + String result = SystemUtil.runShellCommand(cmd); + } + } + + Inet4Address getNextAvailableIpv4AddressLocal() throws Exception { + return (Inet4Address) + getNextAvailableAddress( + NEXT_AVAILABLE_IP4_ADDR_LOCAL, + INITIAL_AVAILABLE_IP4_ADDR_LOCAL, + false /* isIp6 */); + } + + Inet4Address getNextAvailableIpv4AddressRemote() throws Exception { + return (Inet4Address) + getNextAvailableAddress( + NEXT_AVAILABLE_IP4_ADDR_REMOTE, + INITIAL_AVAILABLE_IP4_ADDR_REMOTE, + false /* isIp6 */); + } + + InetAddress getNextAvailableAddress( + byte[] nextAddressBytes, byte[] initialAddressBytes, boolean isIp6) throws Exception { + int addressLen = isIp6 ? IP6_ADDRESS_LEN : IP4_ADDRESS_LEN; + + synchronized (nextAddressBytes) { + if (nextAddressBytes[addressLen - 1] == IP_ADDR_LAST_BYTE_MAX) { + resetNextAvailableAddress(nextAddressBytes, initialAddressBytes); + } + + InetAddress address = InetAddress.getByAddress(nextAddressBytes); + nextAddressBytes[addressLen - 1]++; + return address; + } + } + + private void resetNextAvailableAddress(byte[] nextAddressBytes, byte[] initialAddressBytes) { + synchronized (nextAddressBytes) { + System.arraycopy( + nextAddressBytes, 0, initialAddressBytes, 0, initialAddressBytes.length); + } + } + + static class TestIkeSessionCallback implements IkeSessionCallback { + private CompletableFuture mFutureIkeConfig = + new CompletableFuture<>(); + private CompletableFuture mFutureOnClosedCall = new CompletableFuture<>(); + private CompletableFuture mFutureOnClosedException = + new CompletableFuture<>(); + + private int mOnErrorExceptionsCount = 0; + private ArrayTrackRecord mOnErrorExceptionsTrackRecord = + new ArrayTrackRecord<>(); + + @Override + public void onOpened(@NonNull IkeSessionConfiguration sessionConfiguration) { + mFutureIkeConfig.complete(sessionConfiguration); + } + + @Override + public void onClosed() { + mFutureOnClosedCall.complete(true /* unused */); + } + + @Override + public void onClosedExceptionally(@NonNull IkeException exception) { + mFutureOnClosedException.complete(exception); + } + + @Override + public void onError(@NonNull IkeProtocolException exception) { + mOnErrorExceptionsTrackRecord.add(exception); + } + + public IkeSessionConfiguration awaitIkeConfig() throws Exception { + return mFutureIkeConfig.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); + } + + public IkeException awaitOnClosedException() throws Exception { + return mFutureOnClosedException.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); + } + + public IkeProtocolException awaitNextOnErrorException() { + return mOnErrorExceptionsTrackRecord.poll( + (long) TIMEOUT_MS, + mOnErrorExceptionsCount++, + (transform) -> { + return true; + }); + } + + public void awaitOnClosed() throws Exception { + mFutureOnClosedCall.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); + } + } + + static class TestChildSessionCallback implements ChildSessionCallback { + private CompletableFuture mFutureChildConfig = + new CompletableFuture<>(); + private CompletableFuture mFutureOnClosedCall = new CompletableFuture<>(); + private CompletableFuture mFutureOnClosedException = + new CompletableFuture<>(); + + private int mCreatedIpSecTransformCount = 0; + private int mDeletedIpSecTransformCount = 0; + private ArrayTrackRecord mCreatedIpSecTransformsTrackRecord = + new ArrayTrackRecord<>(); + private ArrayTrackRecord mDeletedIpSecTransformsTrackRecord = + new ArrayTrackRecord<>(); + + @Override + public void onOpened(@NonNull ChildSessionConfiguration sessionConfiguration) { + mFutureChildConfig.complete(sessionConfiguration); + } + + @Override + public void onClosed() { + mFutureOnClosedCall.complete(true /* unused */); + } + + @Override + public void onClosedExceptionally(@NonNull IkeException exception) { + mFutureOnClosedException.complete(exception); + } + + @Override + public void onIpSecTransformCreated(@NonNull IpSecTransform ipSecTransform, int direction) { + mCreatedIpSecTransformsTrackRecord.add( + new IpSecTransformCallRecord(ipSecTransform, direction)); + } + + @Override + public void onIpSecTransformDeleted(@NonNull IpSecTransform ipSecTransform, int direction) { + mDeletedIpSecTransformsTrackRecord.add( + new IpSecTransformCallRecord(ipSecTransform, direction)); + } + + public ChildSessionConfiguration awaitChildConfig() throws Exception { + return mFutureChildConfig.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); + } + + public IkeException awaitOnClosedException() throws Exception { + return mFutureOnClosedException.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); + } + + public IpSecTransformCallRecord awaitNextCreatedIpSecTransform() { + return mCreatedIpSecTransformsTrackRecord.poll( + (long) TIMEOUT_MS, + mCreatedIpSecTransformCount++, + (transform) -> { + return true; + }); + } + + public IpSecTransformCallRecord awaitNextDeletedIpSecTransform() { + return mDeletedIpSecTransformsTrackRecord.poll( + (long) TIMEOUT_MS, + mDeletedIpSecTransformCount++, + (transform) -> { + return true; + }); + } + + public void awaitOnClosed() throws Exception { + mFutureOnClosedCall.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); + } + } + + /** + * This class represents a created or deleted IpSecTransfrom that is provided by + * ChildSessionCallback + */ + static class IpSecTransformCallRecord { + public final IpSecTransform ipSecTransform; + public final int direction; + + IpSecTransformCallRecord(IpSecTransform ipSecTransform, @PolicyDirection int direction) { + this.ipSecTransform = ipSecTransform; + this.direction = direction; + } + } + + // TODO(b/148689509): Verify IKE Session setup using EAP and digital-signature-based auth + + // TODO(b/148689509): Verify hostname based creation +} diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java index bc2bec665f..f07c710ba9 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java @@ -31,13 +31,15 @@ import java.util.Map; /** Shared parameters and util methods for testing different components of IKE */ abstract class IkeTestBase { - private static final int MIN_PORT = 0; - private static final int MAX_PORT = 65535; + static final int MIN_PORT = 0; + static final int MAX_PORT = 65535; private static final int INBOUND_TS_START_PORT = MIN_PORT; private static final int INBOUND_TS_END_PORT = 65520; private static final int OUTBOUND_TS_START_PORT = 16; private static final int OUTBOUND_TS_END_PORT = MAX_PORT; + static final int IP4_ADDRESS_LEN = 4; + static final int IP6_ADDRESS_LEN = 16; static final int IP4_PREFIX_LEN = 32; static final int IP6_PREFIX_LEN = 64; 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 new file mode 100644 index 0000000000..5a8258d57b --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTunUtils.java @@ -0,0 +1,243 @@ +/* + * 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.ipsec.ike.cts; + +import static android.net.ipsec.ike.cts.PacketUtils.BytePayload; +import static android.net.ipsec.ike.cts.PacketUtils.IP4_HDRLEN; +import static android.net.ipsec.ike.cts.PacketUtils.IP6_HDRLEN; +import static android.net.ipsec.ike.cts.PacketUtils.Ip4Header; +import static android.net.ipsec.ike.cts.PacketUtils.Ip6Header; +import static android.net.ipsec.ike.cts.PacketUtils.IpHeader; +import static android.net.ipsec.ike.cts.PacketUtils.Payload; +import static android.net.ipsec.ike.cts.PacketUtils.UDP_HDRLEN; +import static android.net.ipsec.ike.cts.PacketUtils.UdpHeader; +import static android.system.OsConstants.IPPROTO_UDP; + +import static org.junit.Assert.fail; + +import android.os.ParcelFileDescriptor; + +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.nio.ByteBuffer; +import java.util.Arrays; + +public class IkeTunUtils extends TunUtils { + private static final int PORT_LEN = 2; + + private static final int NON_ESP_MARKER_LEN = 4; + private static final byte[] NON_ESP_MARKER = new byte[NON_ESP_MARKER_LEN]; + + private static final int IKE_HEADER_LEN = 28; + private static final int IKE_INIT_SPI_OFFSET = 0; + private static final int IKE_IS_RESP_BYTE_OFFSET = 19; + private static final int IKE_MSG_ID_OFFSET = 20; + + public IkeTunUtils(ParcelFileDescriptor tunFd) { + super(tunFd); + } + + /** + * Await the expected IKE request and inject an IKE response. + * + * @param respIkePkt IKE response packet without IP/UDP headers or NON ESP MARKER. + */ + public byte[] awaitReqAndInjectResp( + long expectedInitIkeSpi, int expectedMsgId, boolean expectedUseEncap, byte[] respIkePkt) + throws Exception { + byte[] request = + awaitIkePacket( + expectedInitIkeSpi, + expectedMsgId, + false /* expectedResp */, + expectedUseEncap); + + // Build response header by flipping address and port + InetAddress srcAddr = getAddress(request, false /* shouldGetSource */); + InetAddress dstAddr = getAddress(request, true /* shouldGetSource */); + int srcPort = getPort(request, false /* shouldGetSource */); + int dstPort = getPort(request, true /* shouldGetSource */); + + byte[] response = + buildIkePacket(srcAddr, dstAddr, srcPort, dstPort, expectedUseEncap, respIkePkt); + injectPacket(response); + return request; + } + + private byte[] awaitIkePacket( + long expectedInitIkeSpi, + int expectedMsgId, + boolean expectedResp, + boolean expectedUseEncap) + throws Exception { + long endTime = System.currentTimeMillis() + TIMEOUT; + int startIndex = 0; + synchronized (mPackets) { + while (System.currentTimeMillis() < endTime) { + byte[] ikePkt = + getFirstMatchingPacket( + (pkt) -> { + return isIke( + pkt, + expectedInitIkeSpi, + expectedMsgId, + expectedResp, + expectedUseEncap); + }, + startIndex); + if (ikePkt != null) { + return ikePkt; // We've found the packet we're looking for. + } + + startIndex = mPackets.size(); + + // Try to prevent waiting too long. If waitTimeout <= 0, we've already hit timeout + long waitTimeout = endTime - System.currentTimeMillis(); + if (waitTimeout > 0) { + mPackets.wait(waitTimeout); + } + } + + String direction = expectedResp ? "response" : "request"; + fail( + "No such IKE " + + direction + + " found with Initiator SPI " + + expectedInitIkeSpi + + " and message ID " + + expectedMsgId); + } + return null; + } + + private static boolean isIke( + byte[] pkt, + long expectedInitIkeSpi, + int expectedMsgId, + boolean expectedResp, + boolean expectedUseEncap) { + int ipProtocolOffset = 0; + int ikeOffset = 0; + if (isIpv6(pkt)) { + // IPv6 UDP expectedUseEncap not supported by kernels; assume non-expectedUseEncap. + ipProtocolOffset = IP6_PROTO_OFFSET; + ikeOffset = IP6_HDRLEN + UDP_HDRLEN; + } else { + // Use default IPv4 header length (assuming no options) + ipProtocolOffset = IP4_PROTO_OFFSET; + ikeOffset = IP4_HDRLEN + UDP_HDRLEN; + + if (expectedUseEncap) { + if (hasNonEspMarker(pkt)) { + ikeOffset += NON_ESP_MARKER_LEN; + } else { + return false; + } + } + } + + return pkt[ipProtocolOffset] == IPPROTO_UDP + && areSpiAndMsgIdEqual( + pkt, ikeOffset, expectedInitIkeSpi, expectedMsgId, expectedResp); + } + + private static boolean hasNonEspMarker(byte[] pkt) { + ByteBuffer buffer = ByteBuffer.wrap(pkt); + int ikeOffset = IP4_HDRLEN + UDP_HDRLEN; + if (buffer.remaining() < ikeOffset) return false; + + buffer.get(new byte[ikeOffset]); // Skip IP and UDP header + byte[] nonEspMarker = new byte[NON_ESP_MARKER_LEN]; + if (buffer.remaining() < NON_ESP_MARKER_LEN) return false; + + buffer.get(nonEspMarker); + return Arrays.equals(NON_ESP_MARKER, nonEspMarker); + } + + private static boolean areSpiAndMsgIdEqual( + byte[] pkt, + int ikeOffset, + long expectedIkeInitSpi, + int expectedMsgId, + boolean expectedResp) { + if (pkt.length <= ikeOffset + IKE_HEADER_LEN) return false; + + ByteBuffer buffer = ByteBuffer.wrap(pkt); + buffer.get(new byte[ikeOffset]); // Skip IP, UDP header (and NON_ESP_MARKER) + + // Check message ID. + buffer.get(new byte[IKE_MSG_ID_OFFSET]); + int msgId = buffer.getInt(); + return expectedMsgId == msgId; + + // TODO: Check SPI and packet direction + } + + private static InetAddress getAddress(byte[] pkt, boolean shouldGetSource) throws Exception { + int ipLen = isIpv6(pkt) ? IP6_ADDR_LEN : IP4_ADDR_LEN; + int srcIpOffset = isIpv6(pkt) ? IP6_ADDR_OFFSET : IP4_ADDR_OFFSET; + int ipOffset = shouldGetSource ? srcIpOffset : srcIpOffset + ipLen; + + ByteBuffer buffer = ByteBuffer.wrap(pkt); + buffer.get(new byte[ipOffset]); + byte[] ipAddrBytes = new byte[ipLen]; + buffer.get(ipAddrBytes); + return InetAddress.getByAddress(ipAddrBytes); + } + + private static int getPort(byte[] pkt, boolean shouldGetSource) { + ByteBuffer buffer = ByteBuffer.wrap(pkt); + int srcPortOffset = isIpv6(pkt) ? IP6_HDRLEN : IP4_HDRLEN; + int portOffset = shouldGetSource ? srcPortOffset : srcPortOffset + PORT_LEN; + + buffer.get(new byte[portOffset]); + return Short.toUnsignedInt(buffer.getShort()); + } + + private static byte[] buildIkePacket( + InetAddress srcAddr, + InetAddress dstAddr, + int srcPort, + int dstPort, + boolean useEncap, + byte[] ikePacket) + throws Exception { + if (useEncap) { + ByteBuffer buffer = ByteBuffer.allocate(NON_ESP_MARKER_LEN + ikePacket.length); + buffer.put(NON_ESP_MARKER); + buffer.put(ikePacket); + ikePacket = buffer.array(); + } + + UdpHeader udpPkt = new UdpHeader(srcPort, dstPort, new BytePayload(ikePacket)); + IpHeader ipPkt = getIpHeader(udpPkt.getProtocolId(), srcAddr, dstAddr, udpPkt); + return ipPkt.getPacketBytes(); + } + + private static IpHeader getIpHeader( + int protocol, InetAddress src, InetAddress dst, Payload payload) { + if ((src instanceof Inet6Address) != (dst instanceof Inet6Address)) { + throw new IllegalArgumentException("Invalid src/dst address combination"); + } + + if (src instanceof Inet6Address) { + return new Ip6Header(protocol, (Inet6Address) src, (Inet6Address) dst, payload); + } else { + return new Ip4Header(protocol, (Inet4Address) src, (Inet4Address) dst, payload); + } + } +} diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TunUtils.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TunUtils.java index 71450ea9c0..cb1d8269d7 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TunUtils.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/TunUtils.java @@ -47,18 +47,18 @@ public class TunUtils { private static final String TAG = TunUtils.class.getSimpleName(); private static final int DATA_BUFFER_LEN = 4096; - private static final int TIMEOUT = 100; + static final int TIMEOUT = 100; - private static final int IP4_PROTO_OFFSET = 9; - private static final int IP6_PROTO_OFFSET = 6; + static final int IP4_PROTO_OFFSET = 9; + static final int IP6_PROTO_OFFSET = 6; - private static final int IP4_ADDR_OFFSET = 12; - private static final int IP4_ADDR_LEN = 4; - private static final int IP6_ADDR_OFFSET = 8; - private static final int IP6_ADDR_LEN = 16; + static final int IP4_ADDR_OFFSET = 12; + static final int IP4_ADDR_LEN = 4; + static final int IP6_ADDR_OFFSET = 8; + static final int IP6_ADDR_LEN = 16; + final List mPackets = new ArrayList<>(); private final ParcelFileDescriptor mTunFd; - private final List mPackets = new ArrayList<>(); private final Thread mReaderThread; public TunUtils(ParcelFileDescriptor tunFd) { @@ -107,7 +107,7 @@ public class TunUtils { return Arrays.copyOf(inBytes, bytesRead); } - private byte[] getFirstMatchingPacket(Predicate verifier, int startIndex) { + byte[] getFirstMatchingPacket(Predicate verifier, int startIndex) { synchronized (mPackets) { for (int i = startIndex; i < mPackets.size(); i++) { byte[] pkt = mPackets.get(i); @@ -198,7 +198,7 @@ public class TunUtils { } } - private static boolean isIpv6(byte[] pkt) { + static boolean isIpv6(byte[] pkt) { // First nibble shows IP version. 0x60 for IPv6 return (pkt[0] & (byte) 0xF0) == (byte) 0x60; } From efb185744313b3baf4b579a9eb6f8640cd603c78 Mon Sep 17 00:00:00 2001 From: Kweku Adams Date: Mon, 4 May 2020 13:34:29 -0700 Subject: [PATCH 0947/1109] Test that idle apps get network when device charges. This is a partial revert of the change that removed the parole (Icd7b6eff8777f9b53a10eca521b73988f58f2d84). Bug: 151802309 Test: atest --rerun-until-failure 10 com.android.cts.net.HostsideRestrictBackgroundNetworkTests Change-Id: I65f5ff20cdd342905e1afd1f4897017aa60682d3 --- .../net/hostside/AbstractAppIdleTestCase.java | 6 +++--- .../cts/net/NetworkPolicyTestsPreparer.java | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java index 51bdf8e502..5fe4573847 100644 --- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java +++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java @@ -50,7 +50,7 @@ abstract class AbstractAppIdleTestCase extends AbstractRestrictBackgroundNetwork public final void tearDown() throws Exception { super.tearDown(); - turnBatteryOff(); + executeSilentShellCommand("cmd battery reset"); setAppIdle(false); } @@ -131,11 +131,11 @@ abstract class AbstractAppIdleTestCase extends AbstractRestrictBackgroundNetwork @RequiredProperties({BATTERY_SAVER_MODE}) @Test public void testAppIdleNetworkAccess_whenCharging() throws Exception { - // Check that idle app doesn't get network when charging + // Check that app is paroled when charging setAppIdle(true); assertBackgroundNetworkAccess(false); turnBatteryOff(); - assertBackgroundNetworkAccess(false); + assertBackgroundNetworkAccess(true); turnBatteryOn(); assertBackgroundNetworkAccess(false); diff --git a/tests/cts/hostside/src/com/android/cts/net/NetworkPolicyTestsPreparer.java b/tests/cts/hostside/src/com/android/cts/net/NetworkPolicyTestsPreparer.java index dfce7da467..b0facec119 100644 --- a/tests/cts/hostside/src/com/android/cts/net/NetworkPolicyTestsPreparer.java +++ b/tests/cts/hostside/src/com/android/cts/net/NetworkPolicyTestsPreparer.java @@ -24,6 +24,9 @@ import com.android.tradefed.targetprep.ITargetPreparer; public class NetworkPolicyTestsPreparer implements ITargetPreparer { private ITestDevice mDevice; private String mOriginalAppStandbyEnabled; + private String mOriginalBatteryStatsConstants; + private final static String KEY_STABLE_CHARGING_DELAY_MS = "battery_charged_delay_ms"; + private final static int DESIRED_STABLE_CHARGING_DELAY_MS = 0; @Override public void setUp(TestInformation testInformation) throws DeviceNotAvailableException { @@ -31,12 +34,18 @@ public class NetworkPolicyTestsPreparer implements ITargetPreparer { mOriginalAppStandbyEnabled = getAppStandbyEnabled(); setAppStandbyEnabled("1"); LogUtil.CLog.d("Original app_standby_enabled: " + mOriginalAppStandbyEnabled); + + mOriginalBatteryStatsConstants = getBatteryStatsConstants(); + setBatteryStatsConstants( + KEY_STABLE_CHARGING_DELAY_MS + "=" + DESIRED_STABLE_CHARGING_DELAY_MS); + LogUtil.CLog.d("Original battery_saver_constants: " + mOriginalBatteryStatsConstants); } @Override public void tearDown(TestInformation testInformation, Throwable e) throws DeviceNotAvailableException { setAppStandbyEnabled(mOriginalAppStandbyEnabled); + setBatteryStatsConstants(mOriginalBatteryStatsConstants); } private void setAppStandbyEnabled(String appStandbyEnabled) throws DeviceNotAvailableException { @@ -51,6 +60,15 @@ public class NetworkPolicyTestsPreparer implements ITargetPreparer { return executeCmd("settings get global app_standby_enabled").trim(); } + private void setBatteryStatsConstants(String batteryStatsConstants) + throws DeviceNotAvailableException { + executeCmd("settings put global battery_stats_constants \"" + batteryStatsConstants + "\""); + } + + private String getBatteryStatsConstants() throws DeviceNotAvailableException { + return executeCmd("settings get global battery_stats_constants"); + } + private String executeCmd(String cmd) throws DeviceNotAvailableException { final String output = mDevice.executeShellCommand(cmd).trim(); LogUtil.CLog.d("Output for '%s': %s", cmd, output); From f941ae9c03aec4566785434d08d6e37c376f41b3 Mon Sep 17 00:00:00 2001 From: markchien Date: Wed, 6 May 2020 14:55:29 +0800 Subject: [PATCH 0948/1109] Tag CtsTetheringTest for sim card required Bug: 155598732 Test: atest CtsTetheringTest Change-Id: I79f841682049707d7cc26bf1ecc3e5affc86d196 --- tests/cts/tethering/AndroidTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/cts/tethering/AndroidTest.xml b/tests/cts/tethering/AndroidTest.xml index 25051ba55c..d0a2bce811 100644 --- a/tests/cts/tethering/AndroidTest.xml +++ b/tests/cts/tethering/AndroidTest.xml @@ -16,6 +16,7 @@