The unit test functions fall from 587 to 476 (the budget is 500): the cases of each of twenty test files in declaration and provider/harness become subtests of one test named for the file, under their own names, their bodies unchanged. Integration tests stay at 30 (budget 50). Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
61 lines
2.4 KiB
Go
61 lines
2.4 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)
|
|
}
|
|
}
|
|
|
|
// TestScheduleDeclaration holds this file's cases, each a subtest of its own name (mesh-sdk's test budget: at most 500 unit tests).
|
|
func TestScheduleDeclaration(t *testing.T) {
|
|
t.Run("AScheduledContainerCarriesTheCronField", testAScheduledContainerCarriesTheCronField)
|
|
t.Run("AMalformedScheduleIsRefused", testAMalformedScheduleIsRefused)
|
|
t.Run("AContainerCannotBeBothRunOnceAndScheduled", testAContainerCannotBeBothRunOnceAndScheduled)
|
|
}
|