fc7b879891
- fixed the tool overlay in tui. - fixed tool calling - added schemas. - getting all sessionIds via event store. - instead of sending all events on the replay - there's a new way for replaying. - session snapshot is now a thing getting sent for previously created sessions. - added logging to important parts. - revert workflowId from WorkflowCompletedEvent.
148 lines
5.4 KiB
Kotlin
148 lines
5.4 KiB
Kotlin
import com.correx.core.events.events.OrchestrationPausedEvent
|
|
import com.correx.core.events.events.OrchestrationResumedEvent
|
|
import com.correx.core.events.events.RetryAttemptedEvent
|
|
import com.correx.core.events.events.WorkflowCompletedEvent
|
|
import com.correx.core.events.events.WorkflowFailedEvent
|
|
import com.correx.core.events.events.WorkflowStartedEvent
|
|
import com.correx.core.events.orchestration.OrchestrationState
|
|
import com.correx.core.events.orchestration.OrchestrationStatus
|
|
import com.correx.core.events.types.SessionId
|
|
import com.correx.core.events.types.StageId
|
|
import com.correx.core.kernel.orchestration.DefaultOrchestrationReducer
|
|
import com.correx.testing.fixtures.EventFixtures.stored
|
|
import org.junit.jupiter.api.Assertions.assertEquals
|
|
import org.junit.jupiter.api.Assertions.assertFalse
|
|
import org.junit.jupiter.api.Assertions.assertNull
|
|
import org.junit.jupiter.api.Assertions.assertTrue
|
|
import org.junit.jupiter.api.Test
|
|
|
|
class OrchestrationReducerTest {
|
|
|
|
private val reducer = DefaultOrchestrationReducer()
|
|
private val sessionId = SessionId("s1")
|
|
private val stageId = StageId("stage-1")
|
|
private val workflowId = "workflow-test"
|
|
private val state = OrchestrationState(workflowId, stageId)
|
|
|
|
@Test
|
|
fun `WorkflowStartedEvent sets status to RUNNING`() {
|
|
val state = reducer.reduce(
|
|
state,
|
|
stored(payload = WorkflowStartedEvent(sessionId, workflowId, stageId)),
|
|
)
|
|
assertEquals(OrchestrationStatus.RUNNING, state.status)
|
|
assertEquals(stageId, state.currentStageId)
|
|
}
|
|
|
|
@Test
|
|
fun `WorkflowFailedEvent sets status to FAILED and failure reason`() {
|
|
val started = reducer.reduce(
|
|
state,
|
|
stored(payload = WorkflowStartedEvent(sessionId, workflowId, stageId)),
|
|
)
|
|
|
|
val failed = reducer.reduce(
|
|
started,
|
|
stored(payload = WorkflowFailedEvent(sessionId, stageId, "Something went wrong", false)),
|
|
)
|
|
assertFalse(failed.failureReason.isNullOrBlank())
|
|
assertEquals(OrchestrationStatus.FAILED, failed.status)
|
|
}
|
|
|
|
@Test
|
|
fun `WorkflowCompletedEvent sets status to COMPLETED`() {
|
|
val started = reducer.reduce(
|
|
state,
|
|
stored(payload = WorkflowStartedEvent(sessionId, workflowId, stageId)),
|
|
)
|
|
|
|
val completed = reducer.reduce(
|
|
started,
|
|
stored(payload = WorkflowCompletedEvent(sessionId, stageId, 1)),
|
|
)
|
|
assertTrue(completed.failureReason.isNullOrBlank())
|
|
assertEquals(OrchestrationStatus.COMPLETED, completed.status)
|
|
assertEquals(stageId, completed.currentStageId)
|
|
}
|
|
|
|
@Test
|
|
fun `OrchestrationPausedEvent sets status to PAUSED with reason and pending approval`() {
|
|
val started = reducer.reduce(
|
|
state,
|
|
stored(payload = WorkflowStartedEvent(sessionId, workflowId, stageId)),
|
|
)
|
|
|
|
val paused = reducer.reduce(
|
|
started,
|
|
stored(payload = OrchestrationPausedEvent(sessionId, stageId, "Requires user approval")),
|
|
)
|
|
assertFalse(paused.pauseReason.isNullOrBlank())
|
|
assertEquals(OrchestrationStatus.PAUSED, paused.status)
|
|
assertTrue(paused.pendingApproval)
|
|
}
|
|
|
|
@Test
|
|
fun `OrchestrationResumedEvent sets status to RUNNING with null reason and no pending approval`() {
|
|
val started = reducer.reduce(
|
|
state,
|
|
stored(payload = WorkflowStartedEvent(sessionId, workflowId, stageId)),
|
|
)
|
|
|
|
val paused = reducer.reduce(
|
|
started,
|
|
stored(payload = OrchestrationPausedEvent(sessionId, stageId, "Requires user approval")),
|
|
)
|
|
|
|
val resumed = reducer.reduce(
|
|
paused,
|
|
stored(payload = OrchestrationResumedEvent(sessionId, stageId)),
|
|
)
|
|
assertTrue(resumed.pauseReason.isNullOrBlank())
|
|
assertEquals(OrchestrationStatus.RUNNING, resumed.status)
|
|
assertFalse(resumed.pendingApproval)
|
|
}
|
|
|
|
@Test
|
|
fun `RetryAttemptedEvent sets status to RUNNING with null reason and no pending approval`() {
|
|
val started = reducer.reduce(
|
|
state,
|
|
stored(payload = WorkflowStartedEvent(sessionId, workflowId, stageId)),
|
|
)
|
|
|
|
val failed = reducer.reduce(
|
|
started,
|
|
stored(payload = WorkflowFailedEvent(sessionId, stageId, "Something went wrong", false)),
|
|
)
|
|
|
|
val retrying1 = reducer.reduce(
|
|
failed,
|
|
stored(payload = RetryAttemptedEvent(sessionId, stageId, 1, 3, "Something went wrong")),
|
|
)
|
|
|
|
val retrying2 = reducer.reduce(
|
|
retrying1,
|
|
stored(payload = RetryAttemptedEvent(sessionId, stageId, 2, 3, "Something went wrong")),
|
|
)
|
|
|
|
val retrying3 = reducer.reduce(
|
|
retrying2,
|
|
stored(payload = RetryAttemptedEvent(sessionId, stageId, 3, 3, "Something went wrong")),
|
|
)
|
|
assertTrue(retrying1.retryCount < retrying2.retryCount && retrying2.retryCount < retrying3.retryCount)
|
|
assertEquals(OrchestrationStatus.RUNNING, retrying1.status)
|
|
assertNull(retrying1.failureReason)
|
|
}
|
|
|
|
|
|
@Test
|
|
fun `unrelated event does nothing`() {
|
|
val started = reducer.reduce(
|
|
state,
|
|
stored(payload = WorkflowStartedEvent(sessionId, workflowId, stageId)),
|
|
)
|
|
|
|
val unrelated = reducer.reduce(started, stored())
|
|
assertEquals(started, unrelated)
|
|
}
|
|
}
|