/*
* Copyright (C) 2006-2016 DLR, Germany
*
* All rights reserved
*
* http://www.rcenvironment.de/
*/
package de.rcenvironment.core.component.workflow.command.api;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.easymock.Capture;
import org.easymock.CaptureType;
import org.easymock.EasyMock;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import de.rcenvironment.core.authentication.Session;
import de.rcenvironment.core.command.common.CommandException;
import de.rcenvironment.core.command.common.CommandException.Type;
import de.rcenvironment.core.command.spi.CommandContext;
import de.rcenvironment.core.communication.api.PlatformService;
import de.rcenvironment.core.component.workflow.execution.api.WorkflowExecutionService;
import de.rcenvironment.core.component.workflow.execution.api.WorkflowFileException;
import de.rcenvironment.core.component.workflow.execution.headless.api.HeadlessWorkflowDescriptionLoaderCallback;
import de.rcenvironment.core.component.workflow.execution.headless.internal.HeadlessWorkflowExecutionServiceImpl;
import de.rcenvironment.core.component.workflow.update.api.PersistentWorkflowDescription;
import de.rcenvironment.core.component.workflow.update.api.PersistentWorkflowDescriptionUpdateService;
import de.rcenvironment.core.notification.DistributedNotificationService;
import de.rcenvironment.core.utils.common.TempFileServiceAccess;
import de.rcenvironment.core.utils.common.textstream.TextOutputReceiver;
import de.rcenvironment.core.utils.common.textstream.receivers.LoggingTextOutReceiver;
/**
* {@link WfCommandPlugin} test.
*
* @author Sascha Zur
* @author Jan Flink
* @author Robert Mischke
*/
public class WfCommandPluginTest {
private static final String MESSAGE_EXPECTED_COMMAND_EXCEPTION = "Expected command exception";
private static final String STRING_RUN = "run";
private static final String STRING_WF = "wf";
private static final Log LOGGER = LogFactory.getLog(WfCommandPluginTest.class);
private WfCommandPlugin wfCommandPlugin;
private HeadlessWorkflowExecutionServiceImpl workflowExecutionService;
/**
* Creates a Session for testing.
*/
@BeforeClass
public static void setUpBeforeClass() {
Session.create("dummyUser", 1);
TempFileServiceAccess.setupUnitTestEnvironment();
}
/**
* Common test setup.
*/
@Before
public void setUp() {
workflowExecutionService = new HeadlessWorkflowExecutionServiceImpl();
workflowExecutionService.bindWorkflowExecutionService(EasyMock.createNiceMock(WorkflowExecutionService.class));
workflowExecutionService.bindDistributedNotificationService(EasyMock.createNiceMock(DistributedNotificationService.class));
workflowExecutionService.bindPlatformService(EasyMock.createNiceMock(PlatformService.class));
wfCommandPlugin = new WfCommandPlugin();
wfCommandPlugin.bindWorkflowExecutionService(workflowExecutionService);
}
/**
* Test sending the "wf run" command without a filename token. The expected behaviour is an exception that signals a syntax error to the
* user
*/
@Test
public void testWFRunCommandWithoutFilename() {
List<String> tokens = new ArrayList<String>();
tokens.add(STRING_WF);
tokens.add(STRING_RUN);
TextOutputReceiver outputReceiver = EasyMock.createNiceMock(LoggingTextOutReceiver.class);
EasyMock.replay(outputReceiver);
// invoke
try {
wfCommandPlugin.execute(new CommandContext(tokens, outputReceiver, null));
fail("Exception expected");
} catch (CommandException e) {
// test exception parameter(s)
assertEquals("Unexpected CommandException sub-type", CommandException.Type.SYNTAX_ERROR, e.getType());
}
EasyMock.verify(outputReceiver);
}
/**
* Test sending the "wf run" command with an invalid filename token. The expected behaviour are response lines containing the words
* "not existent" and "failed" (case insensitive)
*
* @throws CommandException on unexpected command errors
*/
@Test
public void testWFRunCommandWithInvalidFilename() throws CommandException {
final String testFilename = "invalidFilename";
List<String> tokens = new ArrayList<String>();
tokens.add(STRING_WF);
tokens.add(STRING_RUN);
tokens.add(testFilename);
TextOutputReceiver outputReceiver = EasyMock.createNiceMock(LoggingTextOutReceiver.class);
// define mock expectation
Capture<String> capture = new Capture<String>(CaptureType.ALL);
outputReceiver.addOutput(EasyMock.capture(capture));
EasyMock.expectLastCall().anyTimes();
EasyMock.replay(outputReceiver);
// invoke
try {
wfCommandPlugin.execute(new CommandContext(tokens, outputReceiver, null));
fail(MESSAGE_EXPECTED_COMMAND_EXCEPTION);
} catch (CommandException e) {
assertEquals(Type.EXECUTION_ERROR, e.getType());
String message = e.getMessage();
assertTrue("Unexpected reponse text (should contain 'does not exist'): " + message, message.toLowerCase()
.contains("does not exist"));
assertTrue("Unexpected reponse text (should contain the test filename): " + message,
message.contains(testFilename));
}
// test callback parameter(s)
assertEquals("Expected no text output", 0, capture.getValues().size());
EasyMock.verify(outputReceiver);
}
/**
* Test sending the "wf run" command with an invalid file. The expected behaviour is a response line containing the words
* "loading workflow file failed" (case insensitive)
*
* @throws CommandException on unexpected command errors
* @throws WorkflowFileException on unexpected errors
*/
@Test
public void testWFRunCommandWithInvalidFile() throws CommandException, WorkflowFileException {
// create invalid workflow testfile
File dir = null;
File testfile = null;
try {
dir = TempFileServiceAccess.getInstance().createManagedTempDir();
testfile = new File(dir, "testfile.wf");
FileUtils.touch(testfile);
} catch (IOException e) {
LOGGER.error("", e);
}
Assert.assertNotNull(testfile);
Assert.assertTrue(testfile.exists());
Assert.assertTrue(testfile.isFile());
final String errorMessage = "failed";
WorkflowExecutionService wfExeService = EasyMock.createNiceMock(WorkflowExecutionService.class);
EasyMock.expect(wfExeService.loadWorkflowDescriptionFromFileConsideringUpdates(EasyMock.isA(File.class),
EasyMock.isA(HeadlessWorkflowDescriptionLoaderCallback.class))).andThrow(new WorkflowFileException(errorMessage)).anyTimes();
EasyMock.replay(wfExeService);
workflowExecutionService.bindWorkflowExecutionService(wfExeService);
List<String> tokens = new ArrayList<String>();
tokens.add(STRING_WF);
tokens.add(STRING_RUN);
tokens.add(testfile.getAbsolutePath());
TextOutputReceiver outputReceiver = EasyMock.createNiceMock(LoggingTextOutReceiver.class);
// define mock expectation
Capture<String> capture = new Capture<String>(CaptureType.ALL);
outputReceiver.addOutput(EasyMock.capture(capture));
EasyMock.expectLastCall().anyTimes();
EasyMock.replay(outputReceiver);
// invoke
wfCommandPlugin.execute(new CommandContext(tokens, outputReceiver, null));
// test callback parameter(s)
assertEquals(2, capture.getValues().size());
assertTrue(capture.getValues().get(0).contains(errorMessage));
assertTrue(capture.getValues().get(1).contains("not executed"));
EasyMock.verify(outputReceiver);
try {
TempFileServiceAccess.getInstance().disposeManagedTempDirOrFile(dir);
} catch (IOException e) {
LOGGER.error("", e);
}
}
/**
* FIXME: Not done yet.
*
* @throws CommandException on unexpected command errors
*/
@Test
public void testWFRunCommand() throws CommandException {
File dir = null;
File testfile = null;
try {
dir = TempFileServiceAccess.getInstance().createManagedTempDir();
testfile = new File(dir, "testfile.wf");
FileUtils.copyInputStreamToFile(WfCommandPluginTest.class
.getResourceAsStream("/workflows_automated_with_placeholders/Python.wf"), testfile);
} catch (IOException e) {
LOGGER.error("", e);
}
Assert.assertNotNull(testfile);
Assert.assertTrue(testfile.exists());
Assert.assertTrue(testfile.isFile());
PersistentWorkflowDescriptionUpdateService pwdUpdateServiceMock = EasyMock
.createNiceMock(PersistentWorkflowDescriptionUpdateService.class);
// define mock expectation
EasyMock
.expect(
pwdUpdateServiceMock.isUpdateForWorkflowDescriptionAvailable(EasyMock.anyObject(PersistentWorkflowDescription.class),
EasyMock.anyBoolean())).andReturn(false).anyTimes();
EasyMock.replay(pwdUpdateServiceMock);
List<String> tokens = new ArrayList<String>();
tokens.add(STRING_WF);
tokens.add(STRING_RUN);
tokens.add(" \"" + testfile.getAbsolutePath() + " \"");
TextOutputReceiver outputReceiver = EasyMock.createNiceMock(LoggingTextOutReceiver.class);
// define mock expectation
Capture<String> capture = new Capture<String>(CaptureType.ALL);
outputReceiver.addOutput(EasyMock.capture(capture));
EasyMock.expectLastCall().anyTimes();
EasyMock.replay(outputReceiver);
// invoke
try {
wfCommandPlugin.execute(new CommandContext(tokens, outputReceiver, null));
fail(MESSAGE_EXPECTED_COMMAND_EXCEPTION);
} catch (CommandException e) {
assertEquals(Type.EXECUTION_ERROR, e.getType());
}
// test callback parameter(s)
// String capturedText = capture.getValues().toString();
// assertTrue("Unexpected reponse text (should contain 'loading workflow file failed')",
// capturedText.toLowerCase().contains("loading workflow file failed"));
EasyMock.verify(outputReceiver);
try {
TempFileServiceAccess.getInstance().disposeManagedTempDirOrFile(dir);
} catch (IOException e) {
LOGGER.error("", e);
}
}
}