ce7cb702218693d08ea6d83464d2457c9250027c

This commit is contained in:
ms2k 2026-11-12 20:46:28 +09:00
commit 34c5f8963c

View file

@ -0,0 +1,92 @@
package main
import (
"context"
"errors"
"reflect"
"testing"
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
func TestTemplateDrain(t *testing.T) {
for _, purpose := range []string{"build", "qualification"} {
for _, outcome := range []string{"Succeeded", "Failed", "Error"} {
t.Run(purpose+"/"+outcome, func(t *testing.T) {
ctx := context.Background()
now := time.Date(2026, 10, 2, 0, 0, 0, 0, time.UTC)
c := testController(t, continuousDelivery(), &mutableRefs{}, &now)
d, err := decodeProjectDelivery(continuousDelivery())
if err != nil {
t.Fatal(err)
}
if err := c.ensureWorkflow(ctx, &d, "first", "nuthatch-delivery", purpose, nil, nil); err != nil {
t.Fatal(err)
}
old := boundTemplate(t, c, "first").DeepCopy()
c.config.templateQuiet = time.Minute
changeImage(t, c, "nuthatch-delivery", "example.invalid/builder:v2")
if _, err := c.readyTemplate(ctx, "delivery", "nuthatch-delivery"); !errors.Is(err, templatePending) {
t.Fatalf("first change = %v", err)
}
now = now.Add(30 * time.Second)
changeImage(t, c, "nuthatch-delivery", "example.invalid/builder:v3")
if _, err := c.readyTemplate(ctx, "delivery", "nuthatch-delivery"); !errors.Is(err, templatePending) {
t.Fatalf("latest change = %v", err)
}
now = now.Add(time.Minute)
if _, err := c.readyTemplate(ctx, "delivery", "nuthatch-delivery"); !errors.Is(err, templatePending) {
t.Fatalf("queued drain = %v", err)
}
setNamedWorkflowStatus(t, c, "first", "Running", nil)
if _, err := c.readyTemplate(ctx, "delivery", "nuthatch-delivery"); !errors.Is(err, templatePending) {
t.Fatalf("running drain = %v", err)
}
if err := c.ensureWorkflow(ctx, &d, "first", "nuthatch-delivery", purpose, nil, nil); err != nil {
t.Fatal(err)
}
if err := c.ensureWorkflow(ctx, &d, "second", "nuthatch-delivery", purpose, nil, nil); !errors.Is(err, templatePending) {
t.Fatalf("new admission = %v", err)
}
setNamedWorkflowStatus(t, c, "first", outcome, nil)
if err := c.ensureWorkflow(ctx, &d, "second", "nuthatch-delivery", purpose, nil, nil); err != nil {
t.Fatal(err)
}
latest := boundTemplate(t, c, "second")
templates, _, _ := unstructured.NestedSlice(latest.Object, "spec", "templates")
if image := templates[0].(map[string]any)["container"].(map[string]any)["image"]; image != "example.invalid/builder:v3" {
t.Fatalf("published image = %v", image)
}
if !reflect.DeepEqual(old.Object["spec"], boundTemplate(t, c, "first").Object["spec"]) {
t.Fatal("terminal Workflow lost its captured specification")
}
resource := c.client.Resource(templateGVR).Namespace("delivery")
alias, err := resource.Get(ctx, "nuthatch-delivery", metav1.GetOptions{})
if err != nil {
t.Fatal(err)
}
if alias.GetAnnotations()[publishedKey] != latest.GetName() {
t.Fatal("published selection did not retain the latest revision")
}
})
}
}
}
func changeImage(t *testing.T, c *controller, name, image string) {
t.Helper()
resource := c.client.Resource(templateGVR).Namespace("delivery")
object, err := resource.Get(context.Background(), name, metav1.GetOptions{})
if err != nil {
t.Fatal(err)
}
object.SetGeneration(object.GetGeneration() + 1)
if err := unstructured.SetNestedSlice(object.Object, []any{map[string]any{"name": "build", "container": map[string]any{"image": image}}}, "spec", "templates"); err != nil {
t.Fatal(err)
}
if _, err := resource.Update(context.Background(), object, metav1.UpdateOptions{}); err != nil {
t.Fatal(err)
}
}