Files
mesh-sdk/go/declaration/schedule_declaration_test.go

54 lines
2.0 KiB
Go

package declaration
import (
"strings"
"testing"
)
// The host refuses a schedule it does not fully understand, on arrival, for the same reason the
// control plane refuses it near its author (novox/hq ADR 0053): a declaration half-understood is
// refused whole rather than half-applied.
func schedulePinned() string { return "registry.example/runtime@sha256:" + strings.Repeat("a", 64) }
func TestAScheduledContainerCarriesTheCronField(t *testing.T) {
d, err := Parse([]byte(`{"declaration":1,"resources":[
{"id":"sync","type":"container","name":"sync","image":"` + schedulePinned() + `","schedule":"0 3 * * *"}
]}`))
if err != nil {
t.Fatalf("a valid scheduled container was refused: %v", err)
}
c, ok := d.Resources[0].(*Container)
if !ok {
t.Fatalf("the scheduled resource is not a container: %T", d.Resources[0])
}
if c.Schedule != "0 3 * * *" {
t.Errorf("the schedule did not survive parsing: %q", c.Schedule)
}
}
func TestAMalformedScheduleIsRefused(t *testing.T) {
_, err := Parse([]byte(`{"declaration":1,"resources":[
{"id":"sync","type":"container","name":"sync","image":"` + schedulePinned() + `","schedule":"every night"}
]}`))
if err == nil {
t.Fatal("a container with a malformed schedule was accepted")
}
if !strings.Contains(err.Error(), "cron") && !strings.Contains(err.Error(), "field") {
t.Errorf("refused for the wrong reason: %v", err)
}
}
func TestAContainerCannotBeBothRunOnceAndScheduled(t *testing.T) {
// A container runs once and gates, or on a cadence, or stays up — never two (novox/hq ADR 0053).
_, err := Parse([]byte(`{"declaration":1,"resources":[
{"id":"sync","type":"container","name":"sync","image":"` + schedulePinned() + `","run-once":true,"schedule":"0 3 * * *"}
]}`))
if err == nil {
t.Fatal("a container that was both run-once and scheduled was accepted")
}
if !strings.Contains(err.Error(), "run-once") && !strings.Contains(err.Error(), "scheduled") {
t.Errorf("refused for the wrong reason: %v", err)
}
}