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 ¶
- type Scheme
- func (s *Scheme) AddValidationFunc(srcType any, ...)
- func (s *Scheme) Register(funcs ...func(*Scheme) error)
- func (s *Scheme) Test(t *testing.T) *ValidationTestBuilder
- func (s *Scheme) Validate(ctx context.Context, opts sets.Set[string], object any, subresources ...string) field.ErrorList
- func (s *Scheme) ValidateUpdate(ctx context.Context, opts sets.Set[string], object, oldObject any, ...) field.ErrorList
- type ValidationTestBuilder
- type ValidationTester
- func (v *ValidationTester) ExpectInvalid(want ...*field.Error) *ValidationTester
- func (v *ValidationTester) ExpectRegexpsByPath(regexpStringsByPath map[string][]string) *ValidationTester
- func (v *ValidationTester) ExpectValid() *ValidationTester
- func (v *ValidationTester) ExpectValidAt(fldPath *field.Path) *ValidationTester
- func (v *ValidationTester) ExpectValidateFalse(validateFalseArgs ...string) *ValidationTester
- func (v *ValidationTester) ExpectValidateFalseByPath(validateFalseArgsByPath map[string][]string) *ValidationTester
- func (v *ValidationTester) OldValue(oldValue any) *ValidationTester
- func (v *ValidationTester) OldValueFuzzed(oldValue any) *ValidationTester
- func (v *ValidationTester) Opts(opts sets.Set[string]) *ValidationTester
- func (v *ValidationTester) ValidateFalseArgsByPath() map[string][]string
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 (*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) Test ¶
func (s *Scheme) Test(t *testing.T) *ValidationTestBuilder
Test returns a ValidationTestBuilder for this scheme.
type ValidationTestBuilder ¶
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 ¶
func (v *ValidationTester) Opts(opts sets.Set[string]) *ValidationTester
Opts sets the ValidationOpts to use.
func (*ValidationTester) ValidateFalseArgsByPath ¶
func (v *ValidationTester) ValidateFalseArgsByPath() map[string][]string