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

#488 Make Pramen more strict on successes and failures of pipelines. #533

Merged
merged 1 commit into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions pramen/core/src/main/resources/reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,10 @@ pramen {
# The maximum length of errors and exceptions in the notification body. The default value is selected
# so that Pramen can handle at least 100 exceptions in a single email notification.
exception.max.length = 65536

# If true, possible statuses are: Failed, Succeeded, and Succeeded with Warnings. "Partial success" is considered a failure.
# If false, possible statuses are: Failed, Paraially suceeded, Succeeded, and Succeeded with Warnings
strict.failures = true
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ object PipelineNotificationBuilderHtml {
val MIN_MEGABYTES = 10
val NOTIFICATION_REASON_MAX_LENGTH_KEY = "pramen.notifications.reason.max.length"
val NOTIFICATION_EXCEPTION_MAX_LENGTH_KEY = "pramen.notifications.exception.max.length"
val NOTIFICATION_STRICT_FAILURES_KEY = "pramen.notifications.strict.failures"
val SUPPRESS_WARNING_STARTING_WITH = "Based on outdated tables: "
}

Expand All @@ -58,6 +59,7 @@ class PipelineNotificationBuilderHtml(implicit conf: Config) extends PipelineNot

private val maxReasonLength = ConfigUtils.getOptionInt(conf, NOTIFICATION_REASON_MAX_LENGTH_KEY)
private val maxExceptionLength = ConfigUtils.getOptionInt(conf, NOTIFICATION_EXCEPTION_MAX_LENGTH_KEY)
private val strictFailures = ConfigUtils.getOptionBoolean(conf, NOTIFICATION_STRICT_FAILURES_KEY).getOrElse(true)

var appException: Option[Throwable] = None
var warningFlag: Boolean = false
Expand Down Expand Up @@ -182,15 +184,16 @@ class PipelineNotificationBuilderHtml(implicit conf: Config) extends PipelineNot
def pipelineStatus: PipelineStatus = {
val isCertainFailure = appException.nonEmpty
val (someTasksSucceeded, someTasksFailed) = getSuccessFlags
val hasAtLeastOneWarning = warningFlag || hasWarnings
val hasInvalidEmails = validatedEmailsOpt.exists(v => v.invalidDomainEmails.nonEmpty || v.invalidFormatEmails.nonEmpty)
val hasAtLeastOneWarning = warningFlag || hasWarnings || hasInvalidEmails

if (isCertainFailure) {
PipelineStatus.Failure
} else if (!someTasksFailed && !hasAtLeastOneWarning) {
PipelineStatus.Success
} else if (someTasksSucceeded && someTasksFailed) {
} else if (someTasksSucceeded && someTasksFailed && !strictFailures) {
PipelineStatus.PartialSuccess
} else if (someTasksSucceeded && hasAtLeastOneWarning) {
} else if (someTasksSucceeded && !someTasksFailed && hasAtLeastOneWarning) {
PipelineStatus.Warning
} else {
PipelineStatus.Failure
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,16 @@ class PipelineNotificationBuilderHtmlSuite extends AnyWordSpec with TextComparis

assert(builder.renderSubject().startsWith("Notification of PARTIAL SUCCESS for MyNewApp at"))
}

"render failure when strict failures are turned on" in {
val builder = getBuilder(structFailure = true)

builder.addAppName("MyNewApp")
builder.addCompletedTask(TaskResultFactory.getDummyTaskResult(runStatus = TestPrototypes.runStatusWarning))
builder.addCompletedTask(TaskResultFactory.getDummyTaskResult(runStatus = TestPrototypes.runStatusFailure))

assert(builder.renderSubject().startsWith("Notification of FAILURE for MyNewApp at"))
}
}

"renderBody()" should {
Expand Down Expand Up @@ -673,13 +683,16 @@ class PipelineNotificationBuilderHtmlSuite extends AnyWordSpec with TextComparis
}
}

def getBuilder(conf: Config = emptyConfig): PipelineNotificationBuilderHtml = {
def getBuilder(conf: Config = emptyConfig,
structFailure: Boolean = false): PipelineNotificationBuilderHtml = {
implicit val implicitConfig: Config =
conf.withFallback(
ConfigFactory.parseString(
"""pramen {
s"""pramen {
| application.version = 1.0.0
| timezone = "Africa/Johannesburg"
|
| notifications.strict.failures = $structFailure
|}
|""".stripMargin)
)
Expand Down
Loading