Added interruption flag
Signed-off-by: Emmanuel Bigeon <emmanuel@bigeon.fr>
This commit is contained in:
parent
79ee5394d4
commit
901469792d
@ -49,7 +49,7 @@
|
||||
<dependency>
|
||||
<groupId>net.bigeon</groupId>
|
||||
<artifactId>gclc</artifactId>
|
||||
<version>2.0.12</version>
|
||||
<version>2.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.bigeon.test</groupId>
|
||||
|
@ -68,6 +68,7 @@ package net.bigeon.gclc.process.io;
|
||||
* #L%
|
||||
*/
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import net.bigeon.gclc.manager.ConsoleInput;
|
||||
@ -102,6 +103,8 @@ public final class ConnectingConsoleInput implements ConsoleInput {
|
||||
* To read or modify it, you should be in a connectionLock synchronize block. */
|
||||
private boolean disconnection = false;
|
||||
|
||||
private boolean interrupting = false;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see fr.bigeon.gclc.manager.ConsoleInput#close() */
|
||||
@Override
|
||||
@ -149,6 +152,9 @@ public final class ConnectingConsoleInput implements ConsoleInput {
|
||||
public void interruptPrompt() {
|
||||
synchronized (connectionLock) {
|
||||
synchronized (promptLock) {
|
||||
if (prompting) {
|
||||
interrupting = true;
|
||||
}
|
||||
connectionLock.notifyAll();
|
||||
if (connected != null) {
|
||||
connected.interruptPrompt();
|
||||
@ -201,14 +207,21 @@ public final class ConnectingConsoleInput implements ConsoleInput {
|
||||
actualConnected = connected;
|
||||
}
|
||||
if (connect) {
|
||||
try {
|
||||
final String res = actualConnected.prompt(message);
|
||||
synchronized (promptLock) {
|
||||
if (prompting) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
} catch (final InterruptedIOException e) {
|
||||
// The inner console was interrupted. This can mean we are
|
||||
// disconnecting or actually interrupted.
|
||||
if (disconnection) {
|
||||
disconnection = false;
|
||||
} else if (prompting) {
|
||||
return res;
|
||||
} else {
|
||||
// prompt interrupted, lose the result.
|
||||
interrupting = false;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -241,14 +254,21 @@ public final class ConnectingConsoleInput implements ConsoleInput {
|
||||
}
|
||||
if (connect) {
|
||||
synchronized (promptLock) {
|
||||
try {
|
||||
final String res = actualConnected.prompt(message,
|
||||
end - System.currentTimeMillis());
|
||||
if (prompting) {
|
||||
return res;
|
||||
}
|
||||
} catch (final InterruptedIOException e) {
|
||||
// The inner console was interrupted. This can mean we are
|
||||
// disconnecting or actually interrupted.
|
||||
if (disconnection) {
|
||||
disconnection = false;
|
||||
} else if (prompting) {
|
||||
return res;
|
||||
} else {
|
||||
// prompt interrupted, lose the result.
|
||||
throw e;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -257,7 +277,7 @@ public final class ConnectingConsoleInput implements ConsoleInput {
|
||||
|
||||
}
|
||||
|
||||
private void getConnection(final long timeout) {
|
||||
private void getConnection(final long timeout) throws InterruptedIOException {
|
||||
boolean connect;
|
||||
synchronized (connectionLock) {
|
||||
connect = connected != null;
|
||||
@ -268,6 +288,10 @@ public final class ConnectingConsoleInput implements ConsoleInput {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
if (interrupting) {
|
||||
interrupting = false;
|
||||
throw new InterruptedIOException("Prompt ws interrupted");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,14 +12,16 @@ import org.junit.Test;
|
||||
|
||||
import net.bigeon.gclc.exception.CommandRunException;
|
||||
import net.bigeon.gclc.exception.CommandRunExceptionType;
|
||||
import net.bigeon.gclc.utils.PipedConsoleInput;
|
||||
import net.bigeon.gclc.utils.PipedConsoleOutput;
|
||||
import net.bigeon.gclc.manager.PipedConsoleInput;
|
||||
import net.bigeon.gclc.manager.PipedConsoleOutput;
|
||||
|
||||
/** @author Emmanuel Bigeon */
|
||||
public class ForkTaskTest {
|
||||
|
||||
@Test
|
||||
public void testGenericForkTask() throws IOException {
|
||||
|
||||
// FIXME This test fail to complete on Jenkins.
|
||||
final ForkTask task = new ForkTask(5) {
|
||||
|
||||
@Override
|
||||
@ -36,15 +38,11 @@ public class ForkTaskTest {
|
||||
throw new CommandRunException(CommandRunExceptionType.INTERACTION,
|
||||
"Unable to prompt user");
|
||||
}
|
||||
if ("ok".equals(msg)) {
|
||||
out.println("Message");
|
||||
} else {
|
||||
out.println("fail");
|
||||
}
|
||||
out.println(msg);
|
||||
}
|
||||
};
|
||||
|
||||
final Thread execThread = new Thread(task);
|
||||
final Thread execThread = new Thread(task, "Task");
|
||||
execThread.start();
|
||||
try {
|
||||
execThread.join(100);
|
||||
@ -55,11 +53,11 @@ public class ForkTaskTest {
|
||||
|
||||
try (PipedConsoleOutput pco = new PipedConsoleOutput();
|
||||
PipedConsoleInput pci = new PipedConsoleInput(null)) {
|
||||
pci.type("ok");
|
||||
while (!pco.available()) {
|
||||
pci.type("ok");
|
||||
task.join(pco, pci, 1000);
|
||||
}
|
||||
assertEquals("Execution should work", "Message", pco.readNextLine());
|
||||
assertEquals("Positive execution", "ok", pco.readNextLine());
|
||||
}
|
||||
assertFalse("Running state should be updated by task on its completion",
|
||||
task.isRunning());
|
||||
|
@ -14,8 +14,8 @@ import org.junit.Test;
|
||||
|
||||
import net.bigeon.gclc.exception.CommandRunException;
|
||||
import net.bigeon.gclc.exception.CommandRunExceptionType;
|
||||
import net.bigeon.gclc.manager.PipedConsoleOutput;
|
||||
import net.bigeon.gclc.process.mocks.TaskMock;
|
||||
import net.bigeon.gclc.utils.PipedConsoleOutput;
|
||||
|
||||
/** @author Emmanuel Bigeon */
|
||||
public class ProcessListTest {
|
||||
|
@ -4,8 +4,10 @@ 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 java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.io.PipedInputStream;
|
||||
import java.io.PipedOutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -13,9 +15,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import net.bigeon.gclc.manager.PipedConsoleInput;
|
||||
import net.bigeon.gclc.manager.StreamConsoleInput;
|
||||
import net.bigeon.gclc.tools.ConstantString;
|
||||
import net.bigeon.gclc.utils.PipedConsoleInput;
|
||||
import net.bigeon.gclc.utils.StreamConsoleInput;
|
||||
import net.bigeon.test.junitmt.ATestRunnable;
|
||||
import net.bigeon.test.junitmt.FunctionalTestRunnable;
|
||||
import net.bigeon.test.junitmt.TestFunction;
|
||||
@ -81,10 +83,26 @@ public class ConnectingConsoleInputTest {
|
||||
|
||||
@Override
|
||||
public void apply() throws Exception {
|
||||
assertNull("Interrupted should return null", in.prompt("m1", -1));
|
||||
assertNull("Interrupted should return null", in.prompt("m2", 5000));
|
||||
try {
|
||||
in.prompt("m1", -1);
|
||||
fail("interruption of infinite waiting prompt should cause error");
|
||||
} catch (final InterruptedIOException e) {
|
||||
// ok
|
||||
}
|
||||
try {
|
||||
in.prompt("m2", 5000);
|
||||
fail("interruption of finite waiting prompt should cause error");
|
||||
} catch (final InterruptedIOException e) {
|
||||
// ok
|
||||
}
|
||||
synchronized (ended) {
|
||||
ended.set(true);
|
||||
try {
|
||||
assertNull("Overtime should return null", in.prompt("m3", 200));
|
||||
} catch (final InterruptedIOException e) {
|
||||
fail("Unexpected interruption error in overtime");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
final ATestRunnable runnable = new FunctionalTestRunnable(one);
|
||||
@ -95,14 +113,18 @@ public class ConnectingConsoleInputTest {
|
||||
public void run() {
|
||||
while (!ended.get()) {
|
||||
try {
|
||||
th.join(500);
|
||||
th.join(100);
|
||||
} catch (final InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
synchronized (ended) {
|
||||
if (!ended.get()) {
|
||||
in.interruptPrompt();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
th.start();
|
||||
inter.start();
|
||||
@ -112,7 +134,7 @@ public class ConnectingConsoleInputTest {
|
||||
|
||||
final PipedOutputStream os = new PipedOutputStream();
|
||||
final PipedInputStream pis = new PipedInputStream(os);
|
||||
in.connect(new StreamConsoleInput(System.out, pis, StandardCharsets.UTF_8));
|
||||
in.connect(new StreamConsoleInput(null, pis, StandardCharsets.UTF_8));
|
||||
final ATestRunnable runnable2 = new FunctionalTestRunnable(one);
|
||||
final Thread th2 = new Thread(runnable2);
|
||||
final Thread inter2 = new Thread(new Runnable() {
|
||||
@ -121,14 +143,18 @@ public class ConnectingConsoleInputTest {
|
||||
public void run() {
|
||||
while (!ended.get()) {
|
||||
try {
|
||||
th2.join(500);
|
||||
th2.join(100);
|
||||
} catch (final InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
synchronized (ended) {
|
||||
if (!ended.get()) {
|
||||
in.interruptPrompt();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
th2.start();
|
||||
inter2.start();
|
||||
|
@ -8,7 +8,7 @@ import java.io.IOException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import net.bigeon.gclc.utils.PipedConsoleOutput;
|
||||
import net.bigeon.gclc.manager.PipedConsoleOutput;
|
||||
|
||||
public class ConnectingConsoleOutputTest {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user