From 2eefa7fc224aaff3fe3a687c9b33c4ed1d5432ac Mon Sep 17 00:00:00 2001 From: Yann Hamon Date: Sun, 29 Aug 2021 12:57:25 +0200 Subject: [PATCH] Update Junit tests, fix #45 --- pkg/output/junit.go | 10 +- pkg/output/junit_test.go | 175 ++++++++++---------------------- pkg/output/tap_test.go | 2 +- pkg/output/text_test.go | 2 +- pkg/validator/validator_test.go | 24 ++--- 5 files changed, 72 insertions(+), 141 deletions(-) diff --git a/pkg/output/junit.go b/pkg/output/junit.go index d19a817..19177d3 100644 --- a/pkg/output/junit.go +++ b/pkg/output/junit.go @@ -10,9 +10,10 @@ import ( "bufio" "encoding/xml" "fmt" - "github.com/yannh/kubeconform/pkg/validator" "io" "time" + + "github.com/yannh/kubeconform/pkg/validator" ) type TestSuiteCollection struct { @@ -105,8 +106,6 @@ func (o *junito) Write(result validator.Result) error { o.suites[result.Resource.Path] = suite } - suite.Tests++ - sig, _ := result.Resource.Signature() var objectName string if len(sig.Namespace) > 0 { @@ -121,21 +120,20 @@ func (o *junito) Write(result validator.Result) error { case validator.Valid: o.nValid++ case validator.Invalid: - suite.Failures++ o.nInvalid++ failure := TestCaseError{Message: result.Err.Error()} testCase.Failure = append(testCase.Failure, failure) case validator.Error: - suite.Errors++ o.nErrors++ testCase.Error = &TestCaseError{Message: result.Err.Error()} case validator.Skipped: - suite.Skipped++ testCase.Skipped = &TestCaseSkipped{} o.nSkipped++ case validator.Empty: + return nil } + suite.Tests++ suite.Cases = append(suite.Cases, testCase) return nil diff --git a/pkg/output/junit_test.go b/pkg/output/junit_test.go index 044e631..c8e6ee6 100644 --- a/pkg/output/junit_test.go +++ b/pkg/output/junit_test.go @@ -2,73 +2,36 @@ package output import ( "bytes" - "github.com/yannh/kubeconform/pkg/resource" "regexp" "testing" - "github.com/yannh/kubeconform/pkg/validator" + "github.com/yannh/kubeconform/pkg/resource" - "github.com/beevik/etree" + "github.com/yannh/kubeconform/pkg/validator" ) -func isNumeric(s string) bool { - matched, _ := regexp.MatchString("^\\d+(\\.\\d+)?$", s) - return matched -} - -func TestJUnitWrite(t *testing.T) { +func TestJunitWrite(t *testing.T) { for _, testCase := range []struct { name string withSummary bool isStdin bool verbose bool results []validator.Result - evaluate func(d *etree.Document) + expect string }{ { - "empty document", - false, + "an empty result", + true, false, false, []validator.Result{}, - func(d *etree.Document) { - root := d.FindElement("/testsuites") - if root == nil { - t.Errorf("Can't find root testsuite element") - return - } - for _, attr := range root.Attr { - switch attr.Key { - case "time": - case "tests": - case "failures": - case "disabled": - case "errors": - if !isNumeric(attr.Value) { - t.Errorf("Expected a number for /testsuites/@%s", attr.Key) - } - continue - case "name": - if attr.Value != "kubeconform" { - t.Errorf("Expected 'kubeconform' for /testsuites/@name") - } - continue - default: - t.Errorf("Unknown attribute /testsuites/@%s", attr.Key) - continue - } - } - suites := root.SelectElements("testsuite") - if len(suites) != 0 { - t.Errorf("No testsuite elements should be generated when there are no resources") - } - }, + "\n", }, { - "a single deployment, verbose, with summary", + "a single deployment, summary, no verbose", true, false, - true, + false, []validator.Result{ { Resource: resource.Resource{ @@ -77,84 +40,52 @@ func TestJUnitWrite(t *testing.T) { kind: Deployment metadata: name: "my-app" - namespace: "my-namespace" `), }, Status: validator.Valid, Err: nil, }, }, - func(d *etree.Document) { - suites := d.FindElements("//testsuites/testsuite") - if len(suites) != 1 { - t.Errorf("Expected exactly 1 testsuite element, got %d", len(suites)) - return - } - suite := suites[0] - for _, attr := range suite.Attr { - switch attr.Key { - case "name": - if attr.Value != "deployment.yml" { - t.Errorf("Test suite name should be the resource path") - } - continue - case "id": - if attr.Value != "1" { - t.Errorf("testsuite/@id should be 1") - } - continue - case "tests": - if attr.Value != "1" { - t.Errorf("testsuite/@tests should be 1") - } - continue - case "failures": - if attr.Value != "0" { - t.Errorf("testsuite/@failures should be 0") - } - continue - case "errors": - if attr.Value != "0" { - t.Errorf("testsuite/@errors should be 0") - } - continue - case "disabled": - if attr.Value != "0" { - t.Errorf("testsuite/@disabled should be 0") - } - continue - case "skipped": - if attr.Value != "0" { - t.Errorf("testsuite/@skipped should be 0") - } - continue - default: - t.Errorf("Unknown testsuite attribute %s", attr.Key) - continue - } - } - testcases := suite.SelectElements("testcase") - if len(testcases) != 1 { - t.Errorf("Expected exactly 1 testcase, got %d", len(testcases)) - return - } - testcase := testcases[0] - if testcase.SelectAttrValue("name", "") != "my-namespace/my-app" { - t.Errorf("Test case name should be namespace / name") - } - if testcase.SelectAttrValue("classname", "") != "Deployment@apps/v1" { - t.Errorf("Test case class name should be resource kind @ api version") - } - if testcase.SelectElement("skipped") != nil { - t.Errorf("skipped element should not be generated if the kind was not skipped") - } - if testcase.SelectElement("error") != nil { - t.Errorf("error element should not be generated if there was no error") - } - if len(testcase.SelectElements("failure")) != 0 { - t.Errorf("failure elements should not be generated if there were no failures") - } + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n", + }, + { + "a deployment, an empty resource, summary, no verbose", + true, + false, + false, + []validator.Result{ + { + Resource: resource.Resource{ + Path: "deployment.yml", + Bytes: []byte(`apiVersion: apps/v1 +kind: Deployment +metadata: + name: "my-app" +`), + }, + Status: validator.Valid, + Err: nil, + }, + { + Resource: resource.Resource{ + Path: "deployment.yml", + Bytes: []byte(`#A single comment`), + }, + Status: validator.Empty, + Err: nil, + }, }, + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n", }, } { w := new(bytes.Buffer) @@ -165,9 +96,13 @@ metadata: } o.Flush() - doc := etree.NewDocument() - doc.ReadFromString(w.String()) + // We remove the time, which will be different every time, before the comparison + output := w.String() + r := regexp.MustCompile(`time="[^"]*"`) + output = r.ReplaceAllString(output, "time=\"\"") - testCase.evaluate(doc) + if output != testCase.expect { + t.Errorf("%s - expected:, got:\n%s\n%s", testCase.name, testCase.expect, output) + } } } diff --git a/pkg/output/tap_test.go b/pkg/output/tap_test.go index 3cce4a2..8fce042 100644 --- a/pkg/output/tap_test.go +++ b/pkg/output/tap_test.go @@ -8,7 +8,7 @@ import ( "github.com/yannh/kubeconform/pkg/validator" ) -func TestTextWrite(t *testing.T) { +func TestTapWrite(t *testing.T) { for _, testCase := range []struct { name string withSummary bool diff --git a/pkg/output/text_test.go b/pkg/output/text_test.go index a3ca187..39df12a 100644 --- a/pkg/output/text_test.go +++ b/pkg/output/text_test.go @@ -8,7 +8,7 @@ import ( "github.com/yannh/kubeconform/pkg/validator" ) -func TestTapWrite(t *testing.T) { +func TestTextWrite(t *testing.T) { for _, testCase := range []struct { name string withSummary bool diff --git a/pkg/validator/validator_test.go b/pkg/validator/validator_test.go index cd8b2e4..d8e7751 100644 --- a/pkg/validator/validator_test.go +++ b/pkg/validator/validator_test.go @@ -1,13 +1,12 @@ package validator import ( - "github.com/yannh/kubeconform/pkg/registry" - "testing" + "github.com/yannh/kubeconform/pkg/registry" + "testing" - "github.com/yannh/kubeconform/pkg/resource" + "github.com/yannh/kubeconform/pkg/resource" ) - type mockRegistry struct { SchemaDownloader func() ([]byte, error) } @@ -22,14 +21,13 @@ func (m mockRegistry) DownloadSchema(resourceKind, resourceAPIVersion, k8sVersio return m.SchemaDownloader() } - func TestValidate(t *testing.T) { for i, testCase := range []struct { - name string - rawResource, schemaRegistry1 []byte - schemaRegistry2 []byte - ignoreMissingSchema bool - expect Status + name string + rawResource, schemaRegistry1 []byte + schemaRegistry2 []byte + ignoreMissingSchema bool + expect Status }{ { "valid resource", @@ -292,11 +290,11 @@ lastName: bar } { val := v{ opts: Opts{ - SkipKinds: map[string]struct{}{}, - RejectKinds: map[string]struct{}{}, + SkipKinds: map[string]struct{}{}, + RejectKinds: map[string]struct{}{}, IgnoreMissingSchemas: testCase.ignoreMissingSchema, }, - schemaCache: nil, + schemaCache: nil, schemaDownload: downloadSchema, regs: []registry.Registry{ newMockRegistry(func() ([]byte, error) {