131 lines
3.8 KiB
Go
131 lines
3.8 KiB
Go
package runtime
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func validRunningRecord() RuntimeRecord {
|
|
created := time.Date(2026, 4, 27, 12, 0, 0, 0, time.UTC)
|
|
started := created.Add(time.Minute)
|
|
updated := started.Add(time.Minute)
|
|
next := updated.Add(time.Hour)
|
|
return RuntimeRecord{
|
|
GameID: "game-1",
|
|
Status: StatusRunning,
|
|
EngineEndpoint: "http://galaxy-game-1:8080",
|
|
CurrentImageRef: "ghcr.io/galaxy/game:v1.2.3",
|
|
CurrentEngineVersion: "v1.2.3",
|
|
TurnSchedule: "0 18 * * *",
|
|
CurrentTurn: 0,
|
|
NextGenerationAt: &next,
|
|
CreatedAt: created,
|
|
UpdatedAt: updated,
|
|
StartedAt: &started,
|
|
}
|
|
}
|
|
|
|
func TestStatusIsKnown(t *testing.T) {
|
|
for _, status := range AllStatuses() {
|
|
assert.True(t, status.IsKnown(), "want known: %q", status)
|
|
}
|
|
assert.False(t, Status("exotic").IsKnown())
|
|
assert.False(t, Status("").IsKnown())
|
|
}
|
|
|
|
func TestStatusIsTerminal(t *testing.T) {
|
|
assert.True(t, StatusFinished.IsTerminal())
|
|
for _, status := range AllStatuses() {
|
|
if status == StatusFinished {
|
|
continue
|
|
}
|
|
assert.False(t, status.IsTerminal(), "%q must not be terminal", status)
|
|
}
|
|
}
|
|
|
|
func TestAllStatusesStable(t *testing.T) {
|
|
first := AllStatuses()
|
|
second := AllStatuses()
|
|
assert.Equal(t, first, second)
|
|
assert.Len(t, first, 7)
|
|
}
|
|
|
|
func TestRuntimeRecordValidateHappy(t *testing.T) {
|
|
require.NoError(t, validRunningRecord().Validate())
|
|
}
|
|
|
|
func TestRuntimeRecordValidateAcceptsStarting(t *testing.T) {
|
|
record := validRunningRecord()
|
|
record.Status = StatusStarting
|
|
record.StartedAt = nil
|
|
record.NextGenerationAt = nil
|
|
|
|
assert.NoError(t, record.Validate())
|
|
}
|
|
|
|
func TestRuntimeRecordValidateRequiresFinishedAt(t *testing.T) {
|
|
record := validRunningRecord()
|
|
record.Status = StatusFinished
|
|
record.FinishedAt = nil
|
|
|
|
assert.Error(t, record.Validate())
|
|
|
|
finished := record.UpdatedAt.Add(time.Minute)
|
|
record.FinishedAt = &finished
|
|
assert.NoError(t, record.Validate())
|
|
}
|
|
|
|
func TestRuntimeRecordValidateRequiresStoppedAtForStopped(t *testing.T) {
|
|
record := validRunningRecord()
|
|
record.Status = StatusStopped
|
|
assert.Error(t, record.Validate())
|
|
|
|
stopped := record.UpdatedAt.Add(time.Minute)
|
|
record.StoppedAt = &stopped
|
|
assert.NoError(t, record.Validate())
|
|
}
|
|
|
|
func TestRuntimeRecordValidateRejects(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
mutate func(*RuntimeRecord)
|
|
}{
|
|
{"empty game id", func(r *RuntimeRecord) { r.GameID = "" }},
|
|
{"unknown status", func(r *RuntimeRecord) { r.Status = "exotic" }},
|
|
{"empty engine endpoint", func(r *RuntimeRecord) { r.EngineEndpoint = "" }},
|
|
{"empty image ref", func(r *RuntimeRecord) { r.CurrentImageRef = "" }},
|
|
{"empty engine version", func(r *RuntimeRecord) { r.CurrentEngineVersion = "" }},
|
|
{"empty turn schedule", func(r *RuntimeRecord) { r.TurnSchedule = "" }},
|
|
{"negative turn", func(r *RuntimeRecord) { r.CurrentTurn = -1 }},
|
|
{"zero created at", func(r *RuntimeRecord) { r.CreatedAt = time.Time{} }},
|
|
{"zero updated at", func(r *RuntimeRecord) { r.UpdatedAt = time.Time{} }},
|
|
{"updated before created", func(r *RuntimeRecord) {
|
|
r.UpdatedAt = r.CreatedAt.Add(-time.Minute)
|
|
}},
|
|
{"started before created", func(r *RuntimeRecord) {
|
|
before := r.CreatedAt.Add(-time.Minute)
|
|
r.StartedAt = &before
|
|
}},
|
|
{"running missing started at", func(r *RuntimeRecord) { r.StartedAt = nil }},
|
|
{"starting with started at", func(r *RuntimeRecord) {
|
|
r.Status = StatusStarting
|
|
// keep StartedAt set
|
|
}},
|
|
{"zero next generation at", func(r *RuntimeRecord) {
|
|
zero := time.Time{}
|
|
r.NextGenerationAt = &zero
|
|
}},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
record := validRunningRecord()
|
|
tt.mutate(&record)
|
|
assert.Error(t, record.Validate())
|
|
})
|
|
}
|
|
}
|