Skip to content

test(metax): add GPU scoring and QoS quota validation edge case unit tests (#2496) - #2517

Closed
Haseebx162006 wants to merge 3 commits into
Project-HAMi:masterfrom
Haseebx162006:fix/metax-gpu-scoring-qos-tests-2496
Closed

test(metax): add GPU scoring and QoS quota validation edge case unit tests (#2496) #2517
Haseebx162006 wants to merge 3 commits into
Project-HAMi:masterfrom
Haseebx162006:fix/metax-gpu-scoring-qos-tests-2496

Conversation

@Haseebx162006

@Haseebx162006 Haseebx162006 commented Aug 9, 2026

Copy link
Copy Markdown

/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

  1. Defensive Zero & Bound Guards:

    • pkg/device/metax/device.go: Added nil guards for node and node.Annotations in ScoreNode.
    • pkg/device/metax/sdevice.go: Added nil checks for podinfo, pod.Annotations, and CustomInfo maps; implemented resolveMemReq for safe memory bound calculations in Fit (request.Memreq and request.MemPercentagereq) avoiding int32 overflow when Totalmem = math.MaxInt32; updated AddResourceUsage to return an explicit error on nil parameters.
  2. 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. Applied tt.policy to node.Devices.Policy.
      • Test_MetaX_QoS_Quota_Validation: Expanded table-driven test covering matching fixed-share, best-effort, and burst-share QoS 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: nil nodes, empty device slices, topology-aware spread policy.
      • TestMetaxSDevices_Fit_ZeroAndExceedMemory: Captured allocation results verifying Usedmem == math.MaxInt32 on Totalmem = math.MaxInt32 with 100% request (overflow prevention), invalid percentage 102, sentinel percentage 101, and valid percentages 50%/100%.
      • TestMetaxSDevices_AddResourceUsage_NilGuard: Verified error returning on nil inputs.

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?:

NONE

Copilot AI lite review requested due to automatic review settings August 9, 2026 16:09
@hami-robot
hami-robot Bot requested review from ouyangluwei163 and wawa0210 August 9, 2026 16:09
@hami-robot

hami-robot Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Haseebx162006
Once this PR has been reviewed and has the lgtm label, please assign wawa0210 for approval. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@hami-robot

hami-robot Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Welcome @Haseebx162006! It looks like this is your first PR to Project-HAMi/HAMi 🎉

@hami-robot hami-robot Bot added the size/XL label Aug 9, 2026
@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

MetaX 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.

Changes

MetaX hardening

Layer / File(s) Summary
Resource fitting and QoS validation
pkg/device/metax/sdevice.go, pkg/device/metax/sdevice_test.go, pkg/scheduler/score_test.go
Resource accounting and fitting now validate nil inputs, resolve memory requests centrally, and use safe annotation and QoS handling. Tests cover memory boundaries, zero-capacity devices, and QoS cases.
Workload filtering and node scoring
pkg/device/metax/device.go, pkg/device/metax/sdevice.go, pkg/device/metax/sdevice_test.go
Node scoring, app-class checks, online-device prioritization, and online scoring now skip nil entries and safely access annotations. Tests cover nil nodes, empty device history, online app-class scoring, and topology-aware spread scoring.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested labels: enhancement

Suggested reviewers: archlitchi

Poem

I guard each nil path with care,
And test memory limits there.
QoS and scores now safely flow,
While empty devices cause no woe.
Hop, hop—MetaX checks now glow! 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes add the required zero-memory, capacity-bound, and QoS validation tests and harden the related MetaX paths [#2496].
Out of Scope Changes check ✅ Passed The production guards and expanded tests directly support the linked issue by preventing MetaX scoring and quota evaluation failures.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main changes: MetaX GPU scoring and QoS quota validation edge-case tests.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
pkg/device/metax/sdevice_test.go (1)

2907-2986: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Test the changed MetaxDevices.ScoreNode method.

This test invokes MetaxSDevices.ScoreNode. The nil-node guard is in MetaxDevices.ScoreNode at pkg/device/metax/device.go Line 186. Add a direct MetaxDevices.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 win

Exercise the exclusive QoS bypass.

This case sets devUsed to zero. checkDeviceQos returns for an unused device before it checks Coresreq == 100. Add a direct checkDeviceQos test with a used device, mismatched QoS, and Coresreq: 100. Do not use Fit, 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

📥 Commits

Reviewing files that changed from the base of the PR and between 3616313 and 4ad927f.

📒 Files selected for processing (4)
  • pkg/device/metax/device.go
  • pkg/device/metax/sdevice.go
  • pkg/device/metax/sdevice_test.go
  • pkg/scheduler/score_test.go

Comment thread pkg/device/metax/sdevice.go Outdated
…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>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 ScoreNode and Fit edge cases in pkg/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.

Comment thread pkg/device/metax/sdevice.go Outdated
Comment thread pkg/device/metax/sdevice.go Outdated
Comment thread pkg/device/metax/sdevice.go
Comment thread pkg/scheduler/score_test.go
Comment thread pkg/scheduler/score_test.go Outdated
@Haseebx162006
Haseebx162006 force-pushed the fix/metax-gpu-scoring-qos-tests-2496 branch from 4ad927f to 62c53b9 Compare August 9, 2026 16:16
…nd AddResourceUsage nil handling

Signed-off-by: Haseebx162006 <haseebahmad0160@gmail.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 win

Keep exclusive-device prioritization for non-Online app classes.

If MetaxSGPUAppClass exists but is not Online, the condition at Line 449 succeeds and the else if for Coresreq == 100 cannot run. Offline pods that request an exclusive device then skip prioritizeExclusiveDevices.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4ad927f and 3e11f12.

📒 Files selected for processing (3)
  • pkg/device/metax/sdevice.go
  • pkg/device/metax/sdevice_test.go
  • pkg/scheduler/score_test.go

Comment thread pkg/device/metax/sdevice_test.go
Comment thread pkg/scheduler/score_test.go
Signed-off-by: Haseebx162006 <haseebahmad0160@gmail.com>
@Haseebx162006 Haseebx162006 changed the title test(metax): add GPU scoring and QoS quota validation edge case unit tests (#2496) test(metax): add GPU scoring and QoS quota validation edge case unit tests (#2496) /kind testing /kind bug Aug 9, 2026
@Haseebx162006 Haseebx162006 changed the title test(metax): add GPU scoring and QoS quota validation edge case unit tests (#2496) /kind testing /kind bug test(metax): add GPU scoring and QoS quota validation edge case unit tests (#2496) Aug 9, 2026
@Haseebx162006

Copy link
Copy Markdown
Author

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!

@FouoF

FouoF commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

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 FouoF closed this Aug 10, 2026
@Haseebx162006

Copy link
Copy Markdown
Author

@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

@Haseebx162006

Copy link
Copy Markdown
Author

@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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MetaX GPU Scoring & QoS Quota Validation Test

3 participants