mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-14 11:57:48 +00:00
feat: Show textual diff when generate test fails (#11674)
* feat: Show textual diff when generate test fails Signed-off-by: Tomas Aschan <tomasl@spotify.com> * Tweak verbosity level for diff output Signed-off-by: Tomas Aschan <tomasl@spotify.com> * Display a rich diff of the expected and actual resources with --detailed-results Signed-off-by: Tomas Aschan <tomasl@spotify.com> --------- Signed-off-by: Tomas Aschan <tomasl@spotify.com>
This commit is contained in:
parent
7223d44327
commit
8746a8ffbb
3 changed files with 24 additions and 10 deletions
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/report"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/test/filter"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
"github.com/sergi/go-diff/diffmatchpatch"
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
@ -163,21 +164,25 @@ func checkResult(test v1alpha1.TestResult, fs billy.Filesystem, resoucePath stri
|
|||
patchedResource = test.PatchedResources
|
||||
}
|
||||
if patchedResource != "" {
|
||||
equals, err := getAndCompareResource([]*unstructured.Unstructured{&response.PatchedResource}, fs, filepath.Join(resoucePath, patchedResource))
|
||||
equals, diff, err := getAndCompareResource([]*unstructured.Unstructured{&response.PatchedResource}, fs, filepath.Join(resoucePath, patchedResource))
|
||||
if err != nil {
|
||||
return false, err.Error(), "Resource error"
|
||||
}
|
||||
if !equals {
|
||||
return false, "Patched resource didn't match the patched resource in the test result", "Resource diff"
|
||||
dmp := diffmatchpatch.New()
|
||||
legend := dmp.DiffPrettyText(dmp.DiffMain("only in expected", "only in actual", false))
|
||||
return false, fmt.Sprintf("Patched resource didn't match the patched resource in the test result\n(%s)\n\n%s", legend, diff), "Resource diff"
|
||||
}
|
||||
}
|
||||
if test.GeneratedResource != "" {
|
||||
equals, err := getAndCompareResource(rule.GeneratedResources(), fs, filepath.Join(resoucePath, test.GeneratedResource))
|
||||
equals, diff, err := getAndCompareResource(rule.GeneratedResources(), fs, filepath.Join(resoucePath, test.GeneratedResource))
|
||||
if err != nil {
|
||||
return false, err.Error(), "Resource error"
|
||||
}
|
||||
if !equals {
|
||||
return false, "Generated resource didn't match the generated resource in the test result", "Resource diff"
|
||||
dmp := diffmatchpatch.New()
|
||||
legend := dmp.DiffPrettyText(dmp.DiffMain("only in expected", "only in actual", false))
|
||||
return false, fmt.Sprintf("Generated resource didn't match the generated resource in the test result\n(%s)\n\n%s", legend, diff), "Resource diff"
|
||||
}
|
||||
}
|
||||
result := report.ComputePolicyReportResult(false, response, rule)
|
||||
|
|
|
@ -4,14 +4,17 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/go-git/go-billy/v5"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/log"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/resource"
|
||||
"github.com/sergi/go-diff/diffmatchpatch"
|
||||
"gopkg.in/yaml.v2"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
)
|
||||
|
||||
func getAndCompareResource(actualResources []*unstructured.Unstructured, fs billy.Filesystem, path string) (bool, error) {
|
||||
func getAndCompareResource(actualResources []*unstructured.Unstructured, fs billy.Filesystem, path string) (bool, string, error) {
|
||||
expectedResources, err := resource.GetResourceFromPath(fs, path)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("error: failed to load resource (%s)", err)
|
||||
return false, "", fmt.Errorf("error: failed to load resource (%s)", err)
|
||||
}
|
||||
|
||||
expectedResourcesMap := map[string]unstructured.Unstructured{}
|
||||
|
@ -32,11 +35,17 @@ func getAndCompareResource(actualResources []*unstructured.Unstructured, fs bill
|
|||
resource.FixupGenerateLabels(r)
|
||||
equals, err := resource.Compare(r, expectedResourcesMap[r.GetNamespace()+"/"+r.GetName()], true)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("error: failed to compare resources (%s)", err)
|
||||
return false, "", fmt.Errorf("error: failed to compare resources (%s)", err)
|
||||
}
|
||||
if !equals {
|
||||
return false, nil
|
||||
log.Log.V(4).Info("Resource diff", "expected", expectedResourcesMap[r.GetNamespace()+"/"+r.GetName()], "actual", r)
|
||||
es, _ := yaml.Marshal(expectedResourcesMap[r.GetNamespace()+"/"+r.GetName()])
|
||||
as, _ := yaml.Marshal(r)
|
||||
dmp := diffmatchpatch.New()
|
||||
diffs := dmp.DiffMain(string(es), string(as), false)
|
||||
log.Log.V(4).Info("\n" + dmp.DiffPrettyText(diffs) + "\n")
|
||||
return false, dmp.DiffPrettyText(diffs), nil
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
return true, "", nil
|
||||
}
|
||||
|
|
2
go.mod
2
go.mod
|
@ -318,7 +318,7 @@ require (
|
|||
github.com/sassoftware/relic v7.2.1+incompatible // indirect
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.8.0 // indirect
|
||||
github.com/segmentio/ksuid v1.0.4 // indirect
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3
|
||||
github.com/shibumi/go-pathspec v1.3.0 // indirect
|
||||
github.com/shopspring/decimal v1.4.0 // indirect
|
||||
github.com/sigstore/fulcio v1.6.3 // indirect
|
||||
|
|
Loading…
Reference in a new issue