Treat a NotFound resource as observed absence, not an unobserved check - #74
Treat a NotFound resource as observed absence, not an unobserved check#74jessie1111101 wants to merge 2 commits into
Conversation
resource_property already fails closed when a query matches nothing: "no <kind> matched" is a fail, distinct from a check that could not run. But absence only reaches that branch when the query used a selector, which returns an empty item list and exits zero. Naming a resource instead makes kubectl exit non-zero with NotFound, which hit the blanket except and returned "error". That matters because rollup drops an errored entry from both the numerator and the denominator. The most common way an agent fails an objective is by never creating the resource, and scoring that as unobserved inflates correctness rather than lowering it: eleven passes plus one never-created resource reads as 11/11 rather than 11/12. Seen live on deploy-hello-app, where namespace-pss-enforced errored with NotFound after the agent never created the namespace. Detection lives in k8s beside get_resource, since recognising kubectl's output is a kubectl concern, while the fail-versus-error policy stays in the verifiers. It matches the apiserver's "(NotFound)" reason code in full, so a message that merely contains the words "not found" (a missing binary) still errors. scaling_complete had the same hole for its named deployment and is fixed with it; pod_healthy queries by selector and was never affected. Signed-off-by: Jessie Liu <jssl@google.com>
Signed-off-by: Jessie Liu <jssl@google.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: jessie1111101 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 @jessie1111101. Thanks for your PR. I'm waiting for a kubernetes-sigs 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. |
📝 WalkthroughWalkthroughThe change adds exact kubectl ChangesKubernetes NotFound handling
Estimated code review effort: 2 (Simple) | ~15 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Found running
deploy-hello-append to end. The agent never created the namespace, and the objective checking it recordederror, notfail:Why this is a scoring bug
rollup.py:102drops an errored entry from both the numerator and the denominator — correctly, sinceerroris defined inbase.py:94as the absence of an observation.But
NotFoundis an observation, and an unambiguous one. Scoring it as unobserved means the most common way an agent fails an objective — never creating the resource — quietly shrinks the denominator instead of counting against it. Eleven passes plus one never-created resource reads as 11/11 = 1.0 rather than 11/12. It fails silently, and in the direction nobody audits.Why it only happens sometimes
resource_propertyalready fails closed on an empty match:That is the intended behaviour. The problem is that absence only reaches that branch one of the two ways it can arrive:
get ns -l app=x{"items": []}get namespace hello-appNotFoundexcept→error❌So the same condition scores differently depending on how the objective was written.
The change
is_not_found()lives ink8s/next toget_resource— recognising kubectl's output is a kubectl concern, while the fail-versus-error policy stays in the verifiers. It matches the apiserver's(NotFound)reason code in full, parentheses included, sobash: kubectl: command not foundstill errors rather than scoring as an observed absence.In
resource_propertythe handler substitutes an empty payload and falls through, which reuses the existing semantics rather than duplicating them — soabsentstill passes when the resource is gone, and every other operator fails.scaling_completehad the identical hole for its named deployment and is fixed alongside.pod_healthyqueries by selector and was never affected.Tests
Four new cases, verified to actually catch the regression — reverting the fix fails exactly 3 and passes the rest:
fail(waserror)absentoperator with the resource gone →passerrorcommand not found→ stillerror(guards the strict marker)Note the pre-existing
test_subprocess_error_is_reported_in_reasonusesstderr="not found"and still expectserror— it passes unchanged, which is a live check that the strict matching does not over-trigger.1186 tests pass; ruff and boilerplate clean.
Summary by CodeRabbit
Bug Fixes
Tests