mirror of
https://github.com/yannh/kubeconform.git
synced 2026-02-11 14:09:21 +00:00
Update Junit tests, fix #45
This commit is contained in:
parent
1b01a42488
commit
2eefa7fc22
5 changed files with 72 additions and 141 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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{
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue