knative.dev/pkg@v0.0.0-20260602142205-ac97e43f6622/reconciler/reconcile_common_test.go (about) 1 /* 2 Copyright 2020 The Knative Authors 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 https://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package reconciler 18 19 import ( 20 "context" 21 "testing" 22 "time" 23 24 corev1 "k8s.io/api/core/v1" 25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 27 "knative.dev/pkg/apis" 28 duckv1 "knative.dev/pkg/apis/duck/v1" 29 ) 30 31 type TestResource struct { 32 metav1.TypeMeta `json:",inline"` 33 metav1.ObjectMeta `json:"metadata,omitempty"` 34 35 Status duckv1.Status `json:"status"` 36 } 37 38 func (t *TestResource) SetDefaults(context.Context) { 39 t.Annotations = map[string]string{"default": "was set"} 40 } 41 42 func (t *TestResource) GetStatus() *duckv1.Status { 43 return &t.Status 44 } 45 46 func (*TestResource) GetConditionSet() apis.ConditionSet { 47 return apis.NewLivingConditionSet("Foo", "Bar") 48 } 49 50 func makeResource() *TestResource { 51 fooCond := apis.Condition{ 52 Type: "Foo", 53 Status: corev1.ConditionTrue, 54 Message: "Something something foo", 55 } 56 readyCond := apis.Condition{ 57 Type: apis.ConditionReady, 58 Status: corev1.ConditionTrue, 59 Message: "Something something bar", 60 } 61 62 return &TestResource{ 63 ObjectMeta: metav1.ObjectMeta{ 64 Generation: 42, 65 }, 66 67 Status: duckv1.Status{ 68 ObservedGeneration: 0, 69 Conditions: duckv1.Conditions{fooCond, readyCond}, 70 }, 71 } 72 } 73 74 func TestPreProcess(t *testing.T) { 75 resource := makeResource() 76 krShape := duckv1.KRShaped(resource) 77 78 PreProcessReconcile(context.Background(), krShape) 79 80 if resource.Annotations["default"] != "was set" { 81 t.Errorf("Expected default annotations set got=%v", resource.Annotations) 82 } 83 84 if rc := resource.Status.GetCondition("Ready"); rc.Status != "Unknown" { 85 t.Errorf("Expected unchanged ready status got=%s want=Unknown", rc.Status) 86 } 87 88 // Ensure Foo is untouched 89 if rc := resource.Status.GetCondition("Foo"); rc.Status != "True" { 90 t.Errorf("Expected dependant condition to remain got=%s want=True", rc.Status) 91 } 92 93 // Ensure Bar is initialized 94 if rc := resource.Status.GetCondition("Bar"); rc.Status != "True" { 95 t.Errorf("Expected conditions to be initialized got=%s want=True", rc.Status) 96 } 97 } 98 99 func TestPostProcessReconcileBumpsGeneration(t *testing.T) { 100 resource := makeResource() 101 102 krShape := duckv1.KRShaped(resource) 103 PostProcessReconcile(context.Background(), krShape, krShape) 104 105 if resource.Status.ObservedGeneration != resource.Generation { 106 t.Errorf("Expected observed generation bump got=%d want=%d", 107 resource.Status.ObservedGeneration, resource.Generation) 108 } 109 110 if krShape.GetStatus().ObservedGeneration != krShape.GetGeneration() { 111 t.Errorf("Expected observed generation bump got=%d want=%d", 112 resource.Status.ObservedGeneration, resource.Generation) 113 } 114 } 115 116 func TestPostProcessReconcileUpdatesTransitionTimes(t *testing.T) { 117 oldNow := apis.VolatileTime{Inner: metav1.NewTime(time.Now())} 118 resource := makeResource() 119 oldResource := makeResource() 120 // initialize old conditions with oldNow 121 oldResource.Status.Conditions[0].LastTransitionTime = oldNow 122 oldResource.Status.Conditions[1].LastTransitionTime = oldNow 123 // change the second condition, but keep the old timestamp. 124 resource.Status.Conditions[1].LastTransitionTime = oldNow 125 resource.Status.Conditions[1].Status = corev1.ConditionFalse 126 127 new := duckv1.KRShaped(resource) 128 old := duckv1.KRShaped(oldResource) 129 PostProcessReconcile(context.Background(), new, old) 130 131 unchangedCond := resource.Status.Conditions[0] 132 if unchangedCond.LastTransitionTime != oldNow { 133 t.Errorf("Expected unchanged condition to keep old timestamp. Got=%v Want=%v", 134 unchangedCond.LastTransitionTime, oldNow) 135 } 136 137 changedCond := resource.Status.Conditions[1] 138 if changedCond.LastTransitionTime == oldNow { 139 t.Errorf("Expected changed condition to get a new timestamp. Got=%v Want=%v", 140 changedCond.LastTransitionTime, oldNow) 141 } 142 }