fix: preserve fractional scale target minimum - #4067
Elvand-Lie wants to merge 1 commit into
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: Elvand-Lie The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Hi @Elvand-Lie. Thanks for your PR. I'm waiting for a knative member to verify that this patch is reasonable to test. If it is, they should reply with Tip We noticed you've done this a few times! Consider joining the org to skip this step and gain Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
Thanks for the contribution. I think this will need a rebase as the |
b965ed0 to
71bbb54
Compare
The func.yaml schema generator published a lower bound that was looser
than the validation actually enforced. Reflection truncates the
fractional minimum declared on KPAScaleOptions.Target, so the schema said
"target": { "minimum": 0 }
where ValidateScale requires target >= 0.01. A func.yaml with a scale
target of 0.001 therefore validated against the schema and was rejected
at deploy time.
The reflector (github.com/alecthomas/jsonschema) represents the
`minimum` keyword as an int and parses the tag value with strconv.Atoi,
discarding the error:
type Type struct {
Minimum int `json:"minimum,omitempty"`
}
KPAScaleOptions.Target declares jsonschema_extras:"minimum=0.01", so
"0.01" fails to parse and silently degrades to zero.
Re-apply that one keyword on the already-reflected KPAScaleOptions.target
property, reading the value back from the same struct tag so the
constraint stays declared once and cannot drift from the runtime check
it documents. Nothing else about the generated schema changes.
knative#4063 declared exclusiveMinimum=true on this field as a workaround for
exactly this truncation, so that the schema at least rejected the
concrete invalid value 0. Now that the fractional minimum survives, that
workaround is removed: under the draft-04 this document declares, a
boolean exclusiveMinimum would require target > 0.01 and so contradict
ValidateScale, which accepts exactly 0.01.
71bbb54 to
e0a4557
Compare
|
@lkingland Rebased and revised for the top-level scale changes. Re-verified against the latest main and ready for another look. |
Changes
0.01minimum forscale.kpa.targetin the generated func.yaml schema instead of emitting0.exclusiveMinimum=trueworkaround that Add top-levelscalefield to func.yaml #4063 added to that same field while the fractional minimum was still being truncated./kind bug
Fixes #4066
Problem
KPAScaleOptions.Targetdeclares:but the pinned
github.com/alecthomas/jsonschemaimplementation representsminimumas anintand parses its tag value withstrconv.Atoi, discarding the error:"0.01"fails to parse, silently degrades to zero, and the generated schema publishes"minimum": 0where runtime validation requirestarget >= 0.01. Afunc.yamlwithscale.kpa.target: 0.001therefore validated against the published schema and was rejected at deploy time. The schema was looser than the validation it documents.Fix
After the normal reflection pass, restore the fractional minimum on the already-reflected
KPAScaleOptions.targetproperty before the schema is marshalled. The value is read back from the samejsonschema_extrastag rather than duplicated in the generator, so the constraint stays declared once and cannot drift from the runtime check it documents.Removing the
exclusiveMinimum=trueworkaround#4063 declared
exclusiveMinimum=trueon this field as a stopgap for exactly this truncation, so the schema at least excluded the concrete invalid value0. That stopgap must not survive this fix.This document declares draft-04, where a boolean
exclusiveMinimummakesminimumexclusive. The two changes together would have produced:which means
target > 0.01, whilevalidateKPAScalerejects only values< 0.01:so it accepts exactly
0.01. Keeping both would have inverted the original bug: the schema would have become stricter than the runtime check, rejecting a validtarget: 0.01that deploys fine. Removing the workaround now that the real minimum is preserved correctly gets both totarget >= 0.01.Tests
TestTargetMinimumIsPreservedverifies the whole neighbourhood, not just the corrected value:KPAScaleOptions.target.minimumis emitted as exactly0.01KPAScaleOptions.target.exclusiveMinimumis absent, so the bound stays inclusiveutilization.minimum/utilization.maximumare still1and100Test_ValidateScalecovers the runtime boundary on both sides of the same value:targetValidateScale0.01math.Nextafter(0.01, 0)(largest float64 below0.01)0.02together pinning the contract at
target >= 0.01on both the schema and the validation side.You can also confirm the diff by inspection — regenerating changes exactly one line of
schema/func_yaml-schema.json:"target": { - "exclusiveMinimum": true, "type": "number", - "minimum": 0 + "minimum": 0.01 },Validated locally with:
Release Note