Skip to content

test(health): cover inventory and entity metric projections#4080

Merged
chet merged 1 commit into
NVIDIA:mainfrom
chet:gh-issue-4075
Jul 24, 2026
Merged

test(health): cover inventory and entity metric projections#4080
chet merged 1 commit into
NVIDIA:mainfrom
chet:gh-issue-4075

Conversation

@chet

@chet chet commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Health's inventory projection had no direct coverage, and the child metric tests stopped before MetricsCollector::collect_entity.

So, this replaces five standalone entries with one table and adds owner tables for every DiscoveredEntity variant plus representative collection behavior. A #[cfg(test)] in-process Redfish fixture lets the same rows cover populated, sparse, null, malformed, ignored, and sinkless paths without repeating setup.

Related issues

This supports #4075

Type of Change

  • Add - New feature or capability
  • Change - Changes in existing functionality
  • Fix - Bug fixes
  • Remove - Removed features or deprecated functionality
  • Internal - Internal changes (refactoring, tests, docs, etc.)

Breaking Changes

  • This PR contains breaking changes

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed
  • No testing required (docs, internal refactor, etc.)

cargo test -p carbide-health --lib

cargo make format-nightly

cargo make clippy

cargo make carbide-lints

Additional Notes

Production behavior is unchanged. The selected projection code now measures:

Checkpoint Functions Lines Regions Health test entries
Original 7/30 104/339 129/534 405
Converted 7/30 104/339 129/534 401
Expanded 30/30 335/339 509/534 403

The four uncovered source lines are three repeated generic miss arms for the non-processor entity types and one lazy tracing field. Processor rows already exercise the missing-resource and malformed-fetch behavior. Sensor projection remains separate for the next focused change.

@chet
chet requested a review from a team as a code owner July 24, 2026 06:08
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 11ff7e9b-d7e7-47f1-bbab-47fd10c9bdcf

📥 Commits

Reviewing files that changed from the base of the PR and between 4f36238 and be47e72.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • crates/health/Cargo.toml
  • crates/health/src/collectors/entity_metrics.rs
  • crates/health/src/collectors/inventory.rs
  • crates/health/src/collectors/mod.rs
  • crates/health/src/collectors/projection_test_support.rs

Summary by CodeRabbit

  • Tests
    • Expanded health collector coverage with data-driven projection and inventory scenarios across processors, memory, drives, power supplies, and chassis variants.
    • Added validation for sparse/null omission rules, ISO-8601 duration-to-seconds conversion, memory period prefixing, and excerpt/sensor-backed excerpt behavior.
    • Added end-to-end checks for metric collection outcomes, including malformed payload handling and emitted collector-event verification (including “no sink” behavior).
  • Chores
    • Added a test-only projection harness backed by an in-memory HTTP server, including workspace-managed development dependency support.

Walkthrough

Adds an in-memory Axum Redfish fixture and expands health collector tests for inventory projections, child metrics, event emission, sparse resources, missing links, empty resources, and malformed responses.

Changes

Health projection test coverage

Layer / File(s) Summary
Mock Redfish fixture and test wiring
crates/health/Cargo.toml, crates/health/src/collectors/mod.rs, crates/health/src/collectors/projection_test_support.rs
Adds the Axum dev-dependency, test-only module wiring, mock Redfish resources, typed fixture loading, and entity conversion helpers.
Inventory projection validation
crates/health/src/collectors/inventory.rs
Tests populated and sparse inventory projections for processors, memory, drives, power supplies, and chassis, including derived metrics.
Metric projection and collection validation
crates/health/src/collectors/entity_metrics.rs
Adds projection-driven metric assertions and collection cases covering emitted events, durations, excerpts, missing or empty resources, malformed responses, and sink behavior.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related issues

  • Issue 4075 — Adds the requested health inventory, child-metric projection, and collect_entity boundary test coverage.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% 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
Title check ✅ Passed The title is concise and accurately summarizes the main change: test coverage for health inventory and entity metric projections.
Description check ✅ Passed The description is clearly aligned with the changeset, describing the new test coverage and fixture-based projection validation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@chet

chet commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review, thanks!

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

@chet Understood — I’ll perform a complete review of the PR, including the updated test coverage and maintainability considerations.

🐇✅

✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
crates/health/src/collectors/projection_test_support.rs (1)

201-240: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider an explicit enum for the metrics variant to close a silent-misconfiguration gap.

The attributes builder attaches a Metrics link for any Some(_), yet only the "empty" and "malformed" arms materialize the backing resource. A future typo'd tag would fall through Some(_) => {}, leaving a dangling link that 404s at fetch time and quietly alters the scenario under test. Modeling the finite set as an enum makes the match exhaustive and removes the stringly-typed coupling.

♻️ Sketch: replace the `Option<&str>` tag with an enum
enum SparseMetrics {
    None,
    Empty,
    Malformed,
}

for (id, metrics) in [
    ("CPU-sparse", SparseMetrics::None),
    ("CPU-empty", SparseMetrics::Empty),
    ("CPU-malformed", SparseMetrics::Malformed),
] {
    let path = processor(id);
    let metrics_path = format!("{path}/Metrics");
    let attributes = match metrics {
        SparseMetrics::None => json!({}),
        _ => json!({ "Metrics": reference(&metrics_path) }),
    };
    // ...insert resource...
    match metrics {
        SparseMetrics::Empty => { /* insert empty metrics */ }
        SparseMetrics::Malformed => { resources.insert(metrics_path, MockResponse::Malformed); }
        SparseMetrics::None => {}
    }
}

As per coding guidelines: "Represent finite sets of values with enums or enum-backed structs ... rather than passing stringly typed values."

🤖 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 `@crates/health/src/collectors/projection_test_support.rs` around lines 201 -
240, Replace the Option<&str> metrics tags in the test fixture loop with a local
enum representing None, Empty, and Malformed. Update the attributes construction
and resource-materialization match statements to match exhaustively on that
enum, preserving the existing links and backing-resource behavior without a
wildcard arm.

Source: Coding guidelines

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

Nitpick comments:
In `@crates/health/src/collectors/projection_test_support.rs`:
- Around line 201-240: Replace the Option<&str> metrics tags in the test fixture
loop with a local enum representing None, Empty, and Malformed. Update the
attributes construction and resource-materialization match statements to match
exhaustively on that enum, preserving the existing links and backing-resource
behavior without a wildcard arm.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: c4e8d6d5-2bf8-496a-b3c5-bbab17a460fb

📥 Commits

Reviewing files that changed from the base of the PR and between 4f36238 and 6ee92ac.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • crates/health/Cargo.toml
  • crates/health/src/collectors/entity_metrics.rs
  • crates/health/src/collectors/inventory.rs
  • crates/health/src/collectors/mod.rs
  • crates/health/src/collectors/projection_test_support.rs

@chet
chet enabled auto-merge (squash) July 24, 2026 06:24
@chet

chet commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review, thanks!

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

@chet Understood. I’ll perform a complete review of #4080, with particular attention to test correctness, fixture maintainability, and coverage of failure paths.

🐇🔎

✅ Action performed

Full review finished.

@chet

chet commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review, thanks!

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

@chet Understood. I’ll perform a complete review of #4080, with emphasis on test correctness, fixture maintainability, failure-path coverage, and regression risk.

🐇🔎

✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
crates/health/src/collectors/entity_metrics.rs (1)

570-601: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider preserving multiplicity/order in the projection assertions.

project folds the produced Vec<MetricField> into a BTreeMap keyed solely by metric_type. This silently collapses any duplicate metric_type and discards emission order, so a regression that emitted the same metric twice (or reordered fields) would pass child_metric_projection_cases undetected. Since the production path returns a Vec, a sorted Vec<(String, &'static str, f64)> would retain that fidelity while remaining deterministic.

🤖 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 `@crates/health/src/collectors/entity_metrics.rs` around lines 570 - 601,
Update the test helper project and matching expected helper to return sorted
Vec<(String, &'static str, f64)> values instead of BTreeMap keyed by
metric_type. Preserve every emitted field, including duplicates, while sorting
both actual and expected results deterministically so
child_metric_projection_cases detects multiplicity and ordering regressions.
🤖 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.

Nitpick comments:
In `@crates/health/src/collectors/entity_metrics.rs`:
- Around line 570-601: Update the test helper project and matching expected
helper to return sorted Vec<(String, &'static str, f64)> values instead of
BTreeMap keyed by metric_type. Preserve every emitted field, including
duplicates, while sorting both actual and expected results deterministically so
child_metric_projection_cases detects multiplicity and ordering regressions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 3225d988-6518-4556-ab83-0ec9e95d75c2

📥 Commits

Reviewing files that changed from the base of the PR and between 4f36238 and c756df8.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • crates/health/Cargo.toml
  • crates/health/src/collectors/entity_metrics.rs
  • crates/health/src/collectors/inventory.rs
  • crates/health/src/collectors/mod.rs
  • crates/health/src/collectors/projection_test_support.rs

@chet

chet commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review, thanks!

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

@chet Understood. I’ll perform a complete review of #4080, focusing on test correctness, fixture maintainability, failure-path coverage, and regression risk.

🐇🔎

✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
crates/health/src/collectors/projection_test_support.rs (1)

58-90: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider a combined insert_resource helper to eliminate the duplicated path argument.

Throughout mock_resources, each self-describing resource passes its path twice — once as the map key to insert and once as the @odata.id inside resource. A silent divergence between the two would break link resolution in a way that is tedious to diagnose. Folding both into a single helper makes the key and self-link authoritatively identical.

♻️ Proposed helper to keep key and self-link in lockstep
fn insert_resource(
    resources: &mut HashMap<String, MockResponse>,
    path: &str,
    odata_type: &str,
    id: &str,
    name: &str,
    attributes: Value,
) {
    insert(resources, path, resource(path, odata_type, id, name, attributes));
}

Call sites then collapse from insert(&mut resources, SYSTEM, resource(SYSTEM, ...)) to insert_resource(&mut resources, SYSTEM, ...).

🤖 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 `@crates/health/src/collectors/projection_test_support.rs` around lines 58 -
90, Combine the existing resource construction and insertion flow by adding an
`insert_resource` helper alongside `resource` and `insert`; it should accept the
shared path and resource fields, build the value with `resource(path, ...)`,
then insert it under that same path. Update self-describing resource call sites
in `mock_resources` to use `insert_resource`, while leaving standalone `insert`
and reference handling unchanged.
🤖 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.

Nitpick comments:
In `@crates/health/src/collectors/projection_test_support.rs`:
- Around line 58-90: Combine the existing resource construction and insertion
flow by adding an `insert_resource` helper alongside `resource` and `insert`; it
should accept the shared path and resource fields, build the value with
`resource(path, ...)`, then insert it under that same path. Update
self-describing resource call sites in `mock_resources` to use
`insert_resource`, while leaving standalone `insert` and reference handling
unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 4fc5abb6-71a3-47c4-8d13-fbdf0f560b4d

📥 Commits

Reviewing files that changed from the base of the PR and between 4f36238 and 126ab5a.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • crates/health/Cargo.toml
  • crates/health/src/collectors/entity_metrics.rs
  • crates/health/src/collectors/inventory.rs
  • crates/health/src/collectors/mod.rs
  • crates/health/src/collectors/projection_test_support.rs

Health's inventory projection had no direct coverage, and the child metric tests stopped before `MetricsCollector::collect_entity`.

So, this replaces five standalone entries with one table and adds owner tables for every `DiscoveredEntity` variant plus representative collection behavior. A `#[cfg(test)]` in-process Redfish fixture lets the same rows cover populated, sparse, null, malformed, ignored, and sinkless paths without repeating setup.

Selected production coverage moves from 7/30 to 30/30 functions, 104/339 to 335/339 lines, and 129/534 to 509/534 regions. The health library now has 403 test entries instead of 405, with 32 labeled cases across the three tables.

Tests updated!

This supports NVIDIA#4075

Signed-off-by: Chet Nichols III <chetn@nvidia.com>
@chet

chet commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review, thanks!

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

@chet Understood. I’ll perform a complete review of #4080, with particular attention to test correctness, fixture maintainability, failure-path coverage, and regression risk.

🐇🔎

✅ Action performed

Full review finished.

@chet
chet merged commit 605d812 into NVIDIA:main Jul 24, 2026
109 of 110 checks passed
@chet
chet deleted the gh-issue-4075 branch July 24, 2026 10:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants