package runtime import ( "errors" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestTransitionAcceptsAllAllowedPairs(t *testing.T) { for from, tos := range AllowedTransitions() { for _, to := range tos { t.Run(string(from)+"->"+string(to), func(t *testing.T) { assert.NoError(t, Transition(from, to)) }) } } } func TestTransitionRejectsForbiddenPairs(t *testing.T) { allowed := AllowedTransitions() allowedSet := make(map[transitionKey]struct{}) for from, tos := range allowed { for _, to := range tos { allowedSet[transitionKey{from: from, to: to}] = struct{}{} } } for _, from := range AllStatuses() { for _, to := range AllStatuses() { if _, ok := allowedSet[transitionKey{from: from, to: to}]; ok { continue } t.Run(string(from)+"->"+string(to), func(t *testing.T) { err := Transition(from, to) require.Error(t, err) var typed *InvalidTransitionError assert.True(t, errors.As(err, &typed)) assert.Equal(t, from, typed.From) assert.Equal(t, to, typed.To) assert.True(t, errors.Is(err, ErrInvalidTransition)) }) } } } func TestTransitionRejectsUnknownStatus(t *testing.T) { tests := []struct { name string from Status to Status }{ {"unknown from", "exotic", StatusRunning}, {"unknown to", StatusRunning, "exotic"}, {"both unknown", "from-x", "to-y"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := Transition(tt.from, tt.to) require.Error(t, err) assert.True(t, errors.Is(err, ErrInvalidTransition)) }) } } func TestAllowedTransitionsIncludesExpectedFlows(t *testing.T) { allowed := AllowedTransitions() must := func(from Status, expected Status) { t.Helper() got := allowed[from] assert.Containsf(t, got, expected, "expected %q in transitions from %q, got %v", expected, from, got) } must(StatusStarting, StatusRunning) must(StatusRunning, StatusGenerationInProgress) must(StatusGenerationInProgress, StatusRunning) must(StatusGenerationInProgress, StatusGenerationFailed) must(StatusGenerationInProgress, StatusFinished) must(StatusGenerationFailed, StatusGenerationInProgress) must(StatusRunning, StatusEngineUnreachable) must(StatusEngineUnreachable, StatusRunning) must(StatusRunning, StatusStopped) must(StatusGenerationInProgress, StatusStopped) must(StatusGenerationFailed, StatusStopped) must(StatusEngineUnreachable, StatusStopped) }