Skip to content

fix: reject powermetrics on non-Apple-Silicon Macs - #1333

Closed
davidberenstein1957 wants to merge 1 commit into
masterfrom
fix/powermetrics-setup-cli
Closed

fix: reject powermetrics on non-Apple-Silicon Macs#1333
davidberenstein1957 wants to merge 1 commit into
masterfrom
fix/powermetrics-setup-cli

Conversation

@davidberenstein1957

Copy link
Copy Markdown
Collaborator

What changed

ApplePowermetrics._setup_cli() now raises instead of falling through:

  • a Mac whose CPU is not Apple Silicon raises SystemError (previously the method returned without assigning self._cli and without raising, so ApplePowermetrics() succeeded on Intel Macs);
  • detect_cpu_model() returning None raises the same SystemError rather than an unexpected AttributeError;
  • self._cli is assigned on the one path that validated the executable.

_log_values() now uses self._cli instead of a hardcoded "powermetrics", so the validated path is the one actually executed. Two smaller defects in the same argv are fixed alongside it: a stray "" positional argument passed verbatim to powermetrics, and the missing timeout on subprocess.call, which let a hung powermetrics block the measurement thread indefinitely.

Why

Because _setup_cli() never raised on Intel Macs, is_powermetrics_available() returned True whenever a permissive sudo rule existed, and _try_platform_cpu_backend (codecarbon/core/resource_tracker.py:225) routed those machines into _setup_powermetrics, registering an AppleSiliconChip on hardware that has none. With detect_cpu_model() returning None, the resulting AttributeError was swallowed by the broad except Exception in is_powermetrics_available() and reported as powermetrics simply being unavailable, hiding genuine cpuinfo failures.

Note for the changelog: machines that were accidentally using powermetrics on Intel Macs now fall through to Intel Power Gadget or the CPU-load fallback, which is the intended routing but does change their tracking method.

How it was verified

Four new tests in tests/test_powermetrics.py cover the Intel Mac rejection, the None CPU model, the clean argv with a timeout, and the timeout warning path. All four fail on master and pass with this change; the full tests/test_powermetrics.py and tests/test_resource_tracker.py suites pass (51 tests). ruff format --check is clean on both touched files.

Closes#1313

🤖 Generated with Claude Code

@codecov

codecovBot commented Aug 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.45%. Comparing base (eb2cfef) to head (132f230).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@ Coverage Diff @@## master #1333 +/- ##
==========================================
+ Coverage 91.43% 91.45% +0.02% 
==========================================
Files 49 49 Lines 5057 5058 +1 ==========================================
+ Hits 4624 4626 +2 + Misses 433 432 -1 

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@davidberenstein1957
davidberenstein1957 marked this pull request as ready for review August 12, 2026 17:36
@davidberenstein1957
davidberenstein1957 requested a review from a team as a code ownerAugust 12, 2026 17:36
_setup_cli returned without setting _cli and without raising on an Intel
Mac, so ApplePowermetrics() succeeded there and ResourceTracker could
register an AppleSiliconChip on hardware that has none. It also crashed
with AttributeError when detect_cpu_model() returned None.
Raise SystemError on both paths, use the validated self._cli in the
argv, drop a stray empty argument, and give subprocess.call a timeout so
a hung powermetrics cannot block the measurement thread.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@davidberenstein1957

Copy link
Copy Markdown
CollaboratorAuthor

Closing as folded into #1345. Both are about ApplePowermetrics being dishonest in two ways: it constructs successfully on hardware it cannot measure, and it returns NaN when it measures nothing. Same file, same class, adjacent methods, and they collided textually while both extending tests/test_powermetrics.py, so they are now one 'harden powermetrics' review. The subprocess timeout that was bundled in here has been split out separately as #1397, since it is an unrelated change with its own failure mode.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ApplePowermetrics._setup_cli silently succeeds on Intel Macs

1 participant

@davidberenstein1957