-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FR: Initial WRP Validation Framework #80
FR: Initial WRP Validation Framework #80
Conversation
## Overview related to xmidt-org#25, xmidt-org#78, xmidt-org/scytale#88, xmidt-org/talaria#153 s.t. we want a validation mechanism that is configurable by the application & verifies the spec. ### tl;rd This pr introduces the initial validation framework, where applications supply validators (satisfying the `Validator interface`) to `NewMsgTypeValidator` and then used to verify the spec. <details> <summary> Explanation</summary> Apps supply validators satisfying: ```go // Validator is a WRP validator that allows access to the Validate function. type Validator interface { Validate(m Message) error } ``` and listing which validators are used on known and unknown msg types (where unknown msg types are handled by `defaultValidator`): ```go var alwaysValidMsg ValidatorFunc = func(msg Message) error { return nil } msgv, err := NewMsgTypeValidator( // Validates known msg types m: map[MessageType]Validators{SimpleEventMessageType: {alwaysValidMsg}}, // Validates unknown msg types defaultValidator: alwaysValidMsg) err = msgv.Validate(Message{Type: SimpleEventMessageType}) // Known msg type err == nil // True err = msgv.Validate(Message{Type: CreateMessageType}) // Unknown msg type, uses defaultValidator err == nil // True ``` if a default validator is not provided, all unknown msg type will **fail** by default ```go var alwaysValidMsg ValidatorFunc = func(msg Message) error { return nil } msgv, err := NewMsgTypeValidator( // Omitted defaultValidator m: map[MessageType]Validators{SimpleEventMessageType: {alwaysInvalidMsg()}}) err = msgv.Validate(Message{Type: CreateMessageType}) err != nil // True ``` </details> <details> <summary>Type of Change(s)</summary> - Non-breaking Enhancement - All new and existing tests passed. </details> <details> <summary>Module Unit Testing: [PASSING]</summary> </details> <details> <summary>PR Affecting Unit Testing: validator_test.go [PASSING]</summary> ```console Running tool: /usr/local/bin/go test -timeout 30s -run ^(TestHelperValidators|TestMsgTypeValidator)$ github.com/xmidt-org/wrp-go/v3 === RUN TestHelperValidators === RUN TestHelperValidators/alwaysInvalidMsg --- PASS: TestHelperValidators (0.00s) --- PASS: TestHelperValidators/alwaysInvalidMsg (0.00s) === RUN TestMsgTypeValidator === RUN TestMsgTypeValidator/MsgTypeValidator_validate === RUN TestMsgTypeValidator/MsgTypeValidator_validate/known_message_type === RUN TestMsgTypeValidator/MsgTypeValidator_validate/unknown_message_type_with_provided_default_Validator === RUN TestMsgTypeValidator/MsgTypeValidator_validate/known_message_type_with_a_failing_Validator === RUN TestMsgTypeValidator/MsgTypeValidator_validate/unknown_message_type_without_provided_default_Validator === RUN TestMsgTypeValidator/MsgTypeValidator_factory === RUN TestMsgTypeValidator/MsgTypeValidator_factory/with_provided_default_Validator === RUN TestMsgTypeValidator/MsgTypeValidator_factory/without_provided_default_Validator === RUN TestMsgTypeValidator/MsgTypeValidator_factory/empty_list_of_message_type_Validators === RUN TestMsgTypeValidator/MsgTypeValidator_factory/empty_value_'m'_map[MessageType]Validators --- PASS: TestMsgTypeValidator (0.00s) --- PASS: TestMsgTypeValidator/MsgTypeValidator_validate (0.00s) --- PASS: TestMsgTypeValidator/MsgTypeValidator_validate/known_message_type (0.00s) --- PASS: TestMsgTypeValidator/MsgTypeValidator_validate/unknown_message_type_with_provided_default_Validator (0.00s) --- PASS: TestMsgTypeValidator/MsgTypeValidator_validate/known_message_type_with_a_failing_Validator (0.00s) --- PASS: TestMsgTypeValidator/MsgTypeValidator_validate/unknown_message_type_without_provided_default_Validator (0.00s) --- PASS: TestMsgTypeValidator/MsgTypeValidator_factory (0.00s) --- PASS: TestMsgTypeValidator/MsgTypeValidator_factory/with_provided_default_Validator (0.00s) --- PASS: TestMsgTypeValidator/MsgTypeValidator_factory/without_provided_default_Validator (0.00s) --- PASS: TestMsgTypeValidator/MsgTypeValidator_factory/empty_list_of_message_type_Validators (0.00s) --- PASS: TestMsgTypeValidator/MsgTypeValidator_factory/empty_value_'m'_map[MessageType]Validators (0.00s) PASS ok github.com/xmidt-org/wrp-go/v3 0.303s > Test run finished at 5/25/2022, 11:39:22 AM < ``` </details>
Codecov Report
@@ Coverage Diff @@
## main #80 +/- ##
==========================================
+ Coverage 49.30% 49.67% +0.37%
==========================================
Files 19 20 +1
Lines 3235 3259 +24
==========================================
+ Hits 1595 1619 +24
Misses 1469 1469
Partials 171 171
Continue to review full report at Codecov.
|
simplifies the usage of alwaysInvalidMsg
Return `ErrInvalidMsgTypeValidator` and `ErrInvalidMsgType` without additional details. We can add those error details downstream later
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good start, left some small suggestions.
Thx @kristinapathak for the feedback! 🍻
already covered by "Not found success"
…ort & added examples
@kristinapathak I added some testable examples just to try them out. it's pretty neat I can take them out if it's too early for doc examples. |
…om/denopink/wrp-go into denopink/FR-WRPValidationFramework
@denopink, example looks good! 👍 |
update examples Doc/var update Add test for `Nil default Validators` edge case update examples output doc update Updates based on PR review * exported alwaysValid * decoupled data structures leveraging `Validators` to `Validator` * added validateValidator Add multierr to Validator
d943b60
to
793d6f4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally the functions are looking good - I think I only focused on that last time, so have more unit tests comments now. 👍
* converted remaining `Validators` to `Validator` * remove func `validateValidator` * move nil checks to `Validate` func * remove Test struct * add new unexported field to check if `TypeValidato` is valid * add func `IsBad` to TypeValidato to say whether `TypeValidato` is valid * update tests for testAlwaysInvalid and testAlwaysValid * update tests names for `TestTypeValidator` * add tests for `Validators`
* [misunderstanding] Remove unexported field `isbad` from `TypeValidator` and its references * [misunderstanding] Remove `IsBad` func from `TypeValidator` * Use `assert.Zero/NotZero` funcs to test `TypeValidator`'s state
… `testAlwaysInvalid`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests look great! Realized I missed these two small suggestions earlier.
* rename `defaultValidators` to `defaultValidator` * replace `defaultValidators` variadic to `defaultValidator Validator` in `NewTypeValidator` func
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉
Overview
related to #25, #78, xmidt-org/scytale#88, xmidt-org/talaria#153 s.t. we want a validation mechanism that is configurable by clients & verifies the spec.
tl;dr
This pr introduces the initial validation framework, where clients supply validators (satisfying the
Validator interface
) toNewMsgTypeValidator
and then used to verify the spec.Explanation
Clients supply validators satisfying:
and listing which validators are used on known and unknown msg types (where unknown msg types are handled by
defaultValidator
):if a default validator is not provided, all unknown msg type will fail by default
Type of Change(s)