Skip to content

Commit

Permalink
[TH2-4316] Add additional events to the root event with information a…
Browse files Browse the repository at this point in the history
…bout the cause of failure
  • Loading branch information
OptimumCode committed May 31, 2023
1 parent 8606a0d commit 2dc6311
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 5 deletions.
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -229,13 +229,13 @@ test {
}

application {
mainClassName 'com.exactpro.th2.check1.Check1Main'
mainClass.set('com.exactpro.th2.check1.Check1Main')
}

applicationName = 'service'

distTar {
archiveName "${applicationName}.tar"
archiveFileName.set("${applicationName}.tar")
}

dockerPrepare {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ import java.util.concurrent.ForkJoinPool
import java.util.concurrent.TimeUnit.MILLISECONDS
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicReference
import com.exactpro.th2.common.util.toInstant

/**
* Implements common logic for check task.
Expand Down Expand Up @@ -170,7 +171,7 @@ abstract class AbstractCheckTask(
super.onError(e)

refs.rootEvent.status(FAILED)
.bodyData(EventUtils.createMessageBean(e.message))
.exception(e, true)
end(State.ERROR, "Error ${e.message} received in message stream")
}

Expand Down Expand Up @@ -424,6 +425,9 @@ abstract class AbstractCheckTask(

protected open val skipPublication: Boolean = false

protected open val errorEventOnTimeout: Boolean
get() = true

protected fun isCheckpointLastReceivedMessage(): Boolean = bufferContainsStartMessage && !hasMessagesInTimeoutInterval

/**
Expand Down Expand Up @@ -466,6 +470,9 @@ abstract class AbstractCheckTask(
private fun completeEventOrReportError(prevState: State): Boolean {
return try {
if (started) {
if (errorEventOnTimeout && prevState in TIMEOUT_STATES) {
addTimeoutEvent(prevState)
}
completeEvent(prevState)
doAfterCompleteEvent()
false
Expand All @@ -489,6 +496,36 @@ abstract class AbstractCheckTask(
}
}

private fun addTimeoutEvent(timeoutType: State) {
refs.rootEvent.addSubEventWithSamePeriod()
.status(FAILED)
.type(
when (timeoutType) {
State.TIMEOUT -> "CheckTimeoutInterrupted"
State.MESSAGE_TIMEOUT -> "CheckMessageTimeoutInterrupted"
else -> error("unexpected timeout state: $timeoutType")
}
).name("Check task was interrupter because of ${timeoutType.name.lowercase()}")
.bodyData(
EventUtils.createMessageBean(
when (timeoutType) {
State.TIMEOUT ->
"Check task was interrupted because the task execution took longer than ${taskTimeout.timeout} mls. " +
"It might be caused by the lack of the memory or CPU resources. Check the component resources consumption"
State.MESSAGE_TIMEOUT ->
"Check task was interrupted because the timestamp on the last processed message exceeds the message timeout. " +
(checkpointTimeout
?.toInstant()
?.let {
"Rule expects messages between $it and ${it.plusMillis(taskTimeout.messageTimeout)} " +
"but processed one outside this range. Check the attached messages."
} ?: "But the message timeout is not specified. Contact the developers.")
else -> error("unexpected timeout state: $timeoutType")
}
)
)
}

private fun configureRootEvent() {
refs.rootEvent.name(name()).type(type())
setup(refs.rootEvent)
Expand Down Expand Up @@ -585,6 +622,7 @@ abstract class AbstractCheckTask(
private val RESPONSE_EXECUTOR = ForkJoinPool.commonPool()
@JvmField
val CONVERTER = ProtoToIMessageConverter(VerificationUtil.FACTORY_PROXY, null, null, createParameters().setUseMarkerForNullsInMessage(true))
private val TIMEOUT_STATES: Set<State> = setOf(State.TIMEOUT, State.MESSAGE_TIMEOUT)
val EMPTY_STATUS_CONSUMER: (EventStatus) -> Unit = {}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ class NoMessageCheckTask(

override fun type(): String = "noMessageCheck"

override val errorEventOnTimeout: Boolean
get() = false

override fun setup(rootEvent: Event) {
rootEvent.bodyData(EventUtils.createMessageBean("No message check rule for messages from ${sessionKey.run { "$sessionAlias ($direction direction)" }}"))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ class SilenceCheckTask(
}
}

override val errorEventOnTimeout: Boolean
get() = false

override fun name(): String = "AutoSilenceCheck"

override fun type(): String = "AutoSilenceCheck"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -538,8 +538,8 @@ internal class TestCheckRuleTask : AbstractCheckTaskTest() {

val eventBatches = awaitEventBatchRequest(1000L, 2)
val eventList = eventBatches.flatMap(EventBatch::getEventsList)
assertEquals(3, eventList.size)
assertEquals(2, eventList.filter { it.status == FAILED }.size)
assertEquals(4, eventList.size)
assertEquals(3, eventList.filter { it.status == FAILED }.size)
}

@Test
Expand Down

0 comments on commit 2dc6311

Please sign in to comment.