Skip to content

test(health): own sensor metric projection#4086

Open
chet wants to merge 1 commit into
NVIDIA:mainfrom
chet:gh-issue-4081
Open

test(health): own sensor metric projection#4086
chet wants to merge 1 commit into
NVIDIA:mainfrom
chet:gh-issue-4081

Conversation

@chet

@chet chet commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

The sensor collector had two direct tests that checked only range suffix and
label strings. Redfish-to-metric projection, unit normalization, sweep
planning, and the collector boundary still had little or no owner coverage.

This extracts private projection and sweep-plan helpers, then replaces the
narrow checks with six table-driven entries and 37 rows:

  • eight incomplete samples;
  • five accepted projections;
  • thirteen unit aliases;
  • three sweep plans;
  • six collection and lifecycle cases;
  • two concurrency-normalization cases.

The collection table exercises representative fetch, failure, derived-metric,
and stop paths. Drive and power-supply mapping stays with the entity projection
tests instead of being repeated here. The health suite moves from 405 Original
entries to 404 Converted entries and 409 Expanded entries.

Selected production coverage for sensors.rs plus sanitize_unit, excluding
test-module bodies:

  • Original: 4/30 functions, 28/324 LLVM line-instances, 24/413 regions
  • Converted: 4/33 functions, 28/344 LLVM line-instances, 24/439 regions
  • Expanded: 33/43 functions, 319/470 LLVM line-instances, 409/611 regions
  • Converted to Expanded: +29 covered functions, +291 covered line-instances, +385 covered regions

Expanded adds ten TestBmc monomorphs when the collector table instantiates
its generic production methods. Those records add ten functions, 126
line-instances, and 172 regions to the denominator; all 33 common production
records retain identical non-count layouts, and test-body records are excluded.

Related issues

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 — 409 passed

  • cargo make format-nightly

  • cargo make clippy

  • cargo make carbide-lints

  • Local CodeRabbit review — no findings

  • Local Claude review — no correctness findings

Additional Notes

The collector keeps its existing event placement, failure accounting, and
unordered sensor fetch scheduling.

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

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The sensor collector now derives sweep behavior from SensorSweepPlan, projects readings through project_sensor, emits optional range metrics separately, and handles incomplete readings explicitly. Tests expand coverage for sweep modes, projection results, collector behavior, concurrency, and unit sanitization.

Changes

Sensor collection

Layer / File(s) Summary
Sweep planning and fetch control
crates/health/src/collectors/sensors.rs
CollectorSweep maps to explicit skip or collect plans that control derived metrics and sensor fetch limits.
Sensor projection and metric emission
crates/health/src/collectors/sensors.rs
Sensor parsing produces primary and optional range metrics, while missing health and incomplete readings return explicit projection errors and skip emission.
Projection and normalization coverage
crates/health/src/collectors/sensors.rs, crates/health/src/metrics.rs
Tests cover sweep mapping, projection outputs, collection sequencing, concurrency normalization, and sanitized unit aliases.

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

Sequence Diagram(s)

sequenceDiagram
  participant CollectorSweep
  participant SensorSweepPlan
  participant SensorCollector
  participant project_sensor
  participant MetricSink
  CollectorSweep->>SensorSweepPlan: map sweep mode
  SensorSweepPlan->>SensorCollector: provide fetch limit and metric flags
  SensorCollector->>SensorCollector: fetch sensors within limit
  SensorCollector->>project_sensor: validate and project sensor reading
  project_sensor-->>SensorCollector: return primary and optional range metrics
  SensorCollector->>MetricSink: emit projected metrics
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes align with #4081 by adding projection, sweep-plan, lifecycle, concurrency, and sanitize_unit coverage without altering the specified behaviors.
Out of Scope Changes check ✅ Passed No obvious out-of-scope code changes are described; the metrics.rs addition is explicitly within the issue scope for sanitize_unit.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title clearly matches the main change: adding ownership-focused tests for sensor metric projection and related health collector behavior.
Description check ✅ Passed The description directly describes the sensor collector test coverage and refactoring work in the PR.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

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.

🐇🔍

✅ 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/sensors.rs (1)

323-340: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Clarify the option-flattening idiom and the misleading reading binding.

Two readability refinements in this extraction chain:

  • s.health.and_then(std::convert::identity) is simply Option::flatten; the explicit form obscures intent.
  • The .filter(|(_, reading)| ...) closure binds the unit string as reading. It is correct today (only a String exposes is_empty()), but the inverted name is a latent trap for future edits.

As per coding guidelines: "Prefer simple, explicit, readable Rust over clever or unnecessarily abstract code."

♻️ Proposed clarity fix
     let Some(bmc_health) = sensor
         .status
         .as_ref()
-        .and_then(|s| s.health.and_then(std::convert::identity))
+        .and_then(|s| s.health.flatten())
     else {
         return Err(SensorProjectionError::NoHealth);
     };

     let Some((reading, reading_type, unit)) = sensor
         .reading
         .flatten()
         .zip(sensor.reading_type.flatten())
         .zip(sensor.reading_units.clone().flatten())
-        .filter(|(_, reading)| !reading.is_empty())
+        .filter(|(_, unit)| !unit.is_empty())
         .map(|((r, rt), u)| (r, rt, u))
     else {
         return Err(SensorProjectionError::IncompleteReading);
     };
🤖 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/sensors.rs` around lines 323 - 340, In the
health extraction, replace the explicit identity-based flattening of s.health
with Option::flatten. In the reading extraction chain, rename the filter
closure’s second binding to reflect that it is the unit value, while preserving
the existing non-empty check and tuple behavior.

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/sensors.rs`:
- Around line 323-340: In the health extraction, replace the explicit
identity-based flattening of s.health with Option::flatten. In the reading
extraction chain, rename the filter closure’s second binding to reflect that it
is the unit value, while preserving the existing non-empty check and tuple
behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: f2dae110-ae31-400e-a36d-d0a2f07ea959

📥 Commits

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

📒 Files selected for processing (2)
  • crates/health/src/collectors/sensors.rs
  • crates/health/src/metrics.rs

@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/sensors.rs (1)

331-340: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider renaming the filter binding to reflect the value it inspects.

After the two zips the tuple is ((reading, reading_type), units), so the closure binding named reading is in fact the units string. The behaviour is correct — empty units are rejected as IncompleteReading — but the misleading name is a latent trap for anyone later tightening this completeness check.

♻️ Proposed rename for clarity
         .zip(sensor.reading_units.clone().flatten())
-        .filter(|(_, reading)| !reading.is_empty())
+        .filter(|(_, units)| !units.is_empty())
🤖 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/sensors.rs` around lines 331 - 340, Rename the
filter closure’s second tuple binding in the sensor projection flow to indicate
it represents units, not the reading value; preserve the existing empty-units
check and all surrounding tuple mapping behavior.
🤖 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/sensors.rs`:
- Around line 331-340: Rename the filter closure’s second tuple binding in the
sensor projection flow to indicate it represents units, not the reading value;
preserve the existing empty-units check and all surrounding tuple mapping
behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 62ff68db-f7e9-4f29-b1a8-a1a1d2a101fa

📥 Commits

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

📒 Files selected for processing (2)
  • crates/health/src/collectors/sensors.rs
  • crates/health/src/metrics.rs

Replace the two range-only checks with table-driven cases for Redfish projection, unit normalization, sweep planning, collection failures, lifecycle events, and concurrency.

Exercise the real collector path without repeating the drive and power-supply mapping covered by the entity projection tests.

NVIDIA#4081
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 the PR.

🐇🔍

✅ Action performed

Full review finished.

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.

test(health): own sensor metric projection

1 participant