[automerger] Merge "Fix expected reverse lookup of Google DNS IP addresses" into nougat-cts-dev am: 3b416dd354 am: d4831efbe0 am: 88a48fcbfe
Change-Id: I100af07ea8c391545d48b6b8888696a3622b54ec
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 fb773cb..831b387 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;
/**
@@ -129,4 +130,42 @@
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);
+ // Use setBatterySaverMode API to leave power-save mode instead of plugging in charger
+ setBatterySaverMode(false);
+ turnBatteryOn();
+ assertBackgroundNetworkAccess(true);
+
+ // And when no longer charging, it still has network access, since it's not idle
+ 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/AbstractBatterySaverModeTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java
index ed738a6..b5637be 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
@@ -84,16 +84,24 @@
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 bd93232..c01736f 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.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;
@@ -64,6 +65,8 @@
"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";
@@ -97,6 +100,8 @@
protected WifiManager mWfm;
protected int mUid;
private String mMeteredWifi;
+ private boolean mHasWatch;
+ private String mDeviceIdleConstantsSetting;
private boolean mSupported;
@Override
@@ -109,6 +114,13 @@
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";
+ }
mSupported = setUpActiveNetworkMeteringState();
Log.i(TAG, "Apps status on " + getName() + ":\n"
@@ -248,7 +260,7 @@
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);
}
@@ -764,14 +776,14 @@
}
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 {
@@ -823,6 +835,17 @@
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/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java
index ac35bd4..9e4b0c1 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
@@ -102,16 +102,24 @@
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();
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 799fe50..80f99b6 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.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 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 12fe625..075fce6 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
@@ -476,7 +476,11 @@
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(
@@ -506,7 +510,9 @@
private void assertSocketStillOpen(FileDescriptor fd, String host) throws Exception {
try {
+ assertTrue(fd.valid());
sendRequest(fd, host);
+ assertTrue(fd.valid());
} finally {
Os.close(fd);
}
@@ -514,10 +520,12 @@
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);
}
diff --git a/tests/cts/hostside/app2/AndroidManifest.xml b/tests/cts/hostside/app2/AndroidManifest.xml
index 1fa49ba..adf0045 100644
--- a/tests/cts/hostside/app2/AndroidManifest.xml
+++ b/tests/cts/hostside/app2/AndroidManifest.xml
@@ -46,6 +46,7 @@
<action android:name="com.android.cts.net.hostside.app2.action.GET_RESTRICT_BACKGROUND_STATUS" />
<action android:name="com.android.cts.net.hostside.app2.action.CHECK_NETWORK" />
<action android:name="com.android.cts.net.hostside.app2.action.SEND_NOTIFICATION" />
+ <action android:name="com.android.cts.net.hostside.app2.action.SHOW_TOAST" />
</intent-filter>
</receiver>
</application>
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 8806e3b..e07c0f5 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 @@
"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 6d01b15..733c3aa 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_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.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 @@
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 @@
((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 7d5f817..faf75d9 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,22 @@
"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");
+ }
+
+ 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. *
********************/
diff --git a/tests/cts/net/src/android/net/cts/LocalSocketTest.java b/tests/cts/net/src/android/net/cts/LocalSocketTest.java
index 77f0a44..0ff4a30 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.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 @@
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<Result> 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<Result> 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 @@
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<Result> callable)
+ throws Exception {
+ ExecutorService service = Executors.newSingleThreadScheduledExecutor();
+ Future<Result> 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();
+ }
+ }
}