1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
package task
import (
"testing"
"time"
)
func TestValidTransition_AllowedTransitions(t *testing.T) {
tests := []struct {
name string
from State
to State
}{
{"pending to queued", StatePending, StateQueued},
{"pending to cancelled", StatePending, StateCancelled},
{"queued to running", StateQueued, StateRunning},
{"queued to cancelled", StateQueued, StateCancelled},
{"running to completed", StateRunning, StateCompleted},
{"running to failed", StateRunning, StateFailed},
{"running to timed out", StateRunning, StateTimedOut},
{"running to cancelled", StateRunning, StateCancelled},
{"running to budget exceeded", StateRunning, StateBudgetExceeded},
{"failed to queued (retry)", StateFailed, StateQueued},
{"timed out to queued (retry)", StateTimedOut, StateQueued},
{"running to blocked (question)", StateRunning, StateBlocked},
{"blocked to queued (answer resume)", StateBlocked, StateQueued},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if !ValidTransition(tt.from, tt.to) {
t.Errorf("expected transition %s -> %s to be valid", tt.from, tt.to)
}
})
}
}
func TestValidTransition_DisallowedTransitions(t *testing.T) {
tests := []struct {
name string
from State
to State
}{
{"pending to running", StatePending, StateRunning},
{"pending to completed", StatePending, StateCompleted},
{"queued to completed", StateQueued, StateCompleted},
{"completed to running", StateCompleted, StateRunning},
{"completed to queued", StateCompleted, StateQueued},
{"failed to completed", StateFailed, StateCompleted},
{"timed out to completed", StateTimedOut, StateCompleted},
{"ready to queued", StateReady, StateQueued},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if ValidTransition(tt.from, tt.to) {
t.Errorf("expected transition %s -> %s to be invalid", tt.from, tt.to)
}
})
}
}
func TestValidTransition_ReadyState(t *testing.T) {
valid := []struct{ from, to State }{
{StateRunning, StateReady},
{StateReady, StateCompleted},
{StateReady, StatePending},
}
for _, tt := range valid {
if !ValidTransition(tt.from, tt.to) {
t.Errorf("expected transition %s -> %s to be valid", tt.from, tt.to)
}
}
}
func TestDuration_UnmarshalYAML(t *testing.T) {
var d Duration
unmarshal := func(v interface{}) error {
ptr := v.(*string)
*ptr = "30m"
return nil
}
if err := d.UnmarshalYAML(unmarshal); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if d.Duration != 30*time.Minute {
t.Errorf("expected 30m, got %v", d.Duration)
}
}
func TestDuration_MarshalYAML(t *testing.T) {
d := Duration{Duration: 15 * time.Minute}
v, err := d.MarshalYAML()
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if v != "15m0s" {
t.Errorf("expected '15m0s', got %v", v)
}
}
|