github.com/redhat-appstudio/release-service@v0.0.0-20240507143925-083712697924/controllers/releaseplan/adapter_test.go (about) 1 /* 2 Copyright 2022. 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 http://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 releaseplan 18 19 import ( 20 "reflect" 21 "time" 22 23 toolkit "github.com/konflux-ci/operator-toolkit/loader" 24 . "github.com/onsi/ginkgo/v2" 25 . "github.com/onsi/gomega" 26 "github.com/redhat-appstudio/release-service/api/v1alpha1" 27 "github.com/redhat-appstudio/release-service/loader" 28 "k8s.io/apimachinery/pkg/api/meta" 29 30 applicationapiv1alpha1 "github.com/redhat-appstudio/application-api/api/v1alpha1" 31 tektonutils "github.com/redhat-appstudio/release-service/tekton/utils" 32 33 "k8s.io/apimachinery/pkg/api/errors" 34 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 35 "k8s.io/apimachinery/pkg/runtime/schema" 36 ctrl "sigs.k8s.io/controller-runtime" 37 ) 38 39 var _ = Describe("ReleasePlan adapter", Ordered, func() { 40 var ( 41 createReleasePlanAndAdapter func() *adapter 42 createResources func() 43 deleteResources func() 44 45 application *applicationapiv1alpha1.Application 46 releasePlanAdmission *v1alpha1.ReleasePlanAdmission 47 ) 48 49 AfterAll(func() { 50 deleteResources() 51 }) 52 53 BeforeAll(func() { 54 createResources() 55 }) 56 57 Context("When newAdapter is called", func() { 58 It("creates and return a new adapter", func() { 59 Expect(reflect.TypeOf(newAdapter(ctx, k8sClient, nil, loader.NewLoader(), &ctrl.Log))).To(Equal(reflect.TypeOf(&adapter{}))) 60 }) 61 }) 62 63 Context("When EnsureOwnerReferenceIsSet is called", func() { 64 var adapter *adapter 65 66 AfterEach(func() { 67 _ = adapter.client.Delete(ctx, adapter.releasePlan) 68 }) 69 70 BeforeEach(func() { 71 adapter = createReleasePlanAndAdapter() 72 }) 73 74 It("should not fail if the Application does not exist", func() { 75 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 76 { 77 ContextKey: loader.ApplicationContextKey, 78 Err: errors.NewNotFound(schema.GroupResource{}, ""), 79 }, 80 }) 81 82 result, err := adapter.EnsureOwnerReferenceIsSet() 83 Expect(result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 84 Expect(result.RequeueDelay).To(Equal(time.Minute)) 85 Expect(err).NotTo(HaveOccurred()) 86 Expect(adapter.releasePlan.OwnerReferences).To(HaveLen(0)) 87 }) 88 89 It("should set the owner reference", func() { 90 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 91 { 92 ContextKey: loader.ApplicationContextKey, 93 Resource: application, 94 }, 95 }) 96 97 Expect(adapter.releasePlan.OwnerReferences).To(HaveLen(0)) 98 result, err := adapter.EnsureOwnerReferenceIsSet() 99 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 100 Expect(err).NotTo(HaveOccurred()) 101 Expect(adapter.releasePlan.OwnerReferences).To(HaveLen(1)) 102 }) 103 104 It("should delete the releasePlan if the owner is deleted", func() { 105 newApplication := &applicationapiv1alpha1.Application{ 106 ObjectMeta: metav1.ObjectMeta{ 107 GenerateName: "application-", 108 Namespace: "default", 109 }, 110 } 111 Expect(k8sClient.Create(ctx, newApplication)).To(Succeed()) 112 113 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 114 { 115 ContextKey: loader.ApplicationContextKey, 116 Resource: newApplication, 117 }, 118 }) 119 120 Expect(adapter.releasePlan.OwnerReferences).To(HaveLen(0)) 121 result, err := adapter.EnsureOwnerReferenceIsSet() 122 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 123 Expect(err).NotTo(HaveOccurred()) 124 Expect(adapter.releasePlan.OwnerReferences).To(HaveLen(1)) 125 126 Expect(k8sClient.Delete(ctx, newApplication)).To(Succeed()) 127 _, err = adapter.loader.GetReleasePlan(ctx, k8sClient, &v1alpha1.Release{ 128 Spec: v1alpha1.ReleaseSpec{ 129 ReleasePlan: adapter.releasePlan.Name, 130 }, 131 }) 132 Expect(err).To(HaveOccurred()) 133 }) 134 }) 135 136 Context("When EnsureMatchingInformationIsSet is called", func() { 137 var adapter *adapter 138 139 AfterEach(func() { 140 _ = adapter.client.Delete(ctx, adapter.releasePlan) 141 }) 142 143 BeforeEach(func() { 144 adapter = createReleasePlanAndAdapter() 145 }) 146 147 It("should mark the ReleasePlan as unmatched if the ReleasePlanAdmission is not found", func() { 148 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 149 { 150 ContextKey: loader.MatchedReleasePlanAdmissionContextKey, 151 Err: errors.NewNotFound(schema.GroupResource{}, ""), 152 }, 153 }) 154 155 result, err := adapter.EnsureMatchingInformationIsSet() 156 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 157 Expect(err).NotTo(HaveOccurred()) 158 Expect(adapter.releasePlan.Status.ReleasePlanAdmission).To(Equal(v1alpha1.MatchedReleasePlanAdmission{})) 159 }) 160 161 It("should mark the ReleasePlan as matched", func() { 162 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 163 { 164 ContextKey: loader.MatchedReleasePlanAdmissionContextKey, 165 Resource: releasePlanAdmission, 166 }, 167 }) 168 169 result, err := adapter.EnsureMatchingInformationIsSet() 170 Expect(!result.RequeueRequest && !result.CancelRequest).To(BeTrue()) 171 Expect(err).NotTo(HaveOccurred()) 172 Expect(adapter.releasePlan.Status.ReleasePlanAdmission.Name).To(Equal( 173 releasePlanAdmission.Namespace + "/" + releasePlanAdmission.Name)) 174 }) 175 176 It("should not update the lastTransitionTime in the condition if the matched ReleasePlanAdmission hasn't changed", func() { 177 adapter.ctx = toolkit.GetMockedContext(ctx, []toolkit.MockData{ 178 { 179 ContextKey: loader.MatchedReleasePlanAdmissionContextKey, 180 Resource: releasePlanAdmission, 181 }, 182 }) 183 184 adapter.EnsureMatchingInformationIsSet() 185 condition := meta.FindStatusCondition(adapter.releasePlan.Status.Conditions, "Matched") 186 lastTransitionTime := condition.LastTransitionTime 187 adapter.EnsureMatchingInformationIsSet() 188 condition = meta.FindStatusCondition(adapter.releasePlan.Status.Conditions, "Matched") 189 Expect(condition.LastTransitionTime).To(Equal(lastTransitionTime)) 190 }) 191 }) 192 193 createReleasePlanAndAdapter = func() *adapter { 194 releasePlan := &v1alpha1.ReleasePlan{ 195 ObjectMeta: metav1.ObjectMeta{ 196 GenerateName: "releaseplan-", 197 Namespace: "default", 198 }, 199 Spec: v1alpha1.ReleasePlanSpec{ 200 Application: application.Name, 201 Target: "default", 202 }, 203 } 204 Expect(k8sClient.Create(ctx, releasePlan)).To(Succeed()) 205 releasePlan.Kind = "ReleasePlan" 206 207 return newAdapter(ctx, k8sClient, releasePlan, loader.NewMockLoader(), &ctrl.Log) 208 } 209 210 createResources = func() { 211 application = &applicationapiv1alpha1.Application{ 212 ObjectMeta: metav1.ObjectMeta{ 213 Name: "application", 214 Namespace: "default", 215 }, 216 Spec: applicationapiv1alpha1.ApplicationSpec{ 217 DisplayName: "application", 218 }, 219 } 220 Expect(k8sClient.Create(ctx, application)).To(Succeed()) 221 222 releasePlanAdmission = &v1alpha1.ReleasePlanAdmission{ 223 ObjectMeta: metav1.ObjectMeta{ 224 Name: "rpa", 225 Namespace: "default", 226 }, 227 Spec: v1alpha1.ReleasePlanAdmissionSpec{ 228 Applications: []string{application.Name}, 229 Origin: "default", 230 Pipeline: &tektonutils.Pipeline{ 231 PipelineRef: tektonutils.PipelineRef{ 232 Resolver: "bundles", 233 Params: []tektonutils.Param{ 234 {Name: "bundle", Value: "quay.io/some/bundle"}, 235 {Name: "name", Value: "release-pipeline"}, 236 {Name: "kind", Value: "pipeline"}, 237 }, 238 }, 239 }, 240 Policy: "policy", 241 }, 242 } 243 Expect(k8sClient.Create(ctx, releasePlanAdmission)).To(Succeed()) 244 } 245 246 deleteResources = func() { 247 Expect(k8sClient.Delete(ctx, application)).To(Succeed()) 248 Expect(k8sClient.Delete(ctx, releasePlanAdmission)).To(Succeed()) 249 } 250 251 })