+ * To change it you should be in a promptLock. */ private boolean prompting = false; - /** The synchronization lock for the rompting status. */ + /** The synchronization lock for the prompting status. */ private final Object promptLock = new Object(); /** The synchronization lock for the connection status. */ private final Object connectionLock = new Object(); - /** The connected console input. */ + /** The connected console input. + *
+ * To use it, you should be in a promptLock and connectionLock. */ private ConsoleInput connected = null; - /** The connection state. */ + /** The connection state. + *
+ * To read or modify it, you should be in a connectionLock synchronize block. */ private boolean disconnection = false; /* (non-Javadoc) @@ -185,7 +191,11 @@ public final class ConnectingConsoleInput implements ConsoleInput { if (!prompting) { return null; } - if (connected == null) { + boolean connect = true; + synchronized (connectionLock) { + connect = connected != null; + } + if (!connect) { try { promptLock.wait(); } catch (final InterruptedException e) { @@ -193,8 +203,8 @@ public final class ConnectingConsoleInput implements ConsoleInput { Thread.currentThread().interrupt(); } } else { - final String res = connected.prompt(message); synchronized (connectionLock) { + final String res = connected.prompt(message); if (disconnection) { disconnection = false; } else if (prompting) { @@ -219,14 +229,14 @@ public final class ConnectingConsoleInput implements ConsoleInput { synchronized (promptLock) { prompting = true; } - while (true) { + do { synchronized (promptLock) { if (!prompting) { return null; } if (connected == null) { try { - promptLock.wait(); + promptLock.wait(timeout); } catch (final InterruptedException e) { LOGGER.log(Level.WARNING, "Inerruption of console thread", e); Thread.currentThread().interrupt(); @@ -245,19 +255,15 @@ public final class ConnectingConsoleInput implements ConsoleInput { } } } - } + } while (System.currentTimeMillis() < end); + return null; } /* (non-Javadoc) * @see fr.bigeon.gclc.manager.ConsoleInput#setPrompt(java.lang.String) */ @Override public void setPrompt(final String prompt) { - this.prompt = new StringProvider() { - @Override - public String apply() { - return prompt; - } - }; + this.prompt = new ConstantString(prompt); } /* (non-Javadoc) diff --git a/gclc-process/src/test/java/net/bigeon/gclc/process/CommandForegroundTest.java b/gclc-process/src/test/java/net/bigeon/gclc/process/CommandForegroundTest.java new file mode 100644 index 0000000..39c0f24 --- /dev/null +++ b/gclc-process/src/test/java/net/bigeon/gclc/process/CommandForegroundTest.java @@ -0,0 +1,90 @@ +/** + * + */ +package net.bigeon.gclc.process; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import org.junit.Test; + +import net.bigeon.gclc.exception.CommandRunException; +import net.bigeon.gclc.exception.CommandRunExceptionType; +import net.bigeon.gclc.process.mocks.ForkTaskMock; + +/** + * @author Emmanuel Bigeon + * + */ +public class CommandForegroundTest { + + /** + * Test method for {@link net.bigeon.gclc.process.CommandForeground#CommandForeground(java.lang.String, net.bigeon.gclc.process.TaskPool)}. + */ + @Test + public void testCommandForeground() { + final CommandForeground pl = new CommandForeground("fg", new TaskPool()); + assertEquals("Command name should be kept as specified", "fg", + pl.getCommandName()); + } + + /** Test method for + * {@link net.bigeon.gclc.process.CommandForeground#doExecute(net.bigeon.gclc.manager.ConsoleOutput, net.bigeon.gclc.manager.ConsoleInput, net.bigeon.gclc.command.CommandParameters)}. + * + * @throws CommandRunException if a valid command failed */ + @Test + public void testDoExecuteConsoleOutputConsoleInputCommandParameters() + throws CommandRunException { + final TaskPool pool = new TaskPool(false); + final CommandForeground pl = new CommandForeground("fg", pool); + + try { + pl.execute(null, null, "-delai", "1"); + fail("PID should be mandatory"); + } catch (final CommandRunException e) { + assertEquals("No pid specified is a usage error", + CommandRunExceptionType.USAGE, e.getType()); + } + try { + pl.execute(null, null, "-pid", "invalid", "-delai", "1"); + fail("PID should be a number"); + } catch (final CommandRunException e) { + assertEquals("Invalid pid specified is a usage error", + CommandRunExceptionType.USAGE, e.getType()); + } + try { + pl.execute(null, null, "-pid", "2", "-delai", "1"); + fail("PID should exist"); + } catch (final CommandRunException e) { + assertEquals("Inexistent pid specified is a run error", + CommandRunExceptionType.EXECUTION, e.getType()); + } + + final ForkTaskMock cmd = new ForkTaskMock(); + final int id = pool.add(cmd); + pl.execute(null, null, "-pid", Integer.toString(id), "-delai", "1"); + + try { + pl.execute(null, null, "-pid", Integer.toString(id), "-delai", "-1"); + fail("delai should be a posistive number"); + } catch (final CommandRunException e) { + assertEquals("Negative delai specified is a usage error", + CommandRunExceptionType.USAGE, e.getType()); + } + + assert cmd.getRunCall() == 0; + } + + /** + * Test method for {@link net.bigeon.gclc.process.CommandForeground#tip()}. + */ + @Test + public void testTip() { + final CommandForeground pl = new CommandForeground("fg", new TaskPool()); + assertNotNull("Command tip should be defined", pl.tip()); + assertNotNull("Command usage should be defined", pl.usagePattern()); + assertNotNull("Command usage should be defined", pl.usageDetail()); + } + +} diff --git a/gclc-process/src/test/java/net/bigeon/gclc/process/CommandForkTest.java b/gclc-process/src/test/java/net/bigeon/gclc/process/CommandForkTest.java new file mode 100644 index 0000000..ecdea66 --- /dev/null +++ b/gclc-process/src/test/java/net/bigeon/gclc/process/CommandForkTest.java @@ -0,0 +1,86 @@ +/** + * + */ +package net.bigeon.gclc.process; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import org.junit.Test; + +import net.bigeon.gclc.command.ICommandProvider; +import net.bigeon.gclc.command.SubedCommand; +import net.bigeon.gclc.exception.CommandRunException; +import net.bigeon.gclc.exception.CommandRunExceptionType; +import net.bigeon.gclc.exception.InvalidCommandName; +import net.bigeon.gclc.process.mocks.CommandMock; + +/** + * @author Emmanuel Bigeon + * + */ +public class CommandForkTest { + + /** + * Test method for {@link net.bigeon.gclc.process.CommandFork#CommandFork(java.lang.String, net.bigeon.gclc.command.ICommandProvider, net.bigeon.gclc.process.TaskPool)}. + */ + @Test + public void testCommandForkStringICommandProviderTaskPool() { + final TaskPool pool = new TaskPool(); + final ICommandProvider provider = new SubedCommand("test"); + final CommandFork pl = new CommandFork("fork", provider, pool); + assertEquals("Command name should be preserved", "fork", pl.getCommandName()); + } + + /** Test method for + * {@link net.bigeon.gclc.process.CommandFork#execute(net.bigeon.gclc.manager.ConsoleOutput, net.bigeon.gclc.manager.ConsoleInput, java.lang.String[])}. + * + * @throws InvalidCommandName if the test init failed + * @throws CommandRunException */ + @Test + public void testExecute() throws InvalidCommandName, CommandRunException { + final TaskPool pool = new TaskPool(false); + final ICommandProvider provider = new SubedCommand("test"); + final CommandFork pl = new CommandFork("fork", provider, pool); + + try { + pl.execute(null, null); + fail("No command specified should through an exception"); + } catch (final CommandRunException e) { + assertEquals("No command specified is a usage error", + CommandRunExceptionType.USAGE, e.getType()); + } + try { + pl.execute(null, null, "invalid"); + fail("Invalid command specified should through an exception"); + } catch (final CommandRunException e) { + assertEquals("Invalid command specified is a usage error", + CommandRunExceptionType.USAGE, e.getType()); + } + + final CommandMock mock = new CommandMock(); + provider.add(mock); + + pl.execute(null, null, mock.getCommandName()); + + final ForkTask task = (ForkTask) pool.get(pool.getPIDs().iterator().next()); + task.join(null, null, 1000); + + assertEquals("Command should be executed when forked", 1, mock.getExecuteCall()); + } + + /** + * Test method for {@link net.bigeon.gclc.process.CommandFork#tip()}. + */ + @Test + public void testTip() { + final TaskPool pool = new TaskPool(); + final ICommandProvider provider = new SubedCommand("test"); + final CommandFork pl = new CommandFork("fork", provider, pool); + assertNotNull("Command tip should be defined", pl.tip()); + assertNotNull("Command usage should be defined", pl.usagePattern()); + assertNotNull("Command usage should be defined", pl.usageDetail()); + } + +} diff --git a/gclc-process/src/test/java/net/bigeon/gclc/process/ForkCommandTaskTest.java b/gclc-process/src/test/java/net/bigeon/gclc/process/ForkCommandTaskTest.java new file mode 100644 index 0000000..1810418 --- /dev/null +++ b/gclc-process/src/test/java/net/bigeon/gclc/process/ForkCommandTaskTest.java @@ -0,0 +1,35 @@ +/** + * + */ +package net.bigeon.gclc.process; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import net.bigeon.gclc.process.mocks.CommandMock; + +/** + * @author Emmanuel Bigeon + * + */ +public class ForkCommandTaskTest { + + /** Test method for + * {@link net.bigeon.gclc.process.ForkCommandTask#ForkCommandTask(net.bigeon.gclc.command.ICommand, java.lang.String[], int)}. + * + * @throws InterruptedException if there is an error in the thread join */ + @Test + public void testForkCommandTask() throws InterruptedException { + final CommandMock cmd = new CommandMock(); + final ForkCommandTask task = new ForkCommandTask(cmd, new String[0], 1); + + final Thread th = new Thread(task); + th.start(); + th.join(); + + assertEquals("Task should be executed once", 1, cmd.getExecuteCall()); + assertEquals("Names should be consistent between task and command", + cmd.getCommandName(), task.getName()); + } +} diff --git a/gclc-process/src/test/java/net/bigeon/gclc/process/ForkTaskTest.java b/gclc-process/src/test/java/net/bigeon/gclc/process/ForkTaskTest.java new file mode 100644 index 0000000..0078348 --- /dev/null +++ b/gclc-process/src/test/java/net/bigeon/gclc/process/ForkTaskTest.java @@ -0,0 +1,62 @@ +/** + * + */ +package net.bigeon.gclc.process; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import java.io.IOException; + +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; + +/** @author Emmanuel Bigeon */ +public class ForkTaskTest { + + @Test + public void test() throws IOException { + final ForkTask task = new ForkTask(5) { + + @Override + public String getName() { + return "name"; + } + + @Override + protected void doRun() throws CommandRunException { + String msg; + try { + msg = in.prompt(); + } catch (final IOException e) { + throw new CommandRunException(CommandRunExceptionType.INTERACTION, + "Unable to prompt user"); + } + if ("ok".equals(msg)) { + out.println("Message"); + } else { + out.println("fail"); + } + } + }; + + final Thread execThread = new Thread(task); + execThread.start(); + + try (PipedConsoleOutput pco = new PipedConsoleOutput(); + PipedConsoleInput pci = new PipedConsoleInput(null)) { + pci.type("ok"); + while (!pco.available()) { + task.join(pco, pci, 1000); + } + assertEquals("Execution should work", "Message", pco.readNextLine()); + } + assertFalse("Running state should be updated by task on its completion", + task.isRunning()); + } + +} diff --git a/gclc-process/src/test/java/net/bigeon/gclc/process/ProcessClearTest.java b/gclc-process/src/test/java/net/bigeon/gclc/process/ProcessClearTest.java new file mode 100644 index 0000000..c115d9b --- /dev/null +++ b/gclc-process/src/test/java/net/bigeon/gclc/process/ProcessClearTest.java @@ -0,0 +1,53 @@ +/** + * + */ +package net.bigeon.gclc.process; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import net.bigeon.gclc.process.mocks.TaskMock; + +/** + * @author Emmanuel Bigeon + * + */ +public class ProcessClearTest { + + /** + * Test method for {@link net.bigeon.gclc.process.ProcessClear#ProcessClear(java.lang.String, net.bigeon.gclc.process.TaskPool)}. + */ + @Test + public void testProcessClear() { + final ProcessClear pl = new ProcessClear("clear", new TaskPool()); + assertEquals("Command name should be kept as specified", "clear", + pl.getCommandName()); + } + + /** + * Test method for {@link net.bigeon.gclc.process.ProcessClear#execute(net.bigeon.gclc.manager.ConsoleOutput, net.bigeon.gclc.manager.ConsoleInput, java.lang.String[])}. + */ + @Test + public void testExecute() { + final TaskPool pool = new TaskPool(); + final TaskMock task = new TaskMock(); + pool.add(task); + final ProcessClear pl = new ProcessClear("clear", pool); + pl.execute(null, null); + assertTrue("cleared pool should be empty", pool.getPIDs().isEmpty()); + } + + /** + * Test method for {@link net.bigeon.gclc.process.ProcessClear#tip()}. + */ + @Test + public void testTip() { + final ProcessClear pl = new ProcessClear("clear", new TaskPool()); + assertNotNull("Command tip should be defined", pl.tip()); + assertNotNull("Command usage should be defined", pl.usageDetail()); + } + +} diff --git a/gclc-process/src/test/java/net/bigeon/gclc/process/ProcessKillTest.java b/gclc-process/src/test/java/net/bigeon/gclc/process/ProcessKillTest.java new file mode 100644 index 0000000..62ad5a9 --- /dev/null +++ b/gclc-process/src/test/java/net/bigeon/gclc/process/ProcessKillTest.java @@ -0,0 +1,65 @@ +/** + * + */ +package net.bigeon.gclc.process; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import java.io.IOException; + +import org.junit.Test; + +import net.bigeon.gclc.exception.CommandRunException; +import net.bigeon.gclc.exception.CommandRunExceptionType; +import net.bigeon.gclc.process.mocks.TaskMock; + +/** @author Emmanuel Bigeon */ +public class ProcessKillTest { + + /** Test method for + * {@link net.bigeon.gclc.process.ProcessKill#ProcessKill(java.lang.String, net.bigeon.gclc.process.TaskPool)}. */ + @Test + public void testProcessKill() { + final ProcessList pl = new ProcessList("kill", new TaskPool()); + assertEquals("Command name should be kept as specified", "kill", + pl.getCommandName()); + } + + /** Test method for + * {@link net.bigeon.gclc.process.ProcessKill#execute(net.bigeon.gclc.manager.ConsoleOutput, net.bigeon.gclc.manager.ConsoleInput, java.lang.String[])}. + * + * @throws CommandRunException if an error occured in test + * @throws IOException if an error occured with the console output */ + @Test + public void testExecute() throws CommandRunException { + final TaskPool pool = new TaskPool(); + final TaskMock task = new TaskMock(); + final int id = pool.add(task); + final ProcessKill pl = new ProcessKill("kill", pool); + task.reset(); + try { + pl.execute(null, null); + fail("Execution with no pid should raise exception"); + } catch (final CommandRunException e) { + assertEquals("Usage exception expected", CommandRunExceptionType.USAGE, + e.getType()); + } + pl.execute(null, null, Integer.toString(id)); + assertEquals("Task should be shutdown", 1, task.getNumberSetRunning()); + task.reset(); + pl.execute(null, null, Integer.toString(id)); + assertEquals("Task should be shutdown", 1, task.getNumberSetRunning()); + } + + /** Test method for {@link net.bigeon.gclc.process.ProcessKill#tip()}. */ + @Test + public void testTip() { + final ProcessKill pl = new ProcessKill("kill", new TaskPool()); + assertNotNull("Command tip should be defined", pl.tip()); + assertNotNull("Command usage should be defined", pl.usagePattern()); + assertNotNull("Command usage should be defined", pl.usageDetail()); + } + +} diff --git a/gclc-process/src/test/java/net/bigeon/gclc/process/ProcessListTest.java b/gclc-process/src/test/java/net/bigeon/gclc/process/ProcessListTest.java new file mode 100644 index 0000000..7a3cd05 --- /dev/null +++ b/gclc-process/src/test/java/net/bigeon/gclc/process/ProcessListTest.java @@ -0,0 +1,67 @@ +/** + * + */ +package net.bigeon.gclc.process; + +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 java.io.IOException; + +import org.junit.Test; + +import net.bigeon.gclc.exception.CommandRunException; +import net.bigeon.gclc.exception.CommandRunExceptionType; +import net.bigeon.gclc.process.mocks.TaskMock; +import net.bigeon.gclc.utils.PipedConsoleOutput; + +/** @author Emmanuel Bigeon */ +public class ProcessListTest { + + /** Test method for + * {@link net.bigeon.gclc.process.ProcessList#ProcessList(java.lang.String, net.bigeon.gclc.process.TaskPool)}. */ + @Test + public void testProcessList() { + final ProcessList pl = new ProcessList("list", new TaskPool()); + assertEquals("Command name should be kept as specified", "list", + pl.getCommandName()); + } + + /** Test method for + * {@link net.bigeon.gclc.process.ProcessList#execute(net.bigeon.gclc.manager.ConsoleOutput, net.bigeon.gclc.manager.ConsoleInput, java.lang.String[])}. + * + * @throws CommandRunException if an error occured + * @throws IOException if an error in initialization of console occured */ + @Test + public void testExecute() throws CommandRunException, IOException { + final TaskPool pool = new TaskPool(); + final TaskMock task = new TaskMock(); + pool.add(task); + final ProcessList pl = new ProcessList("list", pool); + final PipedConsoleOutput out = new PipedConsoleOutput(); + pl.execute(out, null); + + assertTrue("Task should be contained in list", + out.readNextLine().contains(task.getName())); + + out.close(); + + try { + pl.execute(out, null); + fail("Printing element to closed console should raise interaction exception"); + } catch (final CommandRunException e) { + assertEquals("Console printing error should be an interaction error", + CommandRunExceptionType.INTERACTION, e.getType()); + } + } + + /** Test method for {@link net.bigeon.gclc.process.ProcessList#tip()}. */ + @Test + public void testTip() { + final ProcessList pl = new ProcessList("list", new TaskPool()); + assertNotNull("Command tip should be defined", pl.tip()); + assertNotNull("Command usage should be defined", pl.usageDetail()); + } +} diff --git a/gclc-process/src/test/java/net/bigeon/gclc/process/TaskPoolTest.java b/gclc-process/src/test/java/net/bigeon/gclc/process/TaskPoolTest.java new file mode 100644 index 0000000..3acbad4 --- /dev/null +++ b/gclc-process/src/test/java/net/bigeon/gclc/process/TaskPoolTest.java @@ -0,0 +1,77 @@ +package net.bigeon.gclc.process; + +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 org.junit.Test; + +import net.bigeon.gclc.process.mocks.TaskMock; + +public class TaskPoolTest { + + public TaskMock task = new TaskMock(); + public TaskPool pool = new TaskPool(false); + + @Test + public void testTaskPool() { + assertFalse("task pool should not auto clear if specified", + pool.isAutoClearing()); + pool = new TaskPool(); + assertTrue("Default task pool should not auto clear", pool.isAutoClearing()); + } + + @Test + public void testAdd() { + final int id = pool.add(task); + assertTrue("Added task pid should be in pool", pool.getPIDs().contains(id)); + assertEquals("Added task should be in pool", task, pool.get(id)); + } + + @Test + public void testGet() { + assertNull("Inexistent task id should provide null as task in pool", + pool.get(60)); + final int id = pool.add(task); + assertEquals("Added task should be in pool at its id", task, pool.get(id)); + assertNull("Added task should be in pool at its id", pool.get(id + 1)); + } + + @Test + public void testGetPIDs() { + assertTrue("new pool should be empty", pool.getPIDs().isEmpty()); + final int id = pool.add(task); + assertNull("Added task should be in pool at its id", pool.get(id + 1)); + assertEquals( + "Pool task addition should change the pid collection size accordingly", 1, + pool.getPIDs().size()); + } + + @Test + public void testRemove() { + assertTrue("new pool should be empty", pool.getPIDs().isEmpty()); + pool.remove(60); + assertTrue("removal of inexistent task should be NOP", pool.getPIDs().isEmpty()); + final int id = pool.add(task); + assertEquals( + "Pool task addition should change the pid collection size accordingly", 1, + pool.getPIDs().size()); + pool.remove(id + 1); + assertEquals("removal of inexistent task should be NOP", 1, + pool.getPIDs().size()); + pool.remove(id); + assertTrue("removal of task should reduce the number of tasks", + pool.getPIDs().isEmpty()); + } + + @Test + public void testShutdown() { + final int id = pool.add(task); + task.reset(); + pool.shutdown(); + assertEquals("Shutdown should request shut down of tasks, only once", 1, + task.getNumberSetRunning()); + } + +} diff --git a/gclc-process/src/test/java/net/bigeon/gclc/process/io/ConnectingConsoleInputTest.java b/gclc-process/src/test/java/net/bigeon/gclc/process/io/ConnectingConsoleInputTest.java new file mode 100644 index 0000000..548a89d --- /dev/null +++ b/gclc-process/src/test/java/net/bigeon/gclc/process/io/ConnectingConsoleInputTest.java @@ -0,0 +1,65 @@ +package net.bigeon.gclc.process.io; + +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 java.io.IOException; + +import org.junit.Test; + +import net.bigeon.gclc.tools.ConstantString; +import net.bigeon.gclc.utils.PipedConsoleInput; + +public class ConnectingConsoleInputTest { + + @Test + public void testConnect() throws IOException { + final ConnectingConsoleInput in = new ConnectingConsoleInput(); + final PipedConsoleInput pci = new PipedConsoleInput(null); + assertNull("Inputs should not transmit before connection", in.prompt(1000)); + in.connect(pci); + pci.type("Some message"); + assertEquals("Messages should be buffered", "Some message", in.prompt()); + } + + @Test + public void testDisconnect() throws IOException { + final ConnectingConsoleInput in = new ConnectingConsoleInput(); + final PipedConsoleInput pci = new PipedConsoleInput(null); + assertNull("Inputs should not transmit before connection", in.prompt(1000)); + in.connect(pci); + pci.type("Some message"); + assertEquals("Messages should be buffered", "Some message", in.prompt()); + in.disconnect(); + assertNull("Disconnected inputs should not transmit anymore", in.prompt(1000)); + } + + @Test + public void testIsClosed() throws IOException { + final ConnectingConsoleInput in = new ConnectingConsoleInput(); + assertFalse("New input should not be closed", in.isClosed()); + final PipedConsoleInput pci = new PipedConsoleInput(null); + in.connect(pci); + pci.close(); + assertFalse("Connected input closing should not close connecting", in.isClosed()); + final PipedConsoleInput pci2 = new PipedConsoleInput(null); + in.connect(pci2); + in.close(); + assertTrue("Input should close on request", in.isClosed()); + assertFalse("Connected input should not be closed by connecting closure", + pci2.isClosed()); + } + + @Test + public void testCoveragePrompt() { + final ConnectingConsoleInput in = new ConnectingConsoleInput(); + in.setPrompt("test"); + assertEquals("Prompt should be set correctly", "test", + ((ConstantString) in.getPrompt()).apply()); + final ConstantString prompt = new ConstantString("other"); + in.setPrompt(prompt); + assertEquals("Prompt should be set correctly", prompt, in.getPrompt()); + } +} diff --git a/gclc-process/src/test/java/net/bigeon/gclc/process/io/ConnectingConsoleOutputTest.java b/gclc-process/src/test/java/net/bigeon/gclc/process/io/ConnectingConsoleOutputTest.java new file mode 100644 index 0000000..e919b0c --- /dev/null +++ b/gclc-process/src/test/java/net/bigeon/gclc/process/io/ConnectingConsoleOutputTest.java @@ -0,0 +1,88 @@ +package net.bigeon.gclc.process.io; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; + +import org.junit.Test; + +import net.bigeon.gclc.utils.PipedConsoleOutput; + +public class ConnectingConsoleOutputTest { + + @Test + public void testConnect() throws IOException { + final ConnectingConsoleOutput out = new ConnectingConsoleOutput( + ConnectingConsoleOutput.QUEUE, 10); + final PipedConsoleOutput output = new PipedConsoleOutput(); + out.println("Some message"); + assertFalse("Message should not be transmitted", output.available()); + // Connect + out.connect(output); + + // Connected outputs should receive data + final String res = output.readNextLine(); + assertEquals("Message should be correctly transmitted", "Some message", res); + } + + @Test + public void testDisconnect() throws IOException { + final ConnectingConsoleOutput out = new ConnectingConsoleOutput( + ConnectingConsoleOutput.QUEUE, 10); + final PipedConsoleOutput output = new PipedConsoleOutput(); + // NOP disconnection when no connection + out.disconnect(); + // Connect + out.connect(output); + + // Connected outputs should receive data + out.println("Some message"); + final String res = output.readNextLine(); + assertEquals("Message should be correctly transmitted", "Some message", res); + out.disconnect(); + out.println("Some message"); + assertFalse("Message should not be transmitted", output.available()); + } + + @Test + public void testIsClosed() throws IOException { + final ConnectingConsoleOutput out = new ConnectingConsoleOutput( + ConnectingConsoleOutput.QUEUE, 10); + final PipedConsoleOutput output = new PipedConsoleOutput(); + assertFalse("New output should not be closed", out.isClosed()); + // Connect + out.connect(output); + + output.close(); + + assertFalse("Output should not close when connected outputs do", out.isClosed()); + final PipedConsoleOutput output2 = new PipedConsoleOutput(); + out.connect(output2); + out.close(); + assertTrue("Output should close on request", out.isClosed()); + assertFalse("Output should not close connected output when they do", + output2.isClosed()); + } + + @Test + public void testPrint() throws IOException { + final ConnectingConsoleOutput out = new ConnectingConsoleOutput( + ConnectingConsoleOutput.PERSIST, 10); + + out.print("Some text"); + out.println(); + final PipedConsoleOutput output = new PipedConsoleOutput(); + out.connect(output); + String res = output.readNextLine(); + assertEquals("Message should be correctly transmitted", "Some text", res); + out.disconnect(); + + // Persist should be reprinted on any connect + out.connect(output); + res = output.readNextLine(); + assertEquals("Message should be correctly transmitted", "Some text", res); + out.disconnect(); + } +} diff --git a/gclc-process/src/test/java/net/bigeon/gclc/process/mocks/CommandMock.java b/gclc-process/src/test/java/net/bigeon/gclc/process/mocks/CommandMock.java new file mode 100644 index 0000000..42dbf24 --- /dev/null +++ b/gclc-process/src/test/java/net/bigeon/gclc/process/mocks/CommandMock.java @@ -0,0 +1,60 @@ +/** + * + */ +package net.bigeon.gclc.process.mocks; + +import java.io.IOException; + +import net.bigeon.gclc.command.ICommand; +import net.bigeon.gclc.exception.CommandRunException; +import net.bigeon.gclc.manager.ConsoleInput; +import net.bigeon.gclc.manager.ConsoleOutput; + +/** @author Emmanuel Bigeon */ +public class CommandMock implements ICommand { + + private int executeCall = 0; + private int tipCall = 0; + private int helpCall = 0; + private int commandNameCall = 0; + + /* (non-Javadoc) + * @see net.bigeon.gclc.command.ICommand#execute(net.bigeon.gclc.manager. + * ConsoleOutput, net.bigeon.gclc.manager.ConsoleInput, java.lang.String[]) */ + @Override + public void execute(final ConsoleOutput out, final ConsoleInput in, + final String... args) throws CommandRunException { + executeCall++; + } + + /* (non-Javadoc) + * @see net.bigeon.gclc.command.ICommand#getCommandName() */ + @Override + public String getCommandName() { + commandNameCall++; + return "name"; + } + + /* (non-Javadoc) + * @see + * net.bigeon.gclc.command.ICommand#help(net.bigeon.gclc.manager.ConsoleOutput, + * java.lang.String[]) */ + @Override + public void help(final ConsoleOutput output, final String... args) + throws IOException { + helpCall++; + } + + /* (non-Javadoc) + * @see net.bigeon.gclc.command.ICommand#tip() */ + @Override + public String tip() { + tipCall++; + return "tip"; + } + + /** @return the executeCall */ + public int getExecuteCall() { + return executeCall; + } +} diff --git a/gclc-process/src/test/java/net/bigeon/gclc/process/mocks/ForkTaskMock.java b/gclc-process/src/test/java/net/bigeon/gclc/process/mocks/ForkTaskMock.java new file mode 100644 index 0000000..5124749 --- /dev/null +++ b/gclc-process/src/test/java/net/bigeon/gclc/process/mocks/ForkTaskMock.java @@ -0,0 +1,43 @@ +/** + * + */ +package net.bigeon.gclc.process.mocks; + +import net.bigeon.gclc.exception.CommandRunException; +import net.bigeon.gclc.process.ForkTask; +import net.bigeon.gclc.process.Task; + +/** + * @author Emmanuel Bigeon + * + */ +public class ForkTaskMock extends ForkTask implements Task { + + private int runCall = 0; + + /** @param lines */ + public ForkTaskMock() { + super(10); + } + + /* (non-Javadoc) + * @see net.bigeon.gclc.process.Task#getName() + */ + @Override + public String getName() { + return "name"; + } + + /* (non-Javadoc) + * @see net.bigeon.gclc.process.ForkTask#doRun() + */ + @Override + protected void doRun() throws CommandRunException { + runCall++; + } + + /** @return the runCall */ + public int getRunCall() { + return runCall; + } +} diff --git a/gclc-process/src/test/java/net/bigeon/gclc/process/mocks/TaskMock.java b/gclc-process/src/test/java/net/bigeon/gclc/process/mocks/TaskMock.java new file mode 100644 index 0000000..a11c215 --- /dev/null +++ b/gclc-process/src/test/java/net/bigeon/gclc/process/mocks/TaskMock.java @@ -0,0 +1,57 @@ +package net.bigeon.gclc.process.mocks; + +import net.bigeon.gclc.process.InterruptionListener; +import net.bigeon.gclc.process.Task; + +public class TaskMock implements Task { + + private int runCall = 0; + private int setRunningCall = 0; + + @Override + public void run() { + runCall++; + } + + @Override + public void addInterruptionListener(final InterruptionListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public String getName() { + return "name"; + } + + @Override + public boolean isRunning() { + // TODO Auto-generated method stub + return false; + } + + @Override + public void rmInterruptionListener(final InterruptionListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public void setRunning(final boolean running) { + setRunningCall++; + } + + /** + * + */ + public void reset() { + runCall = 0; + setRunningCall = 0; + } + + /** @return */ + public Object getNumberSetRunning() { + return setRunningCall; + } + +} diff --git a/gclc-process/src/test/java/net/bigeon/gclc/process/mocks/package-info.java b/gclc-process/src/test/java/net/bigeon/gclc/process/mocks/package-info.java new file mode 100644 index 0000000..b114098 --- /dev/null +++ b/gclc-process/src/test/java/net/bigeon/gclc/process/mocks/package-info.java @@ -0,0 +1,4 @@ +/** Mock definitions for testing. + * + * @author Emmanuel Bigeon */ +package net.bigeon.gclc.process.mocks;