testscheme

package
v0.4.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 11, 2025 License: Apache-2.0 Imports: 21 Imported by: 0

Documentation

Overview

Package testscheme provides a scheme implementation and test utilities useful for writing output_tests for validation-gen.

For an output test to use this scheme, it should be located in a dedicated go package. The go package should have validation-gen and this test scheme enabled and must declare a 'localSchemeBuilder' using the 'testscheme.New()' function. For example:

// +k8s:validation-gen-scheme-registry=k8s.io/code-generator/cmd/validation-gen/testscheme.Scheme
// +k8s:validation-gen
package example
import "k8s.io/code-generator/cmd/validation-gen/testscheme"
var localSchemeBuilder = testscheme.New()

This is sufficient for validation-gen to generate a `zz_generated.validations.go` for the types in the package that compile.

With the scheme enabled. An output test may be tested either by handwritten test code or by generated test fixtures.

For example, to test by hand. The testschema provides utilities to create a value and assert that the expected errors are returned when the value is validated:

 func Test(t *testing.T) {
	  st := localSchemeBuilder.Test(t)
	  st.Value(&T1{
		E0:  "x",
		PE0: pointer.To(E0("y")),
	  }).ExpectInvalid(
		field.NotSupported(field.NewPath("e0"), "x", []string{EnumValue1, EnumValue2}),
		field.NotSupported(field.NewPath("pe0"), "y", []string{EnumValue1, EnumValue2}))}
 }

Tests fixtures can also be enabled. For example:

// ...
// +k8s:validation-gen-test-fixture=validateFalse
// package example

When a test fixture is enabled, a `zz_generated.validations_test.go` file will be generated test for all the registered types in the package according to the behavior of the named test fixture(s).

Test Fixtures:

`validateFalse` - This test fixture executes validation of each registered type and accumulates all `validateFalse` validation errors. For example:

type T1 struct {
	// +k8s:validateFalse="field T1.S"
	S string `json:"s"`
	// +k8s:validateFalse="field T1.T"
	T T2 `json:"t"`
}

The above `example.T1` test type has two validated fields: `s` and 't'. The fields are named according to the Go "json" field tag, and each has a validation error identifier provided by `+k8s:validateFalse=<identifier>`.

The `validateFalse` test fixture will validate an instance of `example.T1`, generated using fuzzed data, and then group the validation errors by field name. Represented in JSON like:

{
  "*example.T1": {
    "s": [
      "field T1.S"
    ],
    "t": [
      "field T1.T"
    ]
  }
}

This validation error data contains an object for each registered type, keyed by type name. For each registered type, the validation errors from `+k8s:validateFalse` tags are grouped by field path with all validation error identifiers collected into a list.

This data is compared with the expected validation results that are defined in a `testdata/validate-false.json` file in the same package, and any differences are reported as test errors.

`testdata/validate-false.json` can be generated automatically by setting the `UPDATE_VALIDATION_GEN_FIXTURE_DATA=true` environment variable to true when running the tests.

Test authors that generated `testdata/validate-false.json` are expected to ensure that file is correct before checking it in to source control.

The fuzzed data is generated pseudo-randomly with a consistent seed, with all nilable fields se to a value, and with a single entry for each map and a single element for each slice.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Scheme

type Scheme struct {
	// contains filtered or unexported fields
}

Scheme is similar to runtime.Scheme, but for validation testing purposes. Scheme only supports validation, supports registration of any type (not just runtime.Object) and implements Register directly, allowing it to also be used as a scheme builder. Must only be used with tests that perform all registration before calls to validate.

func New

func New() *Scheme

New creates a new Scheme.

func (*Scheme) AddValidationFunc

func (s *Scheme) AddValidationFunc(srcType any, fn func(ctx context.Context, op operation.Operation, object, oldObject interface{}, subresources ...string) field.ErrorList)

AddValidationFunc registers a validation function. Last writer wins.

func (*Scheme) Register

func (s *Scheme) Register(funcs ...func(*Scheme) error)

Register adds a scheme setup function to the list.

func (*Scheme) Test

func (s *Scheme) Test(t *testing.T) *ValidationTestBuilder

Test returns a ValidationTestBuilder for this scheme.

func (*Scheme) Validate

func (s *Scheme) Validate(ctx context.Context, opts sets.Set[string], object any, subresources ...string) field.ErrorList

Validate validates an object using the registered validation function.

func (*Scheme) ValidateUpdate

func (s *Scheme) ValidateUpdate(ctx context.Context, opts sets.Set[string], object, oldObject any, subresources ...string) field.ErrorList

ValidateUpdate validates an update to an object using the registered validation function.

type ValidationTestBuilder

type ValidationTestBuilder struct {
	*testing.T
	// contains filtered or unexported fields
}

ValidationTestBuilder provides convenience functions to build validation tests.

func (*ValidationTestBuilder) ValidateFixtures

func (s *ValidationTestBuilder) ValidateFixtures()

ValidateFixtures ensures that the validation errors of all registered types match what is expected by the test fixture files. For each registered type, a value is created for the type, and populated by fuzzing the value, before validating the type. See ValueFuzzed for details.

If the UPDATE_VALIDATION_GEN_FIXTURE_DATA=true environment variable is set, test fixture files are created or overridden.

Fixtures:

  • validate-false.json: defines a map of registered type to a map of field path to +validateFalse validations args that are expected to be returned as errors when the type is validated.

func (*ValidationTestBuilder) Value

func (s *ValidationTestBuilder) Value(value any) *ValidationTester

Value returns a ValidationTester for the given value. The value must be a registered with the scheme for validation.

func (*ValidationTestBuilder) ValueFuzzed

func (s *ValidationTestBuilder) ValueFuzzed(value any) *ValidationTester

ValueFuzzed automatically populates the given value using a deterministic filler. The filler sets pointers to values and always includes a two map keys and slice elements.

type ValidationTester

type ValidationTester struct {
	*ValidationTestBuilder
	// contains filtered or unexported fields
}

ValidationTester provides convenience functions to define validation tests for a validatable value.

func (*ValidationTester) ExpectInvalid

func (v *ValidationTester) ExpectInvalid(want ...*field.Error) *ValidationTester

ExpectInvalid validates the value and calls t.Errorf if want does not match the actual errors. Returns ValidationTester to support call chaining.

func (*ValidationTester) ExpectRegexpsByPath

func (v *ValidationTester) ExpectRegexpsByPath(regexpStringsByPath map[string][]string) *ValidationTester

func (*ValidationTester) ExpectValid

func (v *ValidationTester) ExpectValid() *ValidationTester

ExpectValid validates the value and calls t.Errorf if any validation errors are returned. Returns ValidationTester to support call chaining.

func (*ValidationTester) ExpectValidAt

func (v *ValidationTester) ExpectValidAt(fldPath *field.Path) *ValidationTester

ExpectValidAt validates the value and calls t.Errorf for any validation errors at the given path. Returns ValidationTester to support call chaining.

func (*ValidationTester) ExpectValidateFalse

func (v *ValidationTester) ExpectValidateFalse(validateFalseArgs ...string) *ValidationTester

ExpectValidateFalse validates the value and calls t.Errorf if the actual errors do not match the given validateFalseArgs. For example, if the value to validate has a single `+validateFalse="type T1"` tag, ExpectValidateFalse("type T1") will pass. Returns ValidationTester to support call chaining.

func (*ValidationTester) ExpectValidateFalseByPath

func (v *ValidationTester) ExpectValidateFalseByPath(validateFalseArgsByPath map[string][]string) *ValidationTester

func (*ValidationTester) OldValue

func (v *ValidationTester) OldValue(oldValue any) *ValidationTester

OldValue sets the oldValue for this ValidationTester. When oldValue is set to a non-nil value, update validation will be used to test validation. oldValue must be the same type as value. Returns ValidationTester to support call chaining.

func (*ValidationTester) OldValueFuzzed

func (v *ValidationTester) OldValueFuzzed(oldValue any) *ValidationTester

OldValueFuzzed automatically populates the given value using a deterministic filler. The filler sets pointers to values and always includes a two map keys and slice elements.

func (*ValidationTester) Opts

Opts sets the ValidationOpts to use.

func (*ValidationTester) ValidateFalseArgsByPath

func (v *ValidationTester) ValidateFalseArgsByPath() map[string][]string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL