Skip to content

Commit

Permalink
test: refactor error cases helpers
Browse files Browse the repository at this point in the history
Signed-off-by: Mike Beaumont <mjboamail@gmail.com>
  • Loading branch information
michaelbeaumont committed Jan 10, 2023
1 parent 570d9f7 commit f92acc8
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 114 deletions.
18 changes: 3 additions & 15 deletions pkg/core/resources/apis/mesh/gateway_route_validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,13 @@ import (
. "github.com/onsi/ginkgo/v2"

. "github.com/kumahq/kuma/pkg/core/resources/apis/mesh"
"github.com/kumahq/kuma/pkg/core/resources/model"
"github.com/kumahq/kuma/pkg/core/validators"
_ "github.com/kumahq/kuma/pkg/plugins/runtime/gateway/register"
. "github.com/kumahq/kuma/pkg/test/resources"
)

// MeshGatewayRouteGenerator is a ResourceGenerator that creates MeshGatewayResource objects.
type MeshGatewayRouteGenerator func() *MeshGatewayRouteResource

func (g MeshGatewayRouteGenerator) New() model.Resource {
if g != nil {
return g()
}

return nil
}

var _ = Describe("MeshGatewayRoute", func() {
DescribeValidCases(MeshGatewayRouteGenerator(NewMeshGatewayRouteResource),

DescribeValidCases(NewMeshGatewayRouteResource,
Entry("HTTP route", `
type: MeshGatewayRoute
name: route
Expand Down Expand Up @@ -115,7 +103,7 @@ conf:
`),
)

DescribeErrorCases(MeshGatewayRouteGenerator(NewMeshGatewayRouteResource),
DescribeErrorCases(NewMeshGatewayRouteResource,
ErrorCase("missing conf", validators.Violation{
Field: "conf",
Message: "cannot be empty",
Expand Down
16 changes: 3 additions & 13 deletions pkg/core/resources/apis/mesh/gateway_validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,12 @@ import (
"github.com/kumahq/kuma/pkg/core/resources/model"
"github.com/kumahq/kuma/pkg/core/validators"
_ "github.com/kumahq/kuma/pkg/plugins/runtime/gateway/register"
. "github.com/kumahq/kuma/pkg/test/resources"
)

// GatewayGenerateor is a ResourceGenerator that creates GatewayResource objects.
type GatewayGenerator func() *MeshGatewayResource

func (g GatewayGenerator) New() model.Resource {
if g != nil {
return g()
}

return nil
}

var _ = Describe("Gateway", func() {
DescribeValidCases(
GatewayGenerator(NewMeshGatewayResource),
NewMeshGatewayResource,
Entry("HTTPS listener", `
type: MeshGateway
name: gateway
Expand Down Expand Up @@ -112,7 +102,7 @@ conf:
)

DescribeErrorCases(
GatewayGenerator(NewMeshGatewayResource),
NewMeshGatewayResource,
ErrorCase("doesn't have any selectors",
validators.Violation{
Field: `selectors`,
Expand Down
86 changes: 0 additions & 86 deletions pkg/core/resources/apis/mesh/mesh_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,95 +6,9 @@ import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

core_model "github.com/kumahq/kuma/pkg/core/resources/model"
"github.com/kumahq/kuma/pkg/core/validators"
"github.com/kumahq/kuma/pkg/test"
)

func TestMesh(t *testing.T) {
test.RunSpecs(t, "Mesh Suite")
}

// ResourceGenerator creates a resource of a pre-defined type.
type ResourceGenerator interface {
New() core_model.Resource
}

// ResourceValidationCase captures a resource YAML and any corresponding validation error.
type ResourceValidationCase struct {
Resource string
Violations []validators.Violation
}

// DescribeValidCases creates a Ginkgo table test for the given entries,
// where each entry is a valid YAML resource. It ensures that each entry
// can be successfully validated.
func DescribeValidCases(generator ResourceGenerator, cases ...TableEntry) {
DescribeTable(
"should pass validation",
func(given string) {
// setup
resource := generator.New()

// when
err := core_model.FromYAML([]byte(given), resource.GetSpec())

// then
Expect(err).ToNot(HaveOccurred())

// when
verr := core_model.Validate(resource)

// then
Expect(verr).ToNot(HaveOccurred())
},
cases)
}

// DescribeErrorCases creates a Ginkgo table test for the given entries, where each entry
// is a ResourceValidationCase that contains an invalid resource YAML and the corresponding
// validation error.
func DescribeErrorCases(generator ResourceGenerator, cases ...TableEntry) {
DescribeTable(
"should validate all fields and return as many individual errors as possible",
func(given ResourceValidationCase) {
// setup
resource := generator.New()

// when
Expect(
core_model.FromYAML([]byte(given.Resource), resource.GetSpec()),
).ToNot(HaveOccurred())

expected := validators.ValidationError{
Violations: given.Violations,
}

// then
err := core_model.Validate(resource).(*validators.ValidationError)
Expect(err.Violations).To(ConsistOf(expected.Violations))
},
cases,
)
}

// ErrorCase is a helper that generates a table entry for DescribeErrorCases.
func ErrorCase(description string, err validators.Violation, yaml string) TableEntry {
return Entry(
description,
ResourceValidationCase{
Violations: []validators.Violation{err},
Resource: yaml,
},
)
}

func ErrorCases(description string, errs []validators.Violation, yaml string) TableEntry {
return Entry(
description,
ResourceValidationCase{
Violations: errs,
Resource: yaml,
},
)
}
93 changes: 93 additions & 0 deletions pkg/test/resources/validation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package resources

import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

core_model "github.com/kumahq/kuma/pkg/core/resources/model"
"github.com/kumahq/kuma/pkg/core/validators"
)

// ResourceGenerator creates a resource of a pre-defined type.
type ResourceGenerator interface {
New() core_model.Resource
}

// ResourceValidationCase captures a resource YAML and any corresponding validation error.
type ResourceValidationCase struct {
Resource string
Violations []validators.Violation
}

// DescribeValidCases creates a Ginkgo table test for the given entries,
// where each entry is a valid YAML resource. It ensures that each entry
// can be successfully validated.
func DescribeValidCases[T core_model.Resource](generator func() T, cases ...TableEntry) {
DescribeTable(
"should pass validation",
func(given string) {
// setup
resource := generator()

// when
err := core_model.FromYAML([]byte(given), resource.GetSpec())

// then
Expect(err).ToNot(HaveOccurred())

// when
verr := core_model.Validate(resource)

// then
Expect(verr).ToNot(HaveOccurred())
},
cases)
}

// DescribeErrorCases creates a Ginkgo table test for the given entries, where each entry
// is a ResourceValidationCase that contains an invalid resource YAML and the corresponding
// validation error.
func DescribeErrorCases[T core_model.Resource](generator func() T, cases ...TableEntry) {
DescribeTable(
"should validate all fields and return as many individual errors as possible",
func(given ResourceValidationCase) {
// setup
resource := generator()

// when
Expect(
core_model.FromYAML([]byte(given.Resource), resource.GetSpec()),
).ToNot(HaveOccurred())

expected := validators.ValidationError{
Violations: given.Violations,
}

// then
err := core_model.Validate(resource).(*validators.ValidationError)
Expect(err.Violations).To(ConsistOf(expected.Violations))
},
cases,
)
}

// ErrorCase is a helper that generates a table entry for DescribeErrorCases.
func ErrorCase(description string, err validators.Violation, yaml string) TableEntry {
return Entry(
description,
ResourceValidationCase{
Violations: []validators.Violation{err},
Resource: yaml,
},
)
}

func ErrorCases(description string, errs []validators.Violation, yaml string) TableEntry {
return Entry(
description,
ResourceValidationCase{
Violations: errs,
Resource: yaml,
},
)
}

0 comments on commit f92acc8

Please sign in to comment.