Added error storing in the forwarding runnable. Added tests

Signed-off-by: Emmanuel Bigeon <emmanuel@bigeon.fr>
This commit is contained in:
Emmanuel Bigeon 2018-11-24 21:07:28 -05:00
parent dfca63b179
commit 85ef68f6ae
3 changed files with 80 additions and 3 deletions

View File

@ -50,6 +50,12 @@
<artifactId>gclc</artifactId>
<version>2.0.11</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.23.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@ -63,6 +63,7 @@ public final class ForwardingRunnable implements Runnable {
private final ConsoleOutput out;
/** The input stream. */
private final InputStream is;
private Exception error;
/** Create the runnable.
*
@ -78,21 +79,22 @@ public final class ForwardingRunnable implements Runnable {
@Override
public void run() {
try {
readToEnd(out, is);
readToEnd();
is.close();
} catch (final CommandRunException e) {
LOGGER.log(Level.WARNING, "Manager was closed in the meantime...", e); //$NON-NLS-1$
setError(e);
} catch (final IOException e) {
LOGGER.log(Level.WARNING, "Input stream was closed...", e); //$NON-NLS-1$
setError(e);
}
}
/** Read the input until its end.
*
* @param is the input stream
* @throws CommandRunException if the manager was closed while writing the
* stream */
private static void readToEnd(final ConsoleOutput out, final InputStream is)
private void readToEnd()
throws CommandRunException {
int c;
try {
@ -102,6 +104,7 @@ public final class ForwardingRunnable implements Runnable {
}
} catch (final IOException e) {
LOGGER.log(Level.INFO, "input stream reading failed", e); //$NON-NLS-1$
setError(e);
}
}
@ -141,4 +144,14 @@ public final class ForwardingRunnable implements Runnable {
public static Thread connect(final InputStream stream, final ConsoleOutput output) {
return connect(stream, output, "Forwarding");
}
/** @return the error */
public synchronized Exception getError() {
return error;
}
/** @param error the error to set */
private synchronized void setError(final Exception error) {
this.error = error;
}
}

View File

@ -0,0 +1,58 @@
/**
*
*/
package net.bigeon.gclc.system;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.junit.Test;
import org.mockito.Mockito;
import net.bigeon.gclc.exception.CommandRunException;
import net.bigeon.gclc.utils.SinkOutput;
import net.bigeon.gclc.utils.StreamConsoleOutput;
/** @author Emmanuel Bigeon */
public class ForwardingRunnableTest {
/** Test method for {@link net.bigeon.gclc.system.ForwardingRunnable#run()}. */
@Test
public void testClosedOutput() {
final StreamConsoleOutput out = new StreamConsoleOutput();
out.close();
final InputStream is = new ByteArrayInputStream(new byte[] { 1, 2, 3 });
final ForwardingRunnable runnable = new ForwardingRunnable(out, is);
// Runnable should close immediatly.
runnable.run();
assertTrue("Error should be a CommandRunException",
runnable.getError() instanceof CommandRunException);
}
@Test
public void testIOInInput() throws IOException {
final InputStream is = Mockito.mock(InputStream.class);
Mockito.when(is.read()).thenThrow(new IOException());
final ForwardingRunnable runnable = new ForwardingRunnable(SinkOutput.INSTANCE,
is);
// Runnable should close immediatly.
runnable.run();
assertTrue("Error should be an IO", runnable.getError() instanceof IOException);
}
@Test
public void testIOInClose() throws IOException {
final InputStream is = Mockito.mock(InputStream.class);
Mockito.when(is.read()).thenReturn(-1);
Mockito.doThrow(new IOException()).when(is).close();
final ForwardingRunnable runnable = new ForwardingRunnable(SinkOutput.INSTANCE,
is);
// Runnable should close immediatly.
runnable.run();
assertTrue("Error should be an IO", runnable.getError() instanceof IOException);
}
}