Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bw 1126 workflow stdout stderr #6748

Merged
merged 48 commits into from
May 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
40f7696
bad stdout location tests
cjllanwarne Mar 1, 2022
50c87e2
Merge branch 'cjl_bad_stdout_location_tests' of github.com:broadinsti…
kpierre13 Apr 1, 2022
1048541
just a draft
kpierre13 Apr 4, 2022
3733cd8
checkStdout helper function
salonishah11 Apr 4, 2022
5c41251
Adding stderr wdl and test files, refactoring functions and adding fu…
kpierre13 Apr 14, 2022
ef48af4
Fixing error messages
kpierre13 Apr 14, 2022
db173f6
bad stdout location tests
cjllanwarne Mar 1, 2022
c874b8f
just a draft
kpierre13 Apr 4, 2022
8707f50
checkStdout helper function
salonishah11 Apr 4, 2022
4a6583d
Adding stderr wdl and test files, refactoring functions and adding fu…
kpierre13 Apr 14, 2022
cd3e399
Fixing error messages
kpierre13 Apr 14, 2022
ce37aa7
Rebasing
kpierre13 Apr 14, 2022
33431d3
Merge branch 'KP_BW-1126' of github.com:broadinstitute/cromwell into …
kpierre13 Apr 14, 2022
f7ce919
Rebasing
kpierre13 Apr 14, 2022
18a9016
Omitting the metadata section for Travis builds to pass
kpierre13 Apr 15, 2022
40ce41a
Bw 1126 workflow level stdout / stderr expressions fail, hang executi…
kpierre13 Apr 27, 2022
33cbb59
Update wdl/transforms/draft3/src/test/scala/AstToWorkflowDefinitionEl…
kpierre13 Apr 27, 2022
5eecccf
Update wdl/transforms/draft3/src/test/scala/AstToWorkflowDefinitionEl…
kpierre13 Apr 27, 2022
f1e23d9
Update wdl/transforms/draft3/src/test/scala/AstToWorkflowDefinitionEl…
kpierre13 Apr 27, 2022
72c8d97
Update wdl/transforms/draft3/src/test/scala/AstToWorkflowDefinitionEl…
kpierre13 Apr 27, 2022
251bfb6
Changing to more general function naming
kpierre13 Apr 27, 2022
62c134b
Return type change for functions
kpierre13 Apr 27, 2022
4040fe5
Reverting Saloni newline addition
kpierre13 Apr 27, 2022
7bf1774
Reverting Saloni newline addition and fixing return type
kpierre13 Apr 27, 2022
b40766a
bad stdout location tests
cjllanwarne Mar 1, 2022
2b531bc
just a draft
kpierre13 Apr 4, 2022
7f08501
checkStdout helper function
salonishah11 Apr 4, 2022
7d64dc7
Adding stderr wdl and test files, refactoring functions and adding fu…
kpierre13 Apr 14, 2022
d85569f
Fixing error messages
kpierre13 Apr 14, 2022
b55cf3d
Rebasing
kpierre13 Apr 14, 2022
f3bc4f9
Omitting the metadata section for Travis builds to pass
kpierre13 Apr 15, 2022
eaf281e
Bw 1126 workflow level stdout / stderr expressions fail, hang executi…
kpierre13 Apr 27, 2022
f67be32
Update wdl/transforms/draft3/src/test/scala/AstToWorkflowDefinitionEl…
kpierre13 Apr 27, 2022
6b662e1
Update wdl/transforms/draft3/src/test/scala/AstToWorkflowDefinitionEl…
kpierre13 Apr 27, 2022
1f61100
Update wdl/transforms/draft3/src/test/scala/AstToWorkflowDefinitionEl…
kpierre13 Apr 27, 2022
6ba58e0
Update wdl/transforms/draft3/src/test/scala/AstToWorkflowDefinitionEl…
kpierre13 Apr 27, 2022
0b8d3fe
Changing to more general function naming
kpierre13 Apr 27, 2022
775a51f
Return type change for functions
kpierre13 Apr 27, 2022
63a31ae
Reverting Saloni newline addition
kpierre13 Apr 27, 2022
858214d
Reverting Saloni newline addition and fixing return type
kpierre13 Apr 27, 2022
028d1f7
Merge remote-tracking branch 'origin/KP_BW-1126' into KP_BW-1126
kpierre13 Apr 28, 2022
d2ef485
Revert "Reverting Saloni newline addition and fixing return type"
kpierre13 Apr 28, 2022
7821d38
Reverting Saloni newline addition and fixing return type
kpierre13 Apr 27, 2022
8e75ea8
remove_tests
kpierre13 Apr 29, 2022
f5e54f1
remove_corresponding_wdl_files
kpierre13 Apr 29, 2022
2c91101
Updating some unit tests with more correct functionality
kpierre13 Apr 30, 2022
5a59a7b
Fixing missed input for Invalid function
kpierre13 Apr 30, 2022
a19b33d
triggering build
kpierre13 Apr 30, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import cats.data.Validated._
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers._
import wdl.model.draft3.elements.ExpressionElement._
import wdl.model.draft3.elements.{InputDeclarationElement, InputsSectionElement, IntermediateValueDeclarationElement, OutputDeclarationElement, OutputsSectionElement, PrimitiveTypeElement}
import wom.types.{WomSingleFileType, WomStringType}
import wdl.transforms.base.ast2wdlom.AstToWorkflowDefinitionElement._


class AstToWorkflowDefinitionElementSpec extends AnyFlatSpec{
behavior of "Check Stdouts and Stderrs"

val mockInputSectionStdout = Option(InputsSectionElement(Vector(InputDeclarationElement(PrimitiveTypeElement(WomSingleFileType), "i", Some(StdoutElement)))))
val mockInputSectionStderr = Option(InputsSectionElement(Vector(InputDeclarationElement(PrimitiveTypeElement(WomSingleFileType), "i", Some(StderrElement)))))
val mockInputSectionNonStd = Option(InputsSectionElement(Vector(InputDeclarationElement(PrimitiveTypeElement(WomStringType), "more", Some(StringLiteral("more"))))))


val mockIntermediatesStdout = Vector(IntermediateValueDeclarationElement(PrimitiveTypeElement(WomSingleFileType), "y", StdoutElement))
val mockIntermediatesStderr = Vector(IntermediateValueDeclarationElement(PrimitiveTypeElement(WomSingleFileType), "y", StderrElement))
val mockIntermediatesNonStd = Vector(IntermediateValueDeclarationElement(PrimitiveTypeElement(WomStringType), "here", StringLiteral("here")))

val mockOutputSectionStdout = Option(OutputsSectionElement(Vector(OutputDeclarationElement(PrimitiveTypeElement(WomSingleFileType), "s", StdoutElement))))
val mockOutputSectionStderr = Option(OutputsSectionElement(Vector(OutputDeclarationElement(PrimitiveTypeElement(WomSingleFileType), "s", StderrElement))))
val mockOutputSectionNonStd = Option(OutputsSectionElement(Vector(OutputDeclarationElement(PrimitiveTypeElement(WomStringType), "more", StringLiteral("more")))))


it should "return an error when there is an stdout in input section" in {
val testInputs = checkDisallowedInputElement(mockInputSectionStdout, StdoutElement, "stdout")
testInputs match {
case Valid(_) => fail("Input section contained stdout. Should have failed.")
case Invalid(e) => e.head should be("Workflow cannot have stdout expression in input section at workflow-level.")
}
}

it should "return an error when there is an stderr in input section" in {
val testInputs = checkDisallowedInputElement(mockInputSectionStderr, StderrElement, "stderr")
testInputs match {
case Valid(_) => fail("Input section contained stderr. Should have failed.")
case Invalid(e) => e.head should be("Workflow cannot have stderr expression in input section at workflow-level.")
}
}

it should "not return an error for non-stdout/stderr in the inputs section" in {
val testInputs = checkDisallowedInputElement(mockInputSectionNonStd, StdoutElement, "non-stdout/stderr")
testInputs match {
case Valid(_) => // No action
case Invalid(_) => fail("Check shouldn't have returned error as input section had non-stdout/stderr inputs")
}
}

it should "return an error when there is an stdout in output section" in {
val testOutputs = checkDisallowedOutputElement(mockOutputSectionStdout, StdoutElement, "stdout")
testOutputs match {
case Valid(_) => fail("Output section contained stdout. Should have failed.")
case Invalid(e) => e.head should be("Workflow cannot have stdout expression in output section at workflow-level.")
}
}

it should "return an error when there is an stderr in output section" in {
val testOutputs = checkDisallowedOutputElement(mockOutputSectionStderr, StderrElement, "stderr")
testOutputs match {
case Valid(_) => fail("Output section contained stderr. Should have failed.")
case Invalid(e) => e.head should be("Workflow cannot have stderr expression in output section at workflow-level.")
}
}
it should "not return an error for non-stdout/stderr in the outputs section" in {
val testOutputs = checkDisallowedOutputElement(mockOutputSectionNonStd, StdoutElement, "non-stdout/stderr")
testOutputs match {
case Valid(_) => // No action
case Invalid(_) => fail("Check shouldn't have returned error as output section had non-stdout/stderr outputs")
}
}

it should "return an error when there is an stdout at intermediate declaration section" in {
val testIntermediates = checkDisallowedIntermediates(mockIntermediatesStdout, StdoutElement, "stdout")
testIntermediates match {
case Valid(_) => fail("Intermediate section contained stdout. Should have failed.")
case Invalid(e) => e.head should be("Workflow cannot have stdout expression at intermediate declaration section at workflow-level.")
}
}
it should "return an error when there is an stderr at intermediate declaration section" in {
val testIntermediates = checkDisallowedIntermediates(mockIntermediatesStderr, StderrElement, "stderr")
testIntermediates match {
case Valid(_) => fail("Intermediate section contained stderr. Should have failed.")
case Invalid(e) => e.head should be("Workflow cannot have stderr expression at intermediate declaration section at workflow-level.")
}
}

it should "not return an error for non-stdout/stderr in the intermediates section" in {
val testIntermediates = checkDisallowedIntermediates(mockIntermediatesNonStd, StdoutElement, "non-stdout/stderr")
testIntermediates match {
case Valid(_) => // No action
case Invalid(_) => fail("Check shouldn't have returned error as intermediate section had non-stdout/stderr intermediates.")
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import common.transforms.CheckedAtoB
import common.validation.ErrorOr._
import wdl.model.draft3.elements._
import wom.SourceFileLocation
import wdl.model.draft3.elements.ExpressionElement._

object AstToWorkflowDefinitionElement {

Expand All @@ -26,26 +27,65 @@ object AstToWorkflowDefinitionElement {
sourceLocation: Option[SourceFileLocation],
bodyElements: Vector[WorkflowBodyElement]) = {

val inputsSectionValidation: ErrorOr[Option[InputsSectionElement]] = validateSize(bodyElements.filterByType[InputsSectionElement], "inputs", 1)
val outputsSectionValidation: ErrorOr[Option[OutputsSectionElement]] = validateSize(bodyElements.filterByType[OutputsSectionElement], "outputs", 1)
val inputsSectionValidation: ErrorOr[Option[InputsSectionElement]] = for {
inputValidateElement <- validateSize(bodyElements.filterByType[InputsSectionElement], "inputs", 1): ErrorOr[Option[InputsSectionElement]]
_ <- checkDisallowedInputElement(inputValidateElement, StdoutElement, "stdout")
_ <- checkDisallowedInputElement(inputValidateElement, StderrElement, "stderr")
} yield inputValidateElement

val intermediateValueDeclarationStdoutCheck = checkDisallowedIntermediates(bodyElements.filterByType[IntermediateValueDeclarationElement], StdoutElement, "stdout")
val intermediateValueDeclarationStderrCheck = checkDisallowedIntermediates(bodyElements.filterByType[IntermediateValueDeclarationElement], StderrElement, "stderr")

val outputsSectionValidation: ErrorOr[Option[OutputsSectionElement]] = for {
outputValidateElement <- validateSize(bodyElements.filterByType[OutputsSectionElement], "outputs", 1): ErrorOr[Option[OutputsSectionElement]]
_ <- checkDisallowedOutputElement(outputValidateElement, StdoutElement, "stdout")
_ <- checkDisallowedOutputElement(outputValidateElement, StderrElement, "stderr")
} yield outputValidateElement

val graphSections: Vector[WorkflowGraphElement] = bodyElements.filterByType[WorkflowGraphElement]

val metaSectionValidation: ErrorOr[Option[MetaSectionElement]] = validateSize(bodyElements.filterByType[MetaSectionElement], "meta", 1)
val parameterMetaSectionValidation: ErrorOr[Option[ParameterMetaSectionElement]] = validateSize(bodyElements.filterByType[ParameterMetaSectionElement], "parameterMeta", 1)

(inputsSectionValidation, outputsSectionValidation, metaSectionValidation, parameterMetaSectionValidation) mapN {
(validInputs, validOutputs, meta, parameterMeta) =>
(inputsSectionValidation, outputsSectionValidation, metaSectionValidation, parameterMetaSectionValidation, intermediateValueDeclarationStdoutCheck, intermediateValueDeclarationStderrCheck) mapN {
(validInputs, validOutputs, meta, parameterMeta, _, _) =>
WorkflowDefinitionElement(name, validInputs, graphSections.toSet, validOutputs, meta, parameterMeta, sourceLocation)
}
}

def checkDisallowedInputElement(inputSection: Option[InputsSectionElement], expressionType: FunctionCallElement, expressionName: String): ErrorOr[Unit] = {
inputSection match {
case Some(section) =>
if (section.inputDeclarations.flatMap(_.expression).exists(_.isInstanceOf[expressionType.type])) {
s"Workflow cannot have $expressionName expression in input section at workflow-level.".invalidNel
} else ().validNel
case None => ().validNel
}
}

def checkDisallowedOutputElement(outputSection: Option[OutputsSectionElement], expressionType: FunctionCallElement, expressionName: String): ErrorOr[Unit] = {
outputSection match {
case Some(section) =>
if (section.outputs.map(_.expression).exists(_.isInstanceOf[expressionType.type])) {
s"Workflow cannot have $expressionName expression in output section at workflow-level.".invalidNel
} else ().validNel
case None => ().validNel
}
}

def checkDisallowedIntermediates(intermediate: Vector[IntermediateValueDeclarationElement], expressionType: FunctionCallElement, expressionName: String): ErrorOr[Unit] = {
if (intermediate.map(_.expression).exists(_.isInstanceOf[expressionType.type])) {
s"Workflow cannot have $expressionName expression at intermediate declaration section at workflow-level.".invalidNel
} else ().validNel
}

private def validateSize[A](elements: Vector[A], sectionName: String, numExpected: Int): ErrorOr[Option[A]] = {
val sectionValidation: ErrorOr[Option[A]] = if (elements.size > numExpected) {
s"Workflow cannot have more than $numExpected $sectionName sections, found ${elements.size}.".invalidNel
} else {
elements.headOption.validNel
}

sectionValidation
}
}
}