Skip to content

Commit

Permalink
switch to cost range
Browse files Browse the repository at this point in the history
  • Loading branch information
lucymcnatt committed Feb 8, 2025
1 parent 0205711 commit a459a7a
Show file tree
Hide file tree
Showing 9 changed files with 30 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ metadata {
status: Succeeded
}

cost: 0.0016
cost: [0.0017, 0.0015]
15 changes: 7 additions & 8 deletions centaur/src/main/scala/centaur/test/Test.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1061,22 +1061,21 @@ object Operations extends StrictLogging {
}
}

def getExpectedCost(workflowCost: Option[BigDecimal]): IO[BigDecimal] =
def getExpectedCost(workflowCost: Option[List[BigDecimal]]): IO[List[BigDecimal]] =
workflowCost match {
case Some(cost) if cost == 0 => IO.raiseError(new Exception("Expected cost cannot be 0"))
case Some(cost) if cost(0) > cost(1) => IO.raiseError(new Exception(s"Lower bound of expected cost cannot be higher than the upper bound (${cost(0)} - ${cost(1)})"))
case Some(cost) => IO.pure(cost)
case None =>
IO.raiseError(new Exception("Expected 'cost' is required in the test config to validate the workflow cost"))
IO.raiseError(new Exception("Expected cost range is required in the test config to validate the workflow cost"))
}

/**
* Validate that the actual cost is within 10% of the expected cost
* Validate that the actual cost is within the expected range
*/
def validateCost(actualCost: BigDecimal, expectedCost: BigDecimal): IO[Unit] = {
val costDiff = (actualCost - expectedCost).abs / expectedCost
if (costDiff > 0.1) {
def validateCost(actualCost: BigDecimal, expectedCost: List[BigDecimal]): IO[Unit] = {
if (expectedCost(0) > actualCost || actualCost > expectedCost(1)) {
IO.raiseError(
new Exception(s"Expected cost $expectedCost but got $actualCost, which is outside the 10% threshold")
new Exception(s"Expected cost within range ${expectedCost(0)} - ${expectedCost(1)} but got $actualCost")
)
} else {
IO.unit
Expand Down
19 changes: 0 additions & 19 deletions centaur/src/main/scala/centaur/test/formulas/TestFormulas.scala
Original file line number Diff line number Diff line change
Expand Up @@ -113,25 +113,6 @@ object TestFormulas extends StrictLogging {
_ <- validateDirectoryContentsCounts(workflowDefinition, submittedWorkflow, metadata)
} yield SubmitResponse(submittedWorkflow)

def runWorkflowTwiceAndCache(
workflowDefinition: Workflow
)(implicit cromwellTracker: Option[CromwellTracker]): Test[SubmittedWorkflow] =
for {
_ <- checkDescription(workflowDefinition, validityExpectation = Option(true))
_ <- timingVerificationNotSupported(workflowDefinition.maximumAllowedTime)
firstWF <- runSuccessfulWorkflow(workflowDefinition)
secondWf <- runSuccessfulWorkflow(workflowDefinition.secondRun)
_ <- printHashDifferential(firstWF, secondWf)
metadata <- fetchAndValidateNonSubworkflowMetadata(secondWf, workflowDefinition, Option(firstWF.id.id))
_ <- fetchAndValidateJobManagerStyleMetadata(secondWf,
workflowDefinition,
prefetchedOriginalNonSubWorkflowMetadata = None
)
_ = cromwellTracker.track(metadata)
_ <- validateNoCacheMisses(secondWf, metadata, workflowDefinition)
_ <- validateDirectoryContentsCounts(workflowDefinition, secondWf, metadata)
} yield secondWf

def runWorkflowTwiceExpectingCaching(
workflowDefinition: Workflow,
checkCost: Boolean = false
Expand Down
4 changes: 2 additions & 2 deletions centaur/src/main/scala/centaur/test/workflow/Workflow.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ final case class Workflow private (testName: String,
skipDescribeEndpointValidation: Boolean,
submittedWorkflowTracker: SubmittedWorkflowTracker,
maximumAllowedTime: Option[FiniteDuration],
cost: Option[BigDecimal] = None
cost: Option[List[BigDecimal]] = None
) {

def toWorkflowSubmission: WorkflowSingleSubmission = WorkflowSingleSubmission(
Expand Down Expand Up @@ -95,7 +95,7 @@ object Workflow {
val validateDescription: Boolean = conf.get[Boolean]("skipDescribeEndpointValidation").valueOrElse(false)

val maximumTime: Option[FiniteDuration] = conf.get[Option[FiniteDuration]]("maximumTime").value
val cost: Option[BigDecimal] = conf.get[Option[BigDecimal]]("cost").value
val cost: Option[List[BigDecimal]] = conf.get[Option[List[BigDecimal]]]("cost").value

(files, directoryContentCheckValidation, metadata, retryTestFailuresErrorOr) mapN {
(f, d, m, retryTestFailures) =>
Expand Down
8 changes: 4 additions & 4 deletions docs/developers/Centaur.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ metadata {
"failures.0.causedBy": "BetweenKeyboardAndChairException"
}
// Optional, the expected cost of running the workflow
cost: 0.0000
// Optional, the expected cost range of running the workflow
cost:[ 0.0000, 0.0001 ]
filesystemcheck: "local" // possible values: "local", "gcs". Used in conjunction with outputExpectations to define files we expect to exist after running this workflow.
outputExpectations: {
Expand Down Expand Up @@ -110,8 +110,8 @@ In case the absolute path the cromwell root is used (for example: `/home/my_user
In case testing of the caching is required `<<CACHE_HIT_UUID>>` can be used.
The testFormat should be `runtwiceexpectingcallcaching`. To verify that the cost is 0 when using call-caching the testFormat should be `runtwiceexpectingcallcachingnocost`

The cost is optional. If supplied, Centaur will retrieve the cost of the successfully completed workflow and compare it to the cost supplied.
The expected range is within 10% of the estimated cost. If evaluating the cost, the test format must be `WorkflowSuccessAndVerifyCost` and the call-caching option must be disabled for that test (example can be found in the `recursive_imports_cost.test`)
The cost is optional. If supplied, Centaur will retrieve the cost of the successfully completed workflow and compare it to the cost range supplied.
If evaluating the cost, the test format must be `WorkflowSuccessAndVerifyCost` and the call-caching option must be disabled for that test (example can be found in the `recursive_imports_cost.test`)


## Centaur Test Types
Expand Down
8 changes: 4 additions & 4 deletions src/ci/resources/build_application.inc.conf
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ services.MetadataService.config.metadata-write-statistics {
sub-workflow-bundling = true
}

services.GcpCostCatalogService.config {
enabled = true
catalogExpirySeconds = 86400
}
services.GcpCostCatalogService.config {
enabled = true
catalogExpirySeconds = 86400
}

# Make the shutdown timeout conspicuously long, so that if it hangs, it is an obvious problem in CI.
# See https://github.com/broadinstitute/cromwell/issues/2575
Expand Down
7 changes: 4 additions & 3 deletions src/ci/resources/gcp_batch_application.inc.conf.ctmpl
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,10 @@ services {
}
GcpCostCatalogService {
class = "cromwell.services.cost.GcpCostCatalogService"
config {
enabled = true
catalogExpirySeconds = 86400
config {
enabled = true
catalogExpirySeconds = 86400
}
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/ci/resources/papi_application.inc.conf.ctmpl
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ services {
google-auth-name = "service_account"
}
}
GcpCostCatalogService {
class = "cromwell.services.cost.GcpCostCatalogService"
config {
enabled = true
catalogExpirySeconds = 86400
}
}
}

filesystems.drs.global.config.resolver.url = "https://drshub.dsde-dev.broadinstitute.org/api/v4/drs/resolve"
Expand Down
2 changes: 1 addition & 1 deletion src/ci/resources/papi_v2beta_application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ services {
# metadata does not convert non-Strings to Strings since that key will always contain boolean values.
metadata-keys-to-sanitize-utf8mb4 = ["submittedFiles:workflow", "commandLine", "outputs:metadata_type_validation.validate_boolean.boolean_output"]
}
GcpCostCatalogService.config {
GcpCostCatalogService {
enabled = true
catalogExpirySeconds = 86400
}
Expand Down

0 comments on commit a459a7a

Please sign in to comment.