github.com/oam-dev/kubevela@v1.9.11/pkg/appfile/dryrun/diff_test.go (about) 1 /* 2 Copyright 2021 The KubeVela 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 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 dryrun 18 19 import ( 20 "bytes" 21 "context" 22 "os" 23 24 . "github.com/onsi/ginkgo/v2" 25 . "github.com/onsi/gomega" 26 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 27 "k8s.io/apimachinery/pkg/types" 28 "sigs.k8s.io/yaml" 29 30 "github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1" 31 "github.com/oam-dev/kubevela/pkg/appfile" 32 ) 33 34 var _ = Describe("Test Live-Diff", func() { 35 appMultiChangesYAML := readDataFromFile("./testdata/diff-input-app-multichanges.yaml") 36 appNoChangeYAML := readDataFromFile("./testdata/diff-input-app-nochange.yaml") 37 appOnlyAddYAML := readDataFromFile("./testdata/diff-input-app-onlyadd.yaml") 38 appOnlyModifYAML := readDataFromFile("./testdata/diff-input-app-onlymodif.yaml") 39 appOnlyRemoveYAML := readDataFromFile("./testdata/diff-input-app-onlyremove.yaml") 40 41 appMultiChanges := new(v1beta1.Application) 42 appNoChange := new(v1beta1.Application) 43 appOnlyAdd := new(v1beta1.Application) 44 appOnlyModif := new(v1beta1.Application) 45 appOnlyRemove := new(v1beta1.Application) 46 47 origAppRevYAML := readDataFromFile("./testdata/diff-apprevision.yaml") 48 originalAppRev := new(v1beta1.ApplicationRevision) 49 50 diffAndPrint := func(app *v1beta1.Application) string { 51 By("Execute Live-diff") 52 diffResult, err := diffOpt.Diff(context.Background(), app, originalAppRev) 53 Expect(err).Should(BeNil()) 54 Expect(diffResult).ShouldNot(BeNil()) 55 56 By("Print diff result into buffer") 57 buff := &bytes.Buffer{} 58 reportOpt := NewReportDiffOption(10, buff) 59 reportOpt.PrintDiffReport(diffResult) 60 61 return buff.String() 62 } 63 64 BeforeEach(func() { 65 By("Prepare AppRevision data") 66 Expect(yaml.Unmarshal([]byte(origAppRevYAML), originalAppRev)).Should(Succeed()) 67 }) 68 69 It("Test app containing multiple changes(add/modify/remove/no)", func() { 70 Expect(yaml.Unmarshal([]byte(appMultiChangesYAML), appMultiChanges)).Should(Succeed()) 71 diffResultStr := diffAndPrint(appMultiChanges) 72 Expect(diffResultStr).Should(SatisfyAll( 73 ContainSubstring("Application (livediff-demo) has been modified(*)"), 74 ContainSubstring("Component (myweb-1) has been modified(*)"), 75 ContainSubstring("Component (myweb-1) / Trait (myingress/service) has been modified(*)"), 76 ContainSubstring("Component (myweb-1) / Trait (myingress/ingress) has been modified(*)"), 77 ContainSubstring("Component (myweb-2) has no change"), 78 ContainSubstring("Component (myweb-2) / Trait (myingress/service) has been added(+)"), 79 ContainSubstring("Component (myweb-2) / Trait (myingress/ingress) has been added(+)"), 80 ContainSubstring("Component (myweb-3) has been added(+)"), 81 ContainSubstring("Component (myweb-3) / Trait (myingress/service) has been added(+)"), 82 ContainSubstring("Component (myweb-3) / Trait (myingress/ingress) has been added(+)"), 83 )) 84 }) 85 86 It("Test no change", func() { 87 Expect(yaml.Unmarshal([]byte(appNoChangeYAML), appNoChange)).Should(Succeed()) 88 diffResultStr := diffAndPrint(appNoChange) 89 Expect(diffResultStr).Should(SatisfyAll( 90 ContainSubstring("Application (livediff-demo) has no change"), 91 ContainSubstring("Component (myweb-1) has no change"), 92 ContainSubstring("Component (myweb-1) / Trait (myingress/service) has no change"), 93 ContainSubstring("Component (myweb-1) / Trait (myingress/ingress) has no change"), 94 ContainSubstring("Component (myweb-2) has no change"), 95 )) 96 Expect(diffResultStr).ShouldNot(SatisfyAny( 97 ContainSubstring("added"), 98 ContainSubstring("removed"), 99 ContainSubstring("modified"), 100 )) 101 }) 102 103 It("Test only added change", func() { 104 Expect(yaml.Unmarshal([]byte(appOnlyAddYAML), appOnlyAdd)).Should(Succeed()) 105 diffResultStr := diffAndPrint(appOnlyAdd) 106 Expect(diffResultStr).Should(SatisfyAll( 107 ContainSubstring("Application (livediff-demo) has been modified"), 108 ContainSubstring("Component (myweb-1) has no change"), 109 ContainSubstring("Component (myweb-1) / Trait (myingress/service) has no change"), 110 ContainSubstring("Component (myweb-1) / Trait (myingress/ingress) has no change"), 111 ContainSubstring("Component (myweb-2) has no change"), 112 ContainSubstring("Component (myweb-2) / Trait (myingress/service) has been added"), 113 ContainSubstring("Component (myweb-2) / Trait (myingress/ingress) has been added"), 114 ContainSubstring("Component (myweb-3) has been added"), 115 ContainSubstring("Component (myweb-3) / Trait (myingress/service) has been added"), 116 ContainSubstring("Component (myweb-3) / Trait (myingress/ingress) has been added"), 117 )) 118 Expect(diffResultStr).ShouldNot(SatisfyAny( 119 ContainSubstring("removed"), 120 )) 121 }) 122 123 It("Test only modified change", func() { 124 Expect(yaml.Unmarshal([]byte(appOnlyModifYAML), appOnlyModif)).Should(Succeed()) 125 diffResultStr := diffAndPrint(appOnlyModif) 126 Expect(diffResultStr).Should(SatisfyAll( 127 ContainSubstring("Application (livediff-demo) has been modified"), 128 ContainSubstring("Component (myweb-1) has been modified"), 129 ContainSubstring("Component (myweb-1) / Trait (myingress/service) has been modified"), 130 ContainSubstring("Component (myweb-1) / Trait (myingress/ingress) has been modified"), 131 ContainSubstring("Component (myweb-2) has no change"), 132 )) 133 Expect(diffResultStr).ShouldNot(SatisfyAny( 134 ContainSubstring("removed"), 135 ContainSubstring("added"), 136 )) 137 }) 138 139 It("Test only removed change", func() { 140 Expect(yaml.Unmarshal([]byte(appOnlyRemoveYAML), appOnlyRemove)).Should(Succeed()) 141 diffResultStr := diffAndPrint(appOnlyRemove) 142 Expect(diffResultStr).Should(SatisfyAll( 143 ContainSubstring("Application (livediff-demo) has been modified"), 144 ContainSubstring("Component (myweb-1) has no change"), 145 ContainSubstring("Component (myweb-1) / Trait (myingress/service) has no change"), 146 ContainSubstring("Component (myweb-1) / Trait (myingress/ingress) has no change"), 147 ContainSubstring("Component (myweb-2) has been removed"), 148 )) 149 Expect(diffResultStr).ShouldNot(SatisfyAny( 150 ContainSubstring("added"), 151 )) 152 }) 153 154 It("Test renderless diff", func() { 155 liveDiffOpt := LiveDiffOption{ 156 DryRun: NewDryRunOption(k8sClient, cfg, pd, nil, false), 157 Parser: appfile.NewApplicationParser(k8sClient, pd), 158 } 159 applyFile := func(filename string, ns string) { 160 bs, err := os.ReadFile("./testdata/" + filename) 161 Expect(err).Should(Succeed()) 162 un := &unstructured.Unstructured{} 163 Expect(yaml.Unmarshal(bs, un)).Should(Succeed()) 164 un.SetNamespace(ns) 165 Expect(k8sClient.Create(context.Background(), un)).Should(Succeed()) 166 } 167 ctx := context.Background() 168 applyFile("diff-input-app-with-externals.yaml", "default") 169 applyFile("diff-apprevision.yaml", "default") 170 app := &v1beta1.Application{} 171 apprev := &v1beta1.ApplicationRevision{} 172 Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: "default", Name: "livediff-demo"}, app)).Should(Succeed()) 173 Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: "default", Name: "livediff-demo-v1"}, apprev)).Should(Succeed()) 174 reverse := false 175 runDiff := func() string { 176 a, b := LiveDiffObject{Application: app}, LiveDiffObject{ApplicationRevision: apprev} 177 if reverse { 178 a, b = b, a 179 } 180 de, err := liveDiffOpt.RenderlessDiff(ctx, a, b) 181 Expect(err).Should(Succeed()) 182 buff := &bytes.Buffer{} 183 reportOpt := NewReportDiffOption(-1, buff) 184 reportOpt.PrintDiffReport(de) 185 return buff.String() 186 } 187 Expect(runDiff()).Should(ContainSubstring("\"myworker\" not found")) 188 applyFile("td-myingress.yaml", "vela-system") 189 applyFile("cd-myworker.yaml", "vela-system") 190 applyFile("wd-ref-objects.yaml", "vela-system") 191 Expect(runDiff()).Should(ContainSubstring("\"deploy-livediff-demo\" not found")) 192 applyFile("external-workflow.yaml", "default") 193 Expect(runDiff()).Should(ContainSubstring("topology-local not found")) 194 applyFile("external-policy.yaml", "default") 195 Expect(runDiff()).Should(ContainSubstring("deployments.apps \"livediff-demo\" not found")) 196 applyFile("livediff-demo-deploy.yaml", "default") 197 e := runDiff() 198 _ = e 199 Expect(runDiff()).Should(SatisfyAll( 200 ContainSubstring("Application (livediff-demo) has been modified(*)"), 201 ContainSubstring("External Policy (topology-local) has been added(+)"), 202 ContainSubstring("External Workflow (deploy-livediff-demo) has been added(+)"), 203 ContainSubstring("Referred Object (apps/v1 Deployment default/livediff-demo) has been added(+)"), 204 )) 205 reverse = true 206 Expect(runDiff()).Should(SatisfyAll( 207 ContainSubstring("Application (livediff-demo) has been modified(*)"), 208 ContainSubstring("External Policy (topology-local) has been removed(-)"), 209 ContainSubstring("External Workflow (deploy-livediff-demo) has been removed(-)"), 210 ContainSubstring("Referred Object (apps/v1 Deployment default/livediff-demo) has been removed(-)"), 211 )) 212 }) 213 214 })