From 4a0758045c63c50a34f90d3eccd69133b03697da Mon Sep 17 00:00:00 2001 From: Dan Willemsen Date: Mon, 19 Sep 2016 21:27:59 -0700 Subject: [PATCH] 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();