package com.github.jmchilton.blend4j.galaxy;
import static org.testng.AssertJUnit.*;
import com.github.jmchilton.blend4j.galaxy.beans.Workflow;
import com.github.jmchilton.blend4j.galaxy.beans.WorkflowDetails;
import com.github.jmchilton.blend4j.galaxy.beans.WorkflowInputDefinition;
import com.github.jmchilton.blend4j.galaxy.beans.WorkflowInputs;
import com.github.jmchilton.blend4j.galaxy.beans.WorkflowInputs.ExistingHistory;
import com.github.jmchilton.blend4j.galaxy.beans.WorkflowInputs.InputSourceType;
import com.github.jmchilton.blend4j.galaxy.beans.WorkflowInputs.WorkflowInput;
import com.github.jmchilton.blend4j.galaxy.beans.WorkflowOutputs;
import com.github.jmchilton.blend4j.galaxy.beans.WorkflowStepDefinition;
import com.github.jmchilton.blend4j.galaxy.beans.collection.request.CollectionDescription;
import com.github.jmchilton.blend4j.galaxy.beans.collection.request.HistoryDatasetElement;
import com.github.jmchilton.blend4j.galaxy.beans.collection.response.CollectionResponse;
import com.google.common.base.Charsets;
import com.google.common.io.Resources;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.UniformInterfaceException;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class WorkflowsTest {
private static final String TEST_WORKFLOW_NAME = "TestWorkflow1";
private static final String TEST_WORKFLOW_RANDOMLINES = "TestWorkflowRandomlines";
private static final String TEST_WORKFLOW_COLLECTION_LIST = "TestWorkflowCollectionList";
private GalaxyInstance instance;
private WorkflowsClient client;
private String testWorkflow1Contents;
@BeforeMethod
public void init() throws IOException {
instance = TestGalaxyInstance.get();
client = instance.getWorkflowsClient();
testWorkflow1Contents = Resources.asCharSource(getClass().getResource(TEST_WORKFLOW_NAME + ".ga"), Charsets.UTF_8).read();
}
private String ensureHasTestWorkflow1() {
return ensureHasWorkflow(TEST_WORKFLOW_NAME);
}
private String ensureHasWorkflow(final String workflowName) {
String workflowId = null;
for(Workflow workflow : client.getWorkflows()) {
if(workflow.getName().startsWith(workflowName)) {
workflowId = workflow.getId();
break;
}
}
if(workflowId == null) {
final String workflowContents;
try {
workflowContents = Resources.asCharSource(getClass().getResource(workflowName + ".ga"), Charsets.UTF_8).read();
} catch(IOException ex) {
throw new RuntimeException(ex);
}
client.importWorkflow(workflowContents);
workflowId = getTestWorkflowId(workflowName);
}
return workflowId;
}
/**
* Constructs a list collection from the given files within the given history.
* @param historyId The id of the history to build the collection within.
* @param inputIds The ids of the files to add to the collection.
* @return A CollectionResponse object for the constructed collection.
*/
private CollectionResponse constructFileCollectionList(String historyId, List<String> inputIds) {
HistoriesClient historiesClient = instance.getHistoriesClient();
CollectionDescription collectionDescription = new CollectionDescription();
collectionDescription.setCollectionType("list");
collectionDescription.setName("collection");
for (String inputId : inputIds) {
HistoryDatasetElement element = new HistoryDatasetElement();
element.setId(inputId);
element.setName(inputId);
collectionDescription.addDatasetElement(element);
}
return historiesClient.createDatasetCollection(historyId, collectionDescription);
}
/**
* Prepares a workflow which takes as input a collection list.
* @param inputSource The type of input source for this workflow.
* @return A WorkflowInputs describing the workflow.
* @throws InterruptedException
*/
private WorkflowInputs prepareWorkflowCollectionList(WorkflowInputs.InputSourceType inputSource)
throws InterruptedException {
String historyId = TestHelpers.getTestHistoryId(instance);
List<String> ids = TestHelpers.populateTestDatasets(instance, historyId, 2);
String workflowId = ensureHasWorkflow(TEST_WORKFLOW_COLLECTION_LIST);
CollectionResponse collectionResponse = constructFileCollectionList(historyId, ids);
Assert.assertNotNull(collectionResponse.getId());
WorkflowDetails workflowDetails = client.showWorkflow(workflowId);
Assert.assertNotNull(workflowDetails.getId());
String workflowInputId = getWorkflowInputId(workflowDetails, "input_list");
Assert.assertNotNull(workflowInputId);
WorkflowInputs workflowInputs = new WorkflowInputs();
workflowInputs.setDestination(new WorkflowInputs.ExistingHistory(historyId));
workflowInputs.setWorkflowId(workflowId);
workflowInputs.setInput(workflowInputId,
new WorkflowInputs.WorkflowInput(collectionResponse.getId(),
inputSource));
return workflowInputs;
}
/**
* Tests execution of a workflow on a list collection of files and passing.
* @throws InterruptedException
*/
@Test
public void testRunWorkflowCollectionListPass() throws InterruptedException {
WorkflowsClient workflowsClient = instance.getWorkflowsClient();
WorkflowInputs workflowInputs =
prepareWorkflowCollectionList(WorkflowInputs.InputSourceType.HDCA);
WorkflowOutputs outputs = workflowsClient.runWorkflow(workflowInputs);
Assert.assertNotNull(outputs);
Assert.assertNotNull(outputs.getOutputIds());
Assert.assertEquals(1, outputs.getOutputIds().size());
String outputId = outputs.getOutputIds().get(0);
Assert.assertNotNull(outputId);
}
/**
* Tests execution of a workflow on a list collection of files and failing.
* @throws InterruptedException
*/
@Test(expectedExceptions=GalaxyResponseException.class)
public void testRunWorkflowCollectionListFail() throws InterruptedException {
WorkflowsClient workflowsClient = instance.getWorkflowsClient();
WorkflowInputs workflowInputs =
prepareWorkflowCollectionList(WorkflowInputs.InputSourceType.HDA);
workflowsClient.runWorkflow(workflowInputs);
}
@Test
public void testExportWorkflow() {
ensureHasTestWorkflow1();
final String testWorkflowId = getTestWorkflowId();
final String workflowExported = client.exportWorkflow(testWorkflowId);
assert workflowExported.contains("a_galaxy_workflow");
}
@Test
public void testImportExportWorkflow() {
ensureHasTestWorkflow1();
final String testWorkflowId = getTestWorkflowId();
final String workflowJson = client.exportWorkflow(testWorkflowId);
final Workflow importedWorkflow = client.importWorkflow(workflowJson);
}
/**
* Given a WorkflowDetails object, and a label for an input to a workflow, finds the id for this input.
* @param workflowDetails The WorkflowDetails object.
* @param inputLabel The label for the input to search for.
* @return The corresponding id for the passed label.
*/
private String getWorkflowInputId(WorkflowDetails workflowDetails, String inputLabel) {
String workflowInputId = null;
for(final Map.Entry<String, WorkflowInputDefinition> inputEntry : workflowDetails.getInputs().entrySet()) {
final String label = inputEntry.getValue().getLabel();
if(label.equals(inputLabel)) {
workflowInputId = inputEntry.getKey();
}
}
return workflowInputId;
}
@Test
public void testRunWorkflow() throws IOException, InterruptedException {
// Find history
final String historyId = TestHelpers.getTestHistoryId(instance);
final List<String> ids = TestHelpers.populateTestDatasets(instance, historyId, 2);
final String input1Id = ids.get(0);
final String input2Id = ids.get(1);
final String testWorkflowId = getTestWorkflowId();
final WorkflowDetails workflowDetails = client.showWorkflow(testWorkflowId);
String workflowInput1Id = getWorkflowInputId(workflowDetails, "WorkflowInput1");
String workflowInput2Id = getWorkflowInputId(workflowDetails, "WorkflowInput2");
final WorkflowInputs inputs = new WorkflowInputs();
inputs.setDestination(new ExistingHistory(historyId));
inputs.setWorkflowId(testWorkflowId);
inputs.setInput(workflowInput1Id, new WorkflowInput(input1Id, InputSourceType.HDA));
inputs.setInput(workflowInput2Id, new WorkflowInput(input2Id, InputSourceType.HDA));
final WorkflowOutputs output = client.runWorkflow(inputs);
System.out.println("Running workflow in history " + output.getHistoryId());
for(final String outputId : output.getOutputIds()) {
System.out.println(" Workflow Output ID " + outputId);
}
}
@Test
public void testWorkflowToolParameter() throws InterruptedException {
final WorkflowInputs inputs = prepParameterTest();
inputs.setToolParameter("random_lines1", "num_lines", 5);
final WorkflowOutputs output = client.runWorkflow(inputs);
// TODO: Verify outputs...
}
@Test
public void testWorkflowStepParameter() throws InterruptedException {
final WorkflowInputs inputs = prepParameterTest();
final WorkflowDetails workflowDetails = client.showWorkflow(inputs.getWorkflowId());
workflowDetails.getInputs();
String firstStepId = null, secondStepId = null;
for(final Map.Entry<String, WorkflowStepDefinition> entry : workflowDetails.getSteps().entrySet()) {
final String stepId = entry.getKey();
final WorkflowStepDefinition stepDef = entry.getValue();
if(!stepDef.getType().equals("tool")) {
continue;
}
boolean firstStep = true;
for(final Map.Entry<String, WorkflowStepDefinition.WorkflowStepOutput> stepInput : stepDef.getInputSteps().entrySet()) {
if(stepInput.getValue().getStepOutput().equals("out_file1")) {
// Has an input from random lines tool, is second step...
firstStep = false;
}
}
if(firstStep) {
firstStepId = stepId;
} else {
secondStepId = stepId;
}
}
inputs.setStepParameter(firstStepId, "num_lines", 7);
inputs.setStepParameter(secondStepId, "num_lines", 3);
final WorkflowOutputs output = client.runWorkflow(inputs);
// TODO: Verify outputs...
}
/**
* Tests successfully deleting a workflow.
*/
@Test
public void deleteWorkflowRequestSuccess() {
Workflow workflow = client.importWorkflow(testWorkflow1Contents);
WorkflowDetails workflowDetails = client.showWorkflow(workflow.getId());
assert !workflowDetails.isDeleted() : "Workflow is deleted";
client.deleteWorkflowRequest(workflow.getId());
workflowDetails = client.showWorkflow(workflow.getId());
assert workflowDetails.isDeleted() : "Workflow is not deleted";
}
/**
* Tests failing to deleting an invalid workflow.
*/
@Test
public void deleteWorkflowRequestFail() {
Workflow workflow = client.importWorkflow(testWorkflow1Contents);
try {
client.showWorkflow("invalid");
fail("The invalid workflow above exists");
} catch (UniformInterfaceException e) {
assert 400 == e.getResponse().getStatus() : "Invalid status code";
}
try {
client.deleteWorkflowRequest(workflow.getId());
} catch (UniformInterfaceException e) {
assert 400 == e.getResponse().getStatus() : "Invalid status code";
}
}
private WorkflowInputs prepParameterTest() throws InterruptedException {
final String historyId = TestHelpers.getTestHistoryId(instance);
final String testContents = "1\n2\n3\n4\n5\n6\n7\n8\n9\n10";
final String datasetId = TestHelpers.populateTestDataset(this.instance, historyId, testContents);
final String testWorkflowId = ensureHasWorkflow(TEST_WORKFLOW_RANDOMLINES);
final WorkflowDetails workflowDetails = client.showWorkflow(testWorkflowId);
final WorkflowInputs inputs = new WorkflowInputs();
inputs.setDestination(new ExistingHistory(historyId));
inputs.setWorkflowId(testWorkflowId);
final String inputId = workflowDetails.getInputs().keySet().iterator().next();
inputs.setInput(inputId, new WorkflowInput(datasetId, InputSourceType.HDA));
return inputs;
}
private String getTestWorkflowId() {
return getTestWorkflowId(TEST_WORKFLOW_NAME);
}
private String getTestWorkflowId(final String name) {
Workflow matchingWorkflow = null;
for(Workflow workflow : client.getWorkflows()) {
if(workflow.getName().startsWith(name)) {
matchingWorkflow = workflow;
}
}
return matchingWorkflow.getId();
}
}