Skip to content

Remove _is_ground wrapper; guard metering lifespan with config.is_cloud() - #7

Merged
tescalada merged 1 commit into
mainfrom
drop-sparkmeter-mode
Jul 20, 2026
Merged

tescalada merged 1 commit into
mainfrom
drop-sparkmeter-mode

Conversation

@tescalada

Copy link
Copy Markdown
Contributor

Summary

Remove the _is_ground() helper in sparkmeter/metering/lifespan.py and guard the metering lifespan's cloud no-op directly with config.is_cloud().

Details

_is_ground() wrapped config.is_ground() in a try/except whose fallback read os.environ.get("SPARKMETER_MODE", "ground"). SPARKMETER_MODE is not set by any deployment, compose file, Dockerfile, or run script, so that fallback was dead code that always resolved to "ground", while shadowing the real ground/cloud switch.

Ground vs cloud is already determined by config (the HEROKU key, populated from SM_HEROKU). Because local_system is binary, is_cloud() and is_ground() are strict complements, so metering_lifespan now guards its no-op with config.is_cloud() — matching the function's "no-op on cloud" docstring — and _is_ground() is deleted.

Behavior is unchanged: the primary path was already config.is_ground(), and the only removed branch (the SPARKMETER_MODE fallback) was never reachable in practice. config.is_cloud() is safe here — it's a plain dict lookup on the config, loaded during app bootstrap before the lifespan runs.

Test

Adds test_metering_lifespan_is_noop_on_cloud: with config.is_cloud() true, metering_lifespan sets app.state.metering = None and starts no metering runtime.

…ud()

_is_ground() wrapped config.is_ground() in a try/except whose fallback read
SPARKMETER_MODE, an env var that no deployment sets. The config already
determines ground vs cloud (via the HEROKU key), so metering_lifespan now
guards its cloud no-op directly with config.is_cloud(), and _is_ground is
deleted.
@github-actions

Copy link
Copy Markdown

Coverage

Coverage report
FileStmtsMissCoverMissing
sparkmeter
   __version__.py16288%32, 38
   _wsgi_mount_smoketest.py97970%19–152
   app.py3151197%19–20, 111, 368–375, 552–554, 675, 682–683
   asgi.py74740%19–166
   cli.py42686%59–70
   cli_app.py880%4–20
   cli_prompts.py151220%8–12, 17–21, 26–28
   conftest.py181995%51–52, 85–86, 108–120, 209
   controller.py2444283%183, 207–208, 531, 585–642
   debug_memory.py32320%6–63
   periodic.py563145%60–66, 71–75, 80–84, 93–98, 103–111, 124–128
   sentry_proxy.py342235%38, 44–47, 56–65, 73–82
   servercommand.py1127236%47, 56–60, 64–69, 73–78, 82–85, 89–90, 101–103, 112–181
sparkmeter/alembic/versions
   0.32_merge_sms_tables.py46393%61–67
   0.77_snapshot_support.py128298%340, 401
sparkmeter/api
   customerviews0.py283199%301
   historyviews0.py1149219%49–55, 69–72, 81–131, 144–175, 185–216, 230–257
sparkmeter/config
   configparameter.py57296%80, 111
sparkmeter/database
   alchemy.py54493%61–63, 74
   database.py232399%497, 579–580
   ormobject.py55198%65
   session.py21210%12–62
   types.py54394%91–92, 125
sparkmeter/ground
   groundcommand.py201050%20–35
sparkmeter/history
   historyview.py351654%30–31, 41–54, 65–72
sparkmeter/meter
   meterdomain.py7722797%892, 1805–1806, 1817–1868, 1911
sparkmeter/metering
   api.py27967%66–76
   cli.py2275874%158, 174–175, 184, 193, 198–201, 203, 234, 238–244, 281–297, 301–335, 456–458
   dispatch.py741678%78–80, 85–97, 185
   events.py1053468%56, 75–77, 109–112, 118–193, 240
   lifespan.py695225%37–98, 109–125
   reconcile.py1134362%84–107, 119–120, 129, 135–138, 140–143, 169, 259–262, 266–269, 273–276, 287
sparkmeter/metering/tools
   cli_client.py825829%46–52, 56–61, 65–70, 83–107, 115–148, 153–166
sparkmeter/misc
   datetimeutils.py65395%115–117
sparkmeter/system
   systemcommand.py67593%35, 130–132, 134–135
sparkmeter/tariff
   tariffcommand.py821582%27–44
sparkmeter/transaction
   transactionview.py167199%71
sparkmeter/user
   userdomain.py1871294%416–434
sparkmeter/web
   unittestutils.py1741194%30–38, 269, 278, 344, 346
   views.py72199%71
TOTAL1264792193% 

Tests Skipped Failures Errors Time
1267 0 💤 0 ❌ 0 🔥 4m 51s ⏱️

@github-actions

Copy link
Copy Markdown

Diff Coverage

Diff: origin/main...HEAD, staged and unstaged changes

  • sparkmeter/metering/lifespan.py (100%)

Summary

  • Total: 2 lines
  • Missing: 0 lines
  • Coverage: 100%

@tescalada
tescalada merged commit 68afad5 into main Jul 20, 2026
5 checks passed
@tescalada
tescalada deleted the drop-sparkmeter-mode branch September 25, 2026 17:37
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.

1 participant