package io.seqware.cli.test; import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.*; import io.seqware.cli.Main; import io.seqware.pipeline.plugins.WorkflowLifecycle; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; import java.util.HashMap; import net.sourceforge.seqware.common.metadata.Metadata; import net.sourceforge.seqware.common.metadata.MetadataFactory; import net.sourceforge.seqware.common.model.WorkflowRun; import net.sourceforge.seqware.common.module.ReturnValue; import net.sourceforge.seqware.common.util.configtools.ConfigTools; import net.sourceforge.seqware.pipeline.runner.PluginRunner; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @PrepareForTest({ io.seqware.cli.Main.class, net.sourceforge.seqware.pipeline.runner.PluginRunner.class, io.seqware.pipeline.plugins.WorkflowLifecycle.class, net.sourceforge.seqware.common.util.configtools.ConfigTools.class, net.sourceforge.seqware.common.metadata.Metadata.class, net.sourceforge.seqware.common.metadata.MetadataFactory.class }) @RunWith(PowerMockRunner.class) public class WorkflowRunTest { private String errBuff; @Mock Metadata mockMD; @Before public void setUp() { errBuff = ""; PowerMockito.mockStatic(MetadataFactory.class); PowerMockito.mockStatic(ConfigTools.class); PowerMockito.when(ConfigTools.getSettings()).thenReturn(new HashMap<String, String>()); } class WriteFormattedMessageToBufferAnswer implements Answer<Object> { @Override public Object answer(InvocationOnMock invocation) throws Throwable { errBuff = String.format((String) invocation.getArguments()[0], Arrays.copyOfRange(invocation.getArguments(), 1, invocation.getArguments().length)); throw new Exception(errBuff); } } @Test public void testWorkflowRunINI() throws Exception { String[] mainArgs = { "workflow-run", "ini", "--accession", "12345", "--out", "test.out" }; String[] runnerArgs = { "--plugin", "net.sourceforge.seqware.pipeline.plugins.BundleManager", "--", "--list-workflow-params", "--workflow-accession", "12345" }; Path path = FileSystems.getDefault().getPath("src/test/resources/bad.ini"); String ini = new String(Files.readAllBytes(path)); testWithSuccess(mainArgs, runnerArgs, ini); } @Test public void testWorkflowRunININoOut() throws Exception { String[] mainArgs = { "workflow-run", "ini", "--accession", "12345" }; String[] runnerArgs = { "--plugin", "net.sourceforge.seqware.pipeline.plugins.BundleManager", "--", "--list-workflow-params", "--workflow-accession", "12345" }; Path path = FileSystems.getDefault().getPath("src/test/resources/bad.ini"); String ini = new String(Files.readAllBytes(path)); testWithSuccess(mainArgs, runnerArgs, ini); } @Test public void testWorkflowRunINIExtraArgs() throws Exception { String[] mainArgs = { "workflow-run", "ini", "--accession", "12345", "--extra-arg" }; testWithError(mainArgs, "seqware: unexpected arguments to 'workflow-run ini': --extra-arg"); } class WorkflowRunnerAnswer implements Answer<Object> { private String[] runnerArgs; public void setRunnerArgs(String[] args) { this.runnerArgs = args; } @Override public Object answer(InvocationOnMock invocation) throws Throwable { System.out.println("\nArgs to PluginRunner.run: "); for (String s : (String[]) invocation.getArguments()[0]) { System.out.print(s + " "); } String[] givenArgs = ((String[]) invocation.getArguments()[0]); for (int i = 0; i < givenArgs.length; i++) { assertEquals("mismatch on arg #" + i, runnerArgs[i], givenArgs[i]); } return new ReturnValue(); } } private void testWithError(String[] mainArgs, String errorMessage) throws Exception { PowerMockito.spy(Main.class); PowerMockito.doAnswer(new WriteFormattedMessageToBufferAnswer()).when(Main.class, "kill", anyString(), Matchers.<Object> anyVararg()); try { Main.main(mainArgs); } catch (Exception e) { assertEquals(errorMessage, e.getMessage()); } } private void testWithSuccess(String[] mainArgs, String[] runnerArgs, String ini) throws Exception { WorkflowRun wf = new WorkflowRun(); wf = new WorkflowRun(); wf.setIniFile(ini); PowerMockito.when(mockMD.getWorkflowRun(anyInt())).thenReturn(wf); PowerMockito.when(MetadataFactory.get(anyMapOf(String.class, String.class))).thenReturn(mockMD); PluginRunner spiedRunner = PowerMockito.spy(new PluginRunner()); PowerMockito.spy(Main.class); WorkflowLifecycle wfPlugin = PowerMockito.mock(WorkflowLifecycle.class); PowerMockito.when(wfPlugin.do_run()).thenReturn(new ReturnValue()); PowerMockito.whenNew(WorkflowLifecycle.class).withAnyArguments().thenReturn(wfPlugin); WorkflowRunnerAnswer answer = new WorkflowRunnerAnswer(); answer.setRunnerArgs(runnerArgs); PowerMockito.doAnswer(answer).when(spiedRunner, "run", any()); PowerMockito.whenNew(PluginRunner.class).withNoArguments().thenReturn(spiedRunner); Main.main(mainArgs); } }