feat: runtime manager
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
package operation
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestOpKindIsKnown(t *testing.T) {
|
||||
for _, kind := range AllOpKinds() {
|
||||
assert.Truef(t, kind.IsKnown(), "expected %q known", kind)
|
||||
}
|
||||
|
||||
assert.False(t, OpKind("").IsKnown())
|
||||
assert.False(t, OpKind("rollback").IsKnown())
|
||||
}
|
||||
|
||||
func TestAllOpKindsCoverFrozenSet(t *testing.T) {
|
||||
assert.ElementsMatch(t,
|
||||
[]OpKind{
|
||||
OpKindStart, OpKindStop, OpKindRestart, OpKindPatch,
|
||||
OpKindCleanupContainer, OpKindReconcileAdopt, OpKindReconcileDispose,
|
||||
},
|
||||
AllOpKinds(),
|
||||
)
|
||||
}
|
||||
|
||||
func TestOpSourceIsKnown(t *testing.T) {
|
||||
for _, source := range AllOpSources() {
|
||||
assert.Truef(t, source.IsKnown(), "expected %q known", source)
|
||||
}
|
||||
|
||||
assert.False(t, OpSource("").IsKnown())
|
||||
assert.False(t, OpSource("manual").IsKnown())
|
||||
}
|
||||
|
||||
func TestAllOpSourcesCoverFrozenSet(t *testing.T) {
|
||||
assert.ElementsMatch(t,
|
||||
[]OpSource{
|
||||
OpSourceLobbyStream, OpSourceGMRest, OpSourceAdminRest,
|
||||
OpSourceAutoTTL, OpSourceAutoReconcile,
|
||||
},
|
||||
AllOpSources(),
|
||||
)
|
||||
}
|
||||
|
||||
func TestOutcomeIsKnown(t *testing.T) {
|
||||
for _, outcome := range AllOutcomes() {
|
||||
assert.Truef(t, outcome.IsKnown(), "expected %q known", outcome)
|
||||
}
|
||||
|
||||
assert.False(t, Outcome("").IsKnown())
|
||||
assert.False(t, Outcome("partial").IsKnown())
|
||||
}
|
||||
|
||||
func TestAllOutcomesCoverFrozenSet(t *testing.T) {
|
||||
assert.ElementsMatch(t,
|
||||
[]Outcome{OutcomeSuccess, OutcomeFailure},
|
||||
AllOutcomes(),
|
||||
)
|
||||
}
|
||||
|
||||
func successEntry() OperationEntry {
|
||||
started := time.Date(2026, 4, 27, 12, 0, 0, 0, time.UTC)
|
||||
finished := started.Add(time.Second)
|
||||
return OperationEntry{
|
||||
GameID: "game-test",
|
||||
OpKind: OpKindStart,
|
||||
OpSource: OpSourceLobbyStream,
|
||||
SourceRef: "1700000000000-0",
|
||||
ImageRef: "galaxy/game:1.0.0",
|
||||
ContainerID: "container-1",
|
||||
Outcome: OutcomeSuccess,
|
||||
StartedAt: started,
|
||||
FinishedAt: &finished,
|
||||
}
|
||||
}
|
||||
|
||||
func TestOperationEntryValidateHappy(t *testing.T) {
|
||||
require.NoError(t, successEntry().Validate())
|
||||
}
|
||||
|
||||
func TestOperationEntryValidateAcceptsReplayNoOp(t *testing.T) {
|
||||
entry := successEntry()
|
||||
entry.ErrorCode = "replay_no_op"
|
||||
|
||||
assert.NoError(t, entry.Validate())
|
||||
}
|
||||
|
||||
func TestOperationEntryValidateAcceptsInFlight(t *testing.T) {
|
||||
entry := successEntry()
|
||||
entry.FinishedAt = nil
|
||||
|
||||
assert.NoError(t, entry.Validate())
|
||||
}
|
||||
|
||||
func TestOperationEntryValidateRejects(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
mutate func(*OperationEntry)
|
||||
}{
|
||||
{"empty game id", func(e *OperationEntry) { e.GameID = "" }},
|
||||
{"unknown op kind", func(e *OperationEntry) { e.OpKind = "exotic" }},
|
||||
{"unknown op source", func(e *OperationEntry) { e.OpSource = "exotic" }},
|
||||
{"unknown outcome", func(e *OperationEntry) { e.Outcome = "partial" }},
|
||||
{"zero started at", func(e *OperationEntry) { e.StartedAt = time.Time{} }},
|
||||
{"zero finished at", func(e *OperationEntry) {
|
||||
zero := time.Time{}
|
||||
e.FinishedAt = &zero
|
||||
}},
|
||||
{"finished before started", func(e *OperationEntry) {
|
||||
before := e.StartedAt.Add(-time.Second)
|
||||
e.FinishedAt = &before
|
||||
}},
|
||||
{"failure without error code", func(e *OperationEntry) {
|
||||
e.Outcome = OutcomeFailure
|
||||
e.ErrorCode = ""
|
||||
}},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
entry := successEntry()
|
||||
tt.mutate(&entry)
|
||||
assert.Error(t, entry.Validate())
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user