Skip to content

test: pin the device ceiling's refusal, and stop asserting on source text - #282

Merged
GeiserX merged 1 commit into
mainfrom
test/device-ceiling-tripwire
Aug 6, 2026
Merged

test: pin the device ceiling's refusal, and stop asserting on source text#282
GeiserX merged 1 commit into
mainfrom
test/device-ceiling-tripwire

Conversation

@GeiserX

@GeiserX GeiserX commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Two halves of CashPilot-6zp, neither of which widens the ceiling — the bead is explicit that must not happen pre-emptively, and I verified the premise still holds: all six compute services ship an empty docker.image, so none can request anything.

1. The missing tripwire

The existing test catches a compute service becoming deployable without declaring a device. Nothing caught the other order: it declares one, and the ceiling refuses it anyway.

A future GPU service will hit exactly that. The refusal is correct but unexpected, so the new test pins the 403 and its failure message says what to do — including that NVIDIA is not a device at all: it needs gpus: all or a deploy.resources reservation, and the worker spec has no field for either. That is a much bigger change than adding a string to a frozenset.

Plus a control that a device inside the ceiling is allowed (or the refusal test would pass on validation that refuses everything), and a canary on the ceiling's size.

2. A source-text assertion, removed

test_the_deploy_path_actually_forwards_it read app/main.py as text and checked it contained the literal line that forwards devices.

That passes against a build where the line exists but never runs — and its own docstring said "declared-but-ignored would make the corrected CLAUDE.md wrong too", which is precisely the case it could not detect.

It now deploys Mysterium for real, intercepts _proxy_worker_deploy, and asserts the spec handed to the worker carries the device. A control deploys a service that declares none, so the assertion cannot pass on a spec that always sends /dev/net/tun.

Mutation-tested — and mutation 1 is the whole point

Mutation Result
keep the line, drop the value ("devices": None) the new test fails; the old string assertion would have passed
widen the ceiling to admit /dev/dri 3 tests fail, including the existing doc-sync one

Filed separately

CashPilot-jtg4 — the source-text assertion as a class. This was the one I happened to read; a sweep for read_text() in tests/ followed by a substring check would find any others. That is a different job from 6zp, so I did not bundle it.

4351 passed, coverage 95.57%, ruff clean. Verified locally — Actions is still in a major outage.

Summary by CodeRabbit

  • Bug Fixes
    • Deployment handling now correctly passes the required network device to Mysterium.
    • Services without declared devices no longer receive a device list.
    • Undeclared devices are rejected, while approved devices continue to work as expected.

…text

Two halves of CashPilot-6zp, neither of which widens the ceiling -- the bead is
explicit that must not happen pre-emptively, and the premise still holds: all
six compute services ship an empty docker.image, so none can request anything.

1. THE MISSING TRIPWIRE. The existing test catches a compute service becoming
   deployable WITHOUT declaring a device. Nothing caught the other order: it
   declares one, and the ceiling refuses it anyway. A future GPU service will
   hit exactly that, and the refusal is correct but unexpected -- so the new
   test pins the 403 and its message says what to do, including that NVIDIA is
   not a device at all (it needs `gpus: all` or a deploy.resources reservation,
   and the worker spec has no field for either).

   Plus a control that a device INSIDE the ceiling is allowed, or the refusal
   test would pass on validation that refuses everything, and a canary on the
   ceiling's size.

2. A SOURCE-TEXT ASSERTION, REMOVED. test_the_deploy_path_actually_forwards_it
   read app/main.py as text and checked it CONTAINED

       '"devices": docker_conf.get("devices") or None'

   which passes against a build where that line exists but never runs -- and
   its own docstring said "declared-but-ignored would make the corrected
   CLAUDE.md wrong too", the very case it could not detect.

   It now deploys Mysterium for real, intercepts _proxy_worker_deploy, and
   asserts the spec handed to the worker carries the device. A control deploys
   a service that declares none, so the assertion cannot pass on a spec that
   always sends /dev/net/tun.

MUTATION-TESTED, and mutation 1 is the point: replacing the value with
'"devices": None,  # line still here' keeps the old string's shape and breaks
the behaviour. The new test fails where the old one would have passed.
Widening the ceiling to admit /dev/dri fails 3 tests, including the existing
doc-sync one.

4351 passed, 95.57%.
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The deployment tests now execute api_deploy, verify device forwarding, validate Honeygain behavior, and check deny-by-default device enforcement. A fake request fixture supports patched ownership checks.

Changes

Deployment device validation

Layer / File(s) Summary
Deployment forwarding tests
tests/test_beads_batch_56.py
The tests execute api_deploy, capture worker deployment specifications, verify Mysterium receives /dev/net/tun, and verify Honeygain sends no devices.
Allowed-device enforcement
tests/test_beads_batch_56.py
The tests verify HTTP 403 responses for undeclared devices, acceptance of /dev/net/tun, and the exact _ALLOWED_DEVICES contents.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

  • GeiserX/CashPilot#249: Both changes update tests/test_beads_batch_56.py to cover /dev/net/tun declarations, enforcement, and deployment forwarding.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes both main changes: testing device-ceiling refusal and replacing source-text assertions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/device-ceiling-tripwire

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@GeiserX
GeiserX merged commit 43a0596 into main Aug 6, 2026
1 of 2 checks passed
@GeiserX
GeiserX deleted the test/device-ceiling-tripwire branch August 6, 2026 20:55

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

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

Inline comments:
In `@tests/test_beads_batch_56.py`:
- Around line 431-434: Replace the hardcoded HONEYGAIN_EMAIL and
HONEYGAIN_PASSWORD values in the DeployRequest setup with test credentials
loaded from environment variables or the project’s documented encrypted storage
mechanism, while preserving the existing worker_id and request structure.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 0dc293f8-4345-4bef-8056-dd0878991cce

📥 Commits

Reviewing files that changed from the base of the PR and between 2c4d9b0 and 9592465.

📒 Files selected for processing (1)
  • tests/test_beads_batch_56.py

Comment on lines +431 to +434
body = main_module.DeployRequest(
env={"HONEYGAIN_EMAIL": "someone@example.invalid", "HONEYGAIN_PASSWORD": "not-a-real-password"},
worker_id=1,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Remove the hardcoded Honeygain credential values.

Line 432 places credential values in source code. Load test-only values from environment variables or the documented encrypted storage mechanism.

As per coding guidelines: “Never hardcode credentials; obtain secrets through environment variables or the documented encrypted storage mechanism.”

Proposed fix
 import asyncio
+import os
 from unittest.mock import AsyncMock, patch

 body = main_module.DeployRequest(
-    env={"HONEYGAIN_EMAIL": "someone@example.invalid", "HONEYGAIN_PASSWORD": "not-a-real-password"},
+    env={
+        "HONEYGAIN_EMAIL": os.environ["TEST_HONEYGAIN_EMAIL"],
+        "HONEYGAIN_PASSWORD": os.environ["TEST_HONEYGAIN_PASSWORD"],
+    },
     worker_id=1,
 )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
body = main_module.DeployRequest(
env={"HONEYGAIN_EMAIL": "someone@example.invalid", "HONEYGAIN_PASSWORD": "not-a-real-password"},
worker_id=1,
)
import asyncio
import os
from unittest.mock import AsyncMock, patch
body = main_module.DeployRequest(
env={
"HONEYGAIN_EMAIL": os.environ["TEST_HONEYGAIN_EMAIL"],
"HONEYGAIN_PASSWORD": os.environ["TEST_HONEYGAIN_PASSWORD"],
},
worker_id=1,
)
🤖 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 `@tests/test_beads_batch_56.py` around lines 431 - 434, Replace the hardcoded
HONEYGAIN_EMAIL and HONEYGAIN_PASSWORD values in the DeployRequest setup with
test credentials loaded from environment variables or the project’s documented
encrypted storage mechanism, while preserving the existing worker_id and request
structure.

Source: Coding guidelines

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