Skip to content

Commit

Permalink
Update Junit tests, fix #45
Browse files Browse the repository at this point in the history
  • Loading branch information
yannh committed Aug 29, 2021
1 parent 1b01a42 commit 2eefa7f
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 141 deletions.
10 changes: 4 additions & 6 deletions pkg/output/junit.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -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
Expand Down
175 changes: 55 additions & 120 deletions pkg/output/junit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
},
"<testsuites name=\"kubeconform\" time=\"\" tests=\"0\" failures=\"0\" disabled=\"0\" errors=\"0\"></testsuites>\n",
},
{
"a single deployment, verbose, with summary",
"a single deployment, summary, no verbose",
true,
false,
true,
false,
[]validator.Result{
{
Resource: resource.Resource{
Expand All @@ -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")
}
"<testsuites name=\"kubeconform\" time=\"\" tests=\"1\" failures=\"0\" disabled=\"0\" errors=\"0\">\n" +
" <testsuite name=\"deployment.yml\" id=\"1\" tests=\"1\" failures=\"0\" errors=\"0\" disabled=\"0\" skipped=\"0\">\n" +
" <properties></properties>\n" +
" <testcase name=\"my-app\" classname=\"Deployment@apps/v1\"></testcase>\n" +
" </testsuite>\n" +
"</testsuites>\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,
},
},
"<testsuites name=\"kubeconform\" time=\"\" tests=\"1\" failures=\"0\" disabled=\"0\" errors=\"0\">\n" +
" <testsuite name=\"deployment.yml\" id=\"1\" tests=\"1\" failures=\"0\" errors=\"0\" disabled=\"0\" skipped=\"0\">\n" +
" <properties></properties>\n" +
" <testcase name=\"my-app\" classname=\"Deployment@apps/v1\"></testcase>\n" +
" </testsuite>\n" +
"</testsuites>\n",
},
} {
w := new(bytes.Buffer)
Expand All @@ -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)
}
}
}
2 changes: 1 addition & 1 deletion pkg/output/tap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion pkg/output/text_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
24 changes: 11 additions & 13 deletions pkg/validator/validator_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
Expand All @@ -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",
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 2eefa7f

Please sign in to comment.