Files
poimen-workflows/internal/pause/handler_test.go
T

258 lines
6.7 KiB
Go
Raw Normal View History

package pause
import (
"fmt"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestRequestPause(t *testing.T) {
tmpDir := t.TempDir()
sm := NewSnapshotManager(tmpDir)
ph := NewPauseHandler(sm)
signal := &PauseSignal{
WorkflowID: "wf-1",
Reason: "manual pause",
RequestedAt: time.Now(),
}
err := ph.RequestPause(signal)
assert.NoError(t, err)
assert.True(t, ph.IsPaused("wf-1"))
}
func TestRequestResume(t *testing.T) {
tmpDir := t.TempDir()
sm := NewSnapshotManager(tmpDir)
ph := NewPauseHandler(sm)
// First pause
ph.RequestPause(&PauseSignal{WorkflowID: "wf-1", Reason: "pause", RequestedAt: time.Now()})
assert.True(t, ph.IsPaused("wf-1"))
// Then resume
err := ph.RequestResume(&ResumeSignal{WorkflowID: "wf-1", Reason: "resume", RequestedAt: time.Now()})
assert.NoError(t, err)
assert.False(t, ph.IsPaused("wf-1"))
}
func TestIsPaused(t *testing.T) {
tmpDir := t.TempDir()
sm := NewSnapshotManager(tmpDir)
ph := NewPauseHandler(sm)
assert.False(t, ph.IsPaused("wf-1"))
ph.RequestPause(&PauseSignal{WorkflowID: "wf-1", Reason: "pause", RequestedAt: time.Now()})
assert.True(t, ph.IsPaused("wf-1"))
}
func TestGetPauseState(t *testing.T) {
tmpDir := t.TempDir()
sm := NewSnapshotManager(tmpDir)
ph := NewPauseHandler(sm)
ph.RequestPause(&PauseSignal{WorkflowID: "wf-1", Reason: "pause", RequestedAt: time.Now()})
state := ph.GetPauseState("wf-1")
assert.NotNil(t, state)
assert.Equal(t, "wf-1", state.WorkflowID)
assert.True(t, state.IsPaused)
assert.Equal(t, "pause", state.PauseReason)
}
func TestSaveSnapshot(t *testing.T) {
tmpDir := t.TempDir()
sm := NewSnapshotManager(tmpDir)
ph := NewPauseHandler(sm)
snapshot, err := ph.SaveSnapshot(
"wf-1",
"stage1",
[]string{"T1.1"},
[]string{"T1.2"},
nil,
"T1.2",
"activity-1",
nil,
nil,
nil,
)
assert.NoError(t, err)
assert.NotNil(t, snapshot)
assert.Equal(t, "wf-1", snapshot.WorkflowID)
}
func TestRestoreSnapshot(t *testing.T) {
tmpDir := t.TempDir()
sm := NewSnapshotManager(tmpDir)
ph := NewPauseHandler(sm)
// Save snapshot
ph.SaveSnapshot("wf-1", "stage1", []string{"T1.1"}, []string{"T1.2"}, nil, "T1.2", "", nil, nil, nil)
// Restore it
snapshot, err := ph.RestoreSnapshot("wf-1")
assert.NoError(t, err)
assert.NotNil(t, snapshot)
assert.Equal(t, "wf-1", snapshot.WorkflowID)
}
func TestResetPauseState(t *testing.T) {
tmpDir := t.TempDir()
sm := NewSnapshotManager(tmpDir)
ph := NewPauseHandler(sm)
ph.RequestPause(&PauseSignal{WorkflowID: "wf-1", Reason: "pause", RequestedAt: time.Now()})
assert.True(t, ph.IsPaused("wf-1"))
err := ph.ResetPauseState("wf-1")
assert.NoError(t, err)
assert.Nil(t, ph.GetPauseState("wf-1"))
}
func TestGetAllPauseStates(t *testing.T) {
tmpDir := t.TempDir()
sm := NewSnapshotManager(tmpDir)
ph := NewPauseHandler(sm)
ph.RequestPause(&PauseSignal{WorkflowID: "wf-1", Reason: "pause", RequestedAt: time.Now()})
ph.RequestPause(&PauseSignal{WorkflowID: "wf-2", Reason: "pause", RequestedAt: time.Now()})
ph.RequestPause(&PauseSignal{WorkflowID: "wf-3", Reason: "pause", RequestedAt: time.Now()})
states := ph.GetAllPauseStates()
assert.Equal(t, 3, len(states))
}
func TestGetPauseStats(t *testing.T) {
tmpDir := t.TempDir()
sm := NewSnapshotManager(tmpDir)
ph := NewPauseHandler(sm)
ph.RequestPause(&PauseSignal{WorkflowID: "wf-1", Reason: "pause", RequestedAt: time.Now()})
ph.RequestPause(&PauseSignal{WorkflowID: "wf-2", Reason: "pause", RequestedAt: time.Now()})
ph.RequestResume(&ResumeSignal{WorkflowID: "wf-1", Reason: "resume", RequestedAt: time.Now()})
stats := ph.GetPauseStats()
assert.Equal(t, 2, stats["total"])
assert.Equal(t, 1, stats["paused"])
assert.Equal(t, 1, stats["resumed"])
}
func TestPauseStateFields(t *testing.T) {
tmpDir := t.TempDir()
sm := NewSnapshotManager(tmpDir)
ph := NewPauseHandler(sm)
pausedTime := time.Now()
ph.RequestPause(&PauseSignal{WorkflowID: "wf-1", Reason: "manual pause", RequestedAt: pausedTime})
state := ph.GetPauseState("wf-1")
assert.Equal(t, "wf-1", state.WorkflowID)
assert.True(t, state.IsPaused)
assert.Equal(t, "manual pause", state.PauseReason)
assert.NotZero(t, state.PausedAt)
}
func TestResumedAt(t *testing.T) {
tmpDir := t.TempDir()
sm := NewSnapshotManager(tmpDir)
ph := NewPauseHandler(sm)
ph.RequestPause(&PauseSignal{WorkflowID: "wf-1", Reason: "pause", RequestedAt: time.Now()})
ph.RequestResume(&ResumeSignal{WorkflowID: "wf-1", Reason: "resume", RequestedAt: time.Now()})
state := ph.GetPauseState("wf-1")
assert.NotNil(t, state.ResumedAt)
}
func TestResumeNotPausedError(t *testing.T) {
tmpDir := t.TempDir()
sm := NewSnapshotManager(tmpDir)
ph := NewPauseHandler(sm)
// Try to resume without pausing first
err := ph.RequestResume(&ResumeSignal{WorkflowID: "wf-1", Reason: "resume", RequestedAt: time.Now()})
assert.Error(t, err)
}
func TestNilSignals(t *testing.T) {
tmpDir := t.TempDir()
sm := NewSnapshotManager(tmpDir)
ph := NewPauseHandler(sm)
err := ph.RequestPause(nil)
assert.Error(t, err)
err = ph.RequestResume(nil)
assert.Error(t, err)
}
func TestMultipleWorkflowsPause(t *testing.T) {
tmpDir := t.TempDir()
sm := NewSnapshotManager(tmpDir)
ph := NewPauseHandler(sm)
for i := 1; i <= 5; i++ {
wfID := fmt.Sprintf("wf-%d", i)
ph.RequestPause(&PauseSignal{WorkflowID: wfID, Reason: "pause", RequestedAt: time.Now()})
}
states := ph.GetAllPauseStates()
assert.Equal(t, 5, len(states))
for _, state := range states {
assert.True(t, state.IsPaused)
}
}
func TestWaitForPauseOrResume(t *testing.T) {
tmpDir := t.TempDir()
sm := NewSnapshotManager(tmpDir)
ph := NewPauseHandler(sm)
// Send pause signal in goroutine
go func() {
time.Sleep(100 * time.Millisecond)
ph.RequestPause(&PauseSignal{WorkflowID: "wf-1", Reason: "pause", RequestedAt: time.Now()})
}()
// Wait for pause
isPaused, err := ph.WaitForPauseOrResume("wf-1", 1*time.Second)
assert.NoError(t, err)
assert.True(t, isPaused)
}
func TestWaitTimeout(t *testing.T) {
tmpDir := t.TempDir()
sm := NewSnapshotManager(tmpDir)
ph := NewPauseHandler(sm)
// Wait with timeout should fail
_, err := ph.WaitForPauseOrResume("wf-1", 100*time.Millisecond)
assert.Error(t, err)
}
func TestSnapshotWithPause(t *testing.T) {
tmpDir := t.TempDir()
sm := NewSnapshotManager(tmpDir)
ph := NewPauseHandler(sm)
// Save snapshot before pausing
snapshot, err := ph.SaveSnapshot("wf-1", "stage1", []string{"T1.1"}, []string{"T1.2"}, nil, "T1.2", "", nil, nil, nil)
assert.NoError(t, err)
// Pause
ph.RequestPause(&PauseSignal{WorkflowID: "wf-1", Reason: "pause", RequestedAt: time.Now()})
// State should have snapshot
state := ph.GetPauseState("wf-1")
assert.NotNil(t, state)
assert.NotNil(t, state.CurrentSnapshot)
assert.Equal(t, snapshot.WorkflowID, state.CurrentSnapshot.WorkflowID)
}