fix: keep Activity panel rows within their width budget (#282)
## Summary - Follow-up hardening for merged [PR #279](https://github.com/lablup/all-smi/pull/279) and [PR #281](https://github.com/lablup/all-smi/pull/281). - Preserve PR #279's btop-style height gradient while closing the width-budget gaps left in PR #281's CPU Activity panel regression coverage. - Guarantee that Activity panel titles, individual core rows, grouped core rows, and narrow gauges remain inside their allocated columns from the minimum supported terminal width upward. ## Target PRs and issues reviewed - [PR #279](https://github.com/lablup/all-smi/pull/279) / [issue #278](https://github.com/lablup/all-smi/issues/278): the per-row palette mapping, CPU/GPU shared path, annotation isolation, and single-row behavior match the intended implementation. No correctness, security, or performance defect was found; only a stale doc reference to the later-removed left margin needed correction. - [PR #281](https://github.com/lablup/all-smi/pull/281) / [issue #280](https://github.com/lablup/all-smi/issues/280): the margin removal itself is correct, but the regression fixture explicitly avoided three width paths that still violated the issue's every-line width criterion. ## Review findings - Trailing partial individual-core rows accounted for a separator after every possible slot instead of the separators actually emitted, making the final line two columns too wide. - `calculate_cores_per_line` could allocate 15-column gauges even though `draw_bar`'s full representation requires 17 columns, so packing transitions could overflow several times on one row. - Long socket-group titles were never truncated and escaped the top-border budget at widths near the 81-column minimum. - PE-cluster and socket-group per-core block sections were unbounded; high-core-count machines could shrink the requested gauge below its real minimum and push the right border far into the neighboring panel. ## Correctness fixes - Export the full gauge minimum and make `draw_bar` honor smaller requested widths with an exact-width compact fallback. - Pack individual gauges only when their 17-column representation plus inter-gauge spacing fits, and compute partial-row padding from emitted columns. - Truncate oversized panel titles with an ellipsis inside the border budget. - Bound grouped utilization blocks after reserving the full gauge and stop block emission before the panel edge. - Expand the regression sweep across terminal widths 81 through 200, short and tall graph modes, every collapse strategy, trailing partial rows, and 1 to 128 cores; every row must start at column zero, equal the panel width, and match the reserved panel height. ## Security review - No authentication, authorization, secret handling, external input execution, filesystem, or network surface is changed. - Width- and core-count-driven rendering is now bounded by the panel budget, preventing attacker-influenced or malformed high-cardinality telemetry from causing unbounded per-row terminal output. ## Performance and reliability review - Grouped block rendering now stops when the available columns are exhausted instead of iterating and emitting every reported core on an already-overflowing line. - The exhaustive width regression completes in the focused test suite without measurable rendering slowdown, and no per-frame heap growth beyond the existing formatting paths was introduced. ## Validation - [x] `cargo fmt --check` - [x] `cargo check --lib --tests` - [x] `cargo clippy --fix --allow-dirty --lib --tests -- -D warnings` - [x] `cargo clippy --lib --tests -- -D warnings` - [x] `cargo test --lib ui::activity_panel` (33 passed) - [x] `cargo test --lib ui::widgets` (15 passed) - [x] `cargo test` (all unit, integration, and doc-test suites passed) Refs #278 Refs #280 Refs #279 Refs #281
J
Jeongkyu Shin committed
a6857794c267fb3867e96beb8206ce11c758fb0b
Parent: be01be5
Committed by GitHub <noreply@github.com>
on 7/20/2026, 4:42:16 AM