Last active
September 27, 2025 00:29
-
-
Save aaron-prindle/7dbe934092717d1b047d0e7aba5dc171 to your computer and use it in GitHub Desktop.
declarative validation error matcher path translation feature - benchmark test code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import ( | |
| "fmt" | |
| "regexp" | |
| "testing" | |
| ) | |
| // generateNormalizationRules is a helper function to create a slice of N pre-compiled normalization rules. | |
| func generateNormalizationRules(n int) []NormalizationRule { | |
| rules := make([]NormalizationRule, n) | |
| for i := 0; i < n; i++ { | |
| // Create a regex pattern and a corresponding replacement string. | |
| // Example: `spec\.devices\.requests\[(\d+)\]\.allocationMode_99` -> "spec.devices.requests[$1].exactly.allocationMode_99" | |
| pattern := fmt.Sprintf(`spec\.devices\.requests\[(\d+)\]\.allocationMode_%d`, i) | |
| replacement := fmt.Sprintf("spec.devices.requests[$1].exactly.allocationMode_%d", i) | |
| rules[i] = NormalizationRule{ | |
| Regexp: regexp.MustCompile(pattern), | |
| Replacement: replacement, | |
| } | |
| } | |
| return rules | |
| } | |
| func BenchmarkErrorMatcher_Matches_PathNormalization(b *testing.B) { | |
| baseErr := func() *Error { | |
| return &Error{Type: ErrorTypeInvalid, Detail: "some detail"} | |
| } | |
| benchmarks := []struct { | |
| name string | |
| numNormalizationRules int | |
| setupMatcher func(n int) ErrorMatcher | |
| getWantAndGotErrs func(n int) (*Error, *Error) | |
| }{ | |
| { | |
| name: "NoNormalization", | |
| numNormalizationRules: 0, | |
| setupMatcher: func(n int) ErrorMatcher { | |
| // Matcher with ByField but no normalization rules. | |
| return ErrorMatcher{}.ByField() | |
| }, | |
| getWantAndGotErrs: func(n int) (*Error, *Error) { | |
| // Simple case where fields do not match, and there's no normalization logic to run. | |
| want := baseErr() | |
| want.Field = "spec.devices.requests[0].allocationMode" | |
| got := baseErr() | |
| got.Field = "spec.devices.requests[0].someOtherField" | |
| return want, got | |
| }, | |
| }, | |
| { | |
| name: "100Rules_WorstCase", | |
| numNormalizationRules: 100, | |
| setupMatcher: func(n int) ErrorMatcher { | |
| rules := generateNormalizationRules(n) | |
| return ErrorMatcher{}.ByFieldNormalized(rules) | |
| }, | |
| getWantAndGotErrs: func(n int) (*Error, *Error) { | |
| // Create errors that will match the LAST normalization rule, | |
| // forcing the matcher to iterate through all N regex patterns. | |
| idx := n - 1 | |
| want := baseErr() | |
| want.Field = fmt.Sprintf("spec.devices.requests[0].allocationMode_%d", idx) | |
| got := baseErr() | |
| got.Field = fmt.Sprintf("spec.devices.requests[0].exactly.allocationMode_%d", idx) | |
| return want, got | |
| }, | |
| }, | |
| { | |
| name: "1000Rules_WorstCase", | |
| numNormalizationRules: 1000, | |
| setupMatcher: func(n int) ErrorMatcher { | |
| rules := generateNormalizationRules(n) | |
| return ErrorMatcher{}.ByFieldNormalized(rules) | |
| }, | |
| getWantAndGotErrs: func(n int) (*Error, *Error) { | |
| // Create errors that will match the LAST normalization rule. | |
| idx := n - 1 | |
| want := baseErr() | |
| want.Field = fmt.Sprintf("spec.devices.requests[0].allocationMode_%d", idx) | |
| got := baseErr() | |
| got.Field = fmt.Sprintf("spec.devices.requests[0].exactly.allocationMode_%d", idx) | |
| return want, got | |
| }, | |
| }, | |
| } | |
| for _, bm := range benchmarks { | |
| b.Run(bm.name, func(b *testing.B) { | |
| // Setup is done outside the timer. | |
| matcher := bm.setupMatcher(bm.numNormalizationRules) | |
| want, got := bm.getWantAndGotErrs(bm.numNormalizationRules) | |
| b.ResetTimer() | |
| // The loop will run the Matches function b.N times. | |
| // The initial `want.Field != got.Field` check will fail, triggering the path normalization logic. | |
| for i := 0; i < b.N; i++ { | |
| matcher.Matches(want, got) | |
| } | |
| }) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment