ce7cb702218693d08ea6d83464d2457c9250027c
This commit is contained in:
commit
34c5f8963c
1 changed files with 145336 additions and 0 deletions
148
services/project-delivery/controller/render_test.go
Normal file
148
services/project-delivery/controller/render_test.go
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
"slices"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
yamlutil "k8s.io/apimachinery/pkg/util/yaml"
|
||||
dynamicfake "k8s.io/client-go/dynamic/fake"
|
||||
)
|
||||
|
||||
func renderObjects(t *testing.T) ([]runtime.Object, []*unstructured.Unstructured) {
|
||||
t.Helper()
|
||||
path := os.Getenv("DELIVERY_RENDER")
|
||||
if path == "" {
|
||||
t.Skip("DELIVERY_RENDER is not set")
|
||||
}
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer file.Close()
|
||||
decoder := yamlutil.NewYAMLOrJSONDecoder(file, 4096)
|
||||
var objects []runtime.Object
|
||||
var templates []*unstructured.Unstructured
|
||||
for {
|
||||
object := &unstructured.Unstructured{}
|
||||
if err := decoder.Decode(&object.Object); err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
switch object.GetKind() {
|
||||
case "ConfigMap":
|
||||
objects = append(objects, object)
|
||||
case "WorkflowTemplate":
|
||||
objects = append(objects, object)
|
||||
templates = append(templates, object)
|
||||
}
|
||||
}
|
||||
if len(templates) == 0 {
|
||||
t.Fatal("render contains no WorkflowTemplates")
|
||||
}
|
||||
return objects, templates
|
||||
}
|
||||
|
||||
func TestMailKeysGraph(t *testing.T) {
|
||||
_, templates := renderObjects(t)
|
||||
for _, template := range templates {
|
||||
if template.GetName() != "mail-keys-build" {
|
||||
continue
|
||||
}
|
||||
stages, _, err := unstructured.NestedSlice(template.Object, "spec", "templates")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, value := range stages {
|
||||
stage := value.(map[string]any)
|
||||
if stage["name"] != "delivery" {
|
||||
continue
|
||||
}
|
||||
tasks, _, err := unstructured.NestedSlice(stage, "dag", "tasks")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want := map[string][]string{
|
||||
"source-pull": nil,
|
||||
"cache-pull": nil,
|
||||
"toolchain-pull": nil,
|
||||
"build": {"cache-pull", "source-pull", "toolchain-pull"},
|
||||
"image-publish": {"build"},
|
||||
"cache-export": {"build"},
|
||||
}
|
||||
for _, value := range tasks {
|
||||
task := value.(map[string]any)
|
||||
name := task["name"].(string)
|
||||
expected, found := want[name]
|
||||
if !found {
|
||||
t.Fatalf("unexpected or duplicate delivery task %q", name)
|
||||
}
|
||||
parents, _, err := unstructured.NestedStringSlice(task, "dependencies")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
slices.Sort(parents)
|
||||
if !slices.Equal(parents, expected) || task["depends"] != nil {
|
||||
t.Errorf("%s parents = %v (depends: %v), want %v", name, parents, task["depends"], expected)
|
||||
}
|
||||
delete(want, name)
|
||||
}
|
||||
if len(want) != 0 {
|
||||
t.Fatalf("missing delivery tasks: %v", want)
|
||||
}
|
||||
return
|
||||
}
|
||||
t.Fatal("mail-keys-build has no delivery DAG")
|
||||
}
|
||||
t.Fatal("render contains no mail-keys-build")
|
||||
}
|
||||
|
||||
func TestRenderedTemplates(t *testing.T) {
|
||||
objects, templates := renderObjects(t)
|
||||
for _, namespace := range []string{"project-delivery"} {
|
||||
objects = append(objects, &unstructured.Unstructured{Object: map[string]any{
|
||||
"apiVersion": "v1", "kind": "ConfigMap", "metadata": map[string]any{"name": "kube-root-ca.crt", "namespace": namespace},
|
||||
"data": map[string]any{"ca.crt": "synthetic public CA"},
|
||||
}})
|
||||
}
|
||||
client := dynamicfake.NewSimpleDynamicClientWithCustomListKinds(runtime.NewScheme(), map[schema.GroupVersionResource]string{
|
||||
workflowGVR: "WorkflowList", templateGVR: "WorkflowTemplateList", configMapGVR: "ConfigMapList",
|
||||
}, objects...)
|
||||
c := &controller{client: client, now: func() time.Time { return time.Date(2026, 10, 2, 0, 0, 0, 0, time.UTC) }}
|
||||
for _, template := range templates {
|
||||
t.Run(template.GetName(), func(t *testing.T) {
|
||||
name, err := c.readyTemplate(context.Background(), template.GetNamespace(), template.GetName())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
copy, err := client.Resource(templateGVR).Namespace(template.GetNamespace()).Get(context.Background(), name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if copy.GetAnnotations()[templateKey] != template.GetName() {
|
||||
t.Fatal("captured template lost its logical reference")
|
||||
}
|
||||
bundle, err := c.captureBundle(context.Background(), template)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, config := range bundle.configs {
|
||||
captured, err := client.Resource(configMapGVR).Namespace(template.GetNamespace()).Get(context.Background(), config.GetName(), metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if captured.Object["immutable"] != true {
|
||||
t.Fatalf("action ConfigMap %q is mutable", config.GetName())
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue