ce7cb702218693d08ea6d83464d2457c9250027c
This commit is contained in:
commit
34c5f8963c
1 changed files with 145336 additions and 0 deletions
164
services/project-delivery/controller/bundle_test.go
Normal file
164
services/project-delivery/controller/bundle_test.go
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
func TestCapturedSpec(t *testing.T) {
|
||||
instance, template := bundleFixture(t)
|
||||
ctx := context.Background()
|
||||
delivery, err := decodeProjectDelivery(continuousDelivery())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := instance.ensureWorkflow(ctx, &delivery, "first", template.GetName(), "build", nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
bound := boundTemplate(t, instance, "first")
|
||||
stored, _, _ := unstructured.NestedMap(bound.Object, "spec")
|
||||
if err := unstructured.SetNestedSlice(template.Object, []any{map[string]any{"name": "build", "container": map[string]any{"image": "example.invalid/builder:v2"}}}, "spec", "templates"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
gvr := schema.GroupVersionResource{Group: "argoproj.io", Version: "v1alpha1", Resource: "workflowtemplates"}
|
||||
if _, err := instance.client.Resource(gvr).Namespace("delivery").Update(ctx, template, metav1.UpdateOptions{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
live, _, _ := unstructured.NestedMap(boundTemplate(t, instance, "first").Object, "spec")
|
||||
if !reflect.DeepEqual(stored, live) {
|
||||
t.Fatal("captured Workflow spec changed through its live template reference")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapturedActions(t *testing.T) {
|
||||
instance, template := bundleFixture(t)
|
||||
ctx := context.Background()
|
||||
delivery, err := decodeProjectDelivery(continuousDelivery())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := instance.ensureWorkflow(ctx, &delivery, "first", template.GetName(), "build", nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
gvr := schema.GroupVersionResource{Version: "v1", Resource: "configmaps"}
|
||||
config, err := instance.client.Resource(gvr).Namespace("delivery").Get(ctx, "actions", metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
config.Object["data"] = map[string]any{"build.fsx": "printfn \"new action\""}
|
||||
if _, err := instance.client.Resource(gvr).Namespace("delivery").Update(ctx, config, metav1.UpdateOptions{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
volumes, _, _ := unstructured.NestedSlice(boundTemplate(t, instance, "first").Object, "spec", "volumes")
|
||||
name := volumes[0].(map[string]any)["configMap"].(map[string]any)["name"].(string)
|
||||
captured, err := instance.client.Resource(gvr).Namespace("delivery").Get(ctx, name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
value, _, _ := unstructured.NestedString(captured.Object, "data", "build.fsx")
|
||||
if value != "printfn \"old action\"" {
|
||||
t.Fatalf("a later Pod resolves changed action content: %q", value)
|
||||
}
|
||||
}
|
||||
|
||||
func bundleFixture(t *testing.T) (*controller, *unstructured.Unstructured) {
|
||||
t.Helper()
|
||||
now := time.Date(2026, 10, 2, 0, 0, 0, 0, time.UTC)
|
||||
instance := testController(t, continuousDelivery(), &mutableRefs{}, &now)
|
||||
ctx := context.Background()
|
||||
config := &unstructured.Unstructured{Object: map[string]any{
|
||||
"apiVersion": "v1", "kind": "ConfigMap",
|
||||
"metadata": map[string]any{"name": "actions", "namespace": "delivery", "labels": map[string]any{"app.kubernetes.io/name": "project-delivery"}},
|
||||
"data": map[string]any{"build.fsx": "printfn \"old action\""},
|
||||
}}
|
||||
if _, err := instance.client.Resource(schema.GroupVersionResource{Version: "v1", Resource: "configmaps"}).Namespace("delivery").Create(ctx, config, metav1.CreateOptions{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
template := &unstructured.Unstructured{Object: map[string]any{
|
||||
"apiVersion": "argoproj.io/v1alpha1", "kind": "WorkflowTemplate",
|
||||
"metadata": map[string]any{"name": "nuthatch-delivery", "namespace": "delivery"},
|
||||
"spec": map[string]any{
|
||||
"entrypoint": "build",
|
||||
"templates": []any{map[string]any{"name": "build", "container": map[string]any{"image": "example.invalid/builder:v1"}}},
|
||||
"volumes": []any{map[string]any{"name": "actions", "configMap": map[string]any{"name": "actions"}}},
|
||||
},
|
||||
}}
|
||||
gvr := schema.GroupVersionResource{Group: "argoproj.io", Version: "v1alpha1", Resource: "workflowtemplates"}
|
||||
if _, err := instance.client.Resource(gvr).Namespace("delivery").Update(ctx, template, metav1.UpdateOptions{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return instance, template
|
||||
}
|
||||
|
||||
func boundTemplate(t *testing.T, instance *controller, name string) *unstructured.Unstructured {
|
||||
t.Helper()
|
||||
ctx := context.Background()
|
||||
workflow, err := instance.client.Resource(workflowGVR).Namespace("delivery").Get(ctx, name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ref, _, _ := unstructured.NestedString(workflow.Object, "spec", "workflowTemplateRef", "name")
|
||||
gvr := schema.GroupVersionResource{Group: "argoproj.io", Version: "v1alpha1", Resource: "workflowtemplates"}
|
||||
template, err := instance.client.Resource(gvr).Namespace("delivery").Get(ctx, ref, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return template
|
||||
}
|
||||
|
||||
func TestCapturedPatch(t *testing.T) {
|
||||
instance, template := bundleFixture(t)
|
||||
ctx := context.Background()
|
||||
unstructured.RemoveNestedField(template.Object, "spec", "volumes")
|
||||
if err := unstructured.SetNestedSlice(template.Object, []any{map[string]any{
|
||||
"name": "build", "container": map[string]any{"image": "example.invalid/builder:v1"},
|
||||
"podSpecPatch": "volumes:\n- name: actions\n configMap:\n name: actions\n",
|
||||
}}, "spec", "templates"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := instance.client.Resource(templateGVR).Namespace("delivery").Update(ctx, template, metav1.UpdateOptions{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
delivery, err := decodeProjectDelivery(continuousDelivery())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := instance.ensureWorkflow(ctx, &delivery, "first", template.GetName(), "build", nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
config, err := instance.client.Resource(configMapGVR).Namespace("delivery").Get(ctx, "actions", metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
config.Object["data"] = map[string]any{"build.fsx": "printfn \"new action\""}
|
||||
if _, err := instance.client.Resource(configMapGVR).Namespace("delivery").Update(ctx, config, metav1.UpdateOptions{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
templates, _, _ := unstructured.NestedSlice(boundTemplate(t, instance, "first").Object, "spec", "templates")
|
||||
patch := templates[0].(map[string]any)["podSpecPatch"].(string)
|
||||
data, err := yaml.YAMLToJSON([]byte(patch))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var body map[string]any
|
||||
if err := json.Unmarshal(data, &body); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
name := body["volumes"].([]any)[0].(map[string]any)["configMap"].(map[string]any)["name"].(string)
|
||||
captured, err := instance.client.Resource(configMapGVR).Namespace("delivery").Get(ctx, name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
value, _, _ := unstructured.NestedString(captured.Object, "data", "build.fsx")
|
||||
if value != "printfn \"old action\"" {
|
||||
t.Fatalf("nested podSpecPatch resolves changed actions: %q", value)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue