Skip to content

Add tests group and pytest configuration - #7

Merged
wlix13 merged 3 commits into
mainfrom
feature/add-tests
Jul 25, 2026
Merged

Add tests group and pytest configuration#7
wlix13 merged 3 commits into
mainfrom
feature/add-tests

Conversation

@wlix13

@wlix13 wlix13 commented Jul 25, 2026

Copy link
Copy Markdown
Owner

Type of change

  • Bug fix (fixes an issue in a rune, mold or deploy behaviour)
  • Feature (adds a new rune, mold or CLI capability)
  • Enhancement (improves existing provisioning logic or output)
  • Refactor (restructures code without changing behaviour)
  • Breaking change (changes existing mold schemas, CLI usage, or deploy behaviour)
  • Security (security-related fix or hardening)

Description

Why is this change needed?

Related Issues

Testing

  • Unit tests added or updated (uv run poe tests)
  • Deployed to a real host
  • No testing required (documentation changes only)

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • Linter and type checker pass (uv run poe check)
  • Documentation updated (if applicable)

Summary by CodeRabbit

  • Tests

    • Expanded automated coverage across CLI completion, Foundry casting, rune activation, DNS, networking, monitoring, templates, installation, system configuration, and validation behavior.
    • Added checks for error handling, caching, secret redaction, platform-specific behavior, and command generation.
    • Improved test isolation with shared fixtures and mocked external operations.
  • Chores

    • Added pytest configuration, coverage settings, test dependencies, and dedicated test task support.
    • Refined linting rules for test files.

@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@wlix13, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 24 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: dc23bfb5-efd0-4ad0-bc96-7277a823f07a

📥 Commits

Reviewing files that changed from the base of the PR and between 68b2350 and ec70c14.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (46)
  • pyproject.toml
  • tests/__init__.py
  • tests/cli/__init__.py
  • tests/cli/components/__init__.py
  • tests/cli/components/completion/__init__.py
  • tests/cli/components/completion/test_controller.py
  • tests/cli/components/completion/test_powershell.py
  • tests/cli/components/foundry/__init__.py
  • tests/cli/components/foundry/test_controller.py
  • tests/cli/conftest.py
  • tests/cli/core/__init__.py
  • tests/cli/core/test_application.py
  • tests/cli/test_types.py
  • tests/conftest.py
  • tests/test_foundry.py
  • tests/test_foundry_cast.py
  • tests/test_foundry_pyinfra.py
  • tests/test_models_dns.py
  • tests/test_molds_dns.py
  • tests/test_molds_monitoring.py
  • tests/test_molds_netsec.py
  • tests/test_molds_telemt.py
  • tests/test_molds_user.py
  • tests/test_molds_utils.py
  • tests/test_runes_dns.py
  • tests/test_runes_meta.py
  • tests/test_runes_misc.py
  • tests/test_runes_netsec.py
  • tests/test_runes_profiles.py
  • tests/test_runes_telemt.py
  • tests/test_runes_users.py
  • tests/test_smithy_arch.py
  • tests/test_smithy_github.py
  • tests/test_smithy_http.py
  • tests/test_smithy_install.py
  • tests/test_smithy_network.py
  • tests/test_smithy_nezha.py
  • tests/test_smithy_nezha_dashboard.py
  • tests/test_smithy_packages.py
  • tests/test_smithy_service.py
  • tests/test_smithy_sni.py
  • tests/test_smithy_swap.py
  • tests/test_smithy_system.py
  • tests/test_smithy_versions.py
  • tests/test_templates.py
  • tests/test_templates_telemt.py
📝 Walkthrough

Walkthrough

This PR configures pytest and adds broad automated coverage for CLI components, Foundry casting, molds, runes, Smithy utilities, installation flows, networking, monitoring, and template rendering.

Changes

Test infrastructure and CLI

Layer / File(s) Summary
Pytest setup and CLI behavior
pyproject.toml, tests/conftest.py, tests/cli/...
Adds pytest tooling, configuration, shared isolation fixtures, and tests for CLI lifecycle, types, completion, PowerShell integration, and installation.

Foundry casting

Layer / File(s) Summary
Foundry casting and pyinfra tests
tests/cli/components/foundry/..., tests/test_foundry*.py
Tests stage resolution, argv construction, casting failures, rune selection, full casts, and pyinfra patching.

Molds and models

Layer / File(s) Summary
Mold and model validation
tests/test_models_dns.py, tests/test_molds_*.py
Covers DNS providers, mold validation and redaction, merge/coercion utilities, and rune activation behavior.

Runes

Layer / File(s) Summary
Rune behavior and metadata tests
tests/test_runes_*.py
Tests rune formatting, metadata discovery, firewall and SSH configuration, profiles, Telemt checks, and SSH-key installation.

Smithy

Layer / File(s) Summary
Smithy utilities and installation tests
tests/test_smithy_*.py
Covers architecture, GitHub releases, HTTP, binary installation, networking, monitoring, packages, services, SNI, swap, system, and version handling.

Templates

Layer / File(s) Summary
Template rendering tests
tests/test_templates*.py
Validates template lookup, Jinja rendering, Telemt TOML generation, and optional systemd service directives.

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

Possibly related PRs

Suggested labels: cli, foundry, smithy, molds, runes, templates

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.83% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding a tests dependency group and pytest configuration.
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 unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/add-tests

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.

@wlix13 wlix13 self-assigned this Jul 25, 2026
@github-actions github-actions Bot added tests Testing dependencies Changes to dependencies labels Jul 25, 2026
@wlix13
wlix13 force-pushed the feature/add-tests branch from 64052b9 to 68b2350 Compare July 25, 2026 21:26

@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: 2

🧹 Nitpick comments (3)
tests/test_foundry.py (1)

15-18: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Move BASE_SYSTEM/ensure_system imports to module level.

Both test functions re-import these locally instead of using the top-level import block (where BASE_FEATURES/ensure_features already live). Minor duplication.

♻️ Suggested fix
 from nullforge.molds.defaults import BASE_FEATURES
+from nullforge.molds.defaults import BASE_SYSTEM
 from nullforge.molds.utils import ensure_features
+from nullforge.molds.utils import ensure_system

then drop the local imports inside each test body.

Also applies to: 35-38

🤖 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_foundry.py` around lines 15 - 18, Move the BASE_SYSTEM and
ensure_system imports into the module-level import block alongside BASE_FEATURES
and ensure_features, then remove the duplicated local imports from both test
functions while preserving their existing usage.
tests/conftest.py (1)

30-42: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Shared _ops mock across 7 unrelated operation modules risks cross-test call-history pollution.

server, systemd, files, git, apt, dnf, and python are all patched with the exact same MagicMock() instance, and it's never reset between tests (patchers start once at import and stop only at session end). Any two of these modules sharing an attribute name will share call history, and history accumulates for the whole session. This is fine for the current cohort (no assertions inspect _ops), but it's a latent flakiness risk for later test layers (molds/runes/Smithy) that build on this fixture.

♻️ Suggested fix: give each module its own mock
-_ops = MagicMock()
-
 _patchers = [
     patch("pyinfra.context.host", _mock_host),
-    patch("pyinfra.operations.server", _ops),
-    patch("pyinfra.operations.systemd", _ops),
-    patch("pyinfra.operations.files", _ops),
-    patch("pyinfra.operations.git", _ops),
-    patch("pyinfra.operations.apt", _ops),
-    patch("pyinfra.operations.dnf", _ops),
-    patch("pyinfra.operations.python", _ops),
+    patch("pyinfra.operations.server", MagicMock()),
+    patch("pyinfra.operations.systemd", MagicMock()),
+    patch("pyinfra.operations.files", MagicMock()),
+    patch("pyinfra.operations.git", MagicMock()),
+    patch("pyinfra.operations.apt", MagicMock()),
+    patch("pyinfra.operations.dnf", MagicMock()),
+    patch("pyinfra.operations.python", MagicMock()),
     patch.object(_pyinfra_local, "include", MagicMock()),
 ]
🤖 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/conftest.py` around lines 30 - 42, Replace the shared _ops MagicMock
used in _patchers with a distinct mock for each patched operation module:
server, systemd, files, git, apt, dnf, and python. Keep the existing patch
targets and behavior unchanged while ensuring each module has isolated call
history.
tests/test_runes_netsec.py (1)

106-120: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Test re-derives conntrack_max_for's formula instead of calling it.

get_total_memory is mocked but conntrack_max_for is not, so the assertion is built from an independently reimplemented formula (TOTAL_MEMORY * 1024 * 1024 * 0.02 / 300) rather than the real function's output. If the production formula changes, this test won't detect the drift reliably.

♻️ Suggested fix: derive the expected value from the real function
-    def test_injects_ram_derived_sizing(self) -> None:
+    def test_injects_ram_derived_sizing(self) -> None:
+        from nullforge.runes.netsec import conntrack_max_for
         with (
             patch("nullforge.runes.netsec.module_loaded", return_value=True),
             patch("nullforge.runes.netsec.get_total_memory", return_value=self.TOTAL_MEMORY),
         ):
             result = _resolve_conntrack_sysctls({"net.netfilter.nf_conntrack_udp_timeout": 30})

-        ct_max_target = int(self.TOTAL_MEMORY * 1024 * 1024 * 0.02 / 300)
+        ct_max_target = conntrack_max_for(self.TOTAL_MEMORY)
         ct_buckets = max(4096, (ct_max_target + 3) // 4)
🤖 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_runes_netsec.py` around lines 106 - 120, Update
test_injects_ram_derived_sizing to derive the expected conntrack target by
calling the production conntrack_max_for function with the mocked TOTAL_MEMORY,
rather than reimplementing its formula locally. Keep the existing bucket
rounding, range, and configured-timeout assertions unchanged.
🤖 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_models_dns.py`:
- Around line 18-26: Update test_quad9_doh_no_ecs and test_quad9_doh_with_ecs to
assert that the filtered doh list is non-empty, or matches the expected server
count, before checking URL contents; retain the existing URL assertions for the
selected DoH endpoints.

In `@tests/test_molds_utils.py`:
- Around line 49-53: Update test_sub_mold_overrides_field to construct the
overlay DnsMold with a non-default mode such as DnsMode.NONE, while keeping the
expected result assertion aligned with that value so the test verifies
merge_features applies the sub-mold override.

---

Nitpick comments:
In `@tests/conftest.py`:
- Around line 30-42: Replace the shared _ops MagicMock used in _patchers with a
distinct mock for each patched operation module: server, systemd, files, git,
apt, dnf, and python. Keep the existing patch targets and behavior unchanged
while ensuring each module has isolated call history.

In `@tests/test_foundry.py`:
- Around line 15-18: Move the BASE_SYSTEM and ensure_system imports into the
module-level import block alongside BASE_FEATURES and ensure_features, then
remove the duplicated local imports from both test functions while preserving
their existing usage.

In `@tests/test_runes_netsec.py`:
- Around line 106-120: Update test_injects_ram_derived_sizing to derive the
expected conntrack target by calling the production conntrack_max_for function
with the mocked TOTAL_MEMORY, rather than reimplementing its formula locally.
Keep the existing bucket rounding, range, and configured-timeout assertions
unchanged.
🪄 Autofix (Beta)

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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a039af68-916a-4396-95b5-ae9be5dd7a9a

📥 Commits

Reviewing files that changed from the base of the PR and between 878a59a and 68b2350.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (46)
  • pyproject.toml
  • tests/__init__.py
  • tests/cli/__init__.py
  • tests/cli/components/__init__.py
  • tests/cli/components/completion/__init__.py
  • tests/cli/components/completion/test_controller.py
  • tests/cli/components/completion/test_powershell.py
  • tests/cli/components/foundry/__init__.py
  • tests/cli/components/foundry/test_controller.py
  • tests/cli/conftest.py
  • tests/cli/core/__init__.py
  • tests/cli/core/test_application.py
  • tests/cli/test_types.py
  • tests/conftest.py
  • tests/test_foundry.py
  • tests/test_foundry_cast.py
  • tests/test_foundry_pyinfra.py
  • tests/test_models_dns.py
  • tests/test_molds_dns.py
  • tests/test_molds_monitoring.py
  • tests/test_molds_netsec.py
  • tests/test_molds_telemt.py
  • tests/test_molds_user.py
  • tests/test_molds_utils.py
  • tests/test_runes_dns.py
  • tests/test_runes_meta.py
  • tests/test_runes_misc.py
  • tests/test_runes_netsec.py
  • tests/test_runes_profiles.py
  • tests/test_runes_telemt.py
  • tests/test_runes_users.py
  • tests/test_smithy_arch.py
  • tests/test_smithy_github.py
  • tests/test_smithy_http.py
  • tests/test_smithy_install.py
  • tests/test_smithy_network.py
  • tests/test_smithy_nezha.py
  • tests/test_smithy_nezha_dashboard.py
  • tests/test_smithy_packages.py
  • tests/test_smithy_service.py
  • tests/test_smithy_sni.py
  • tests/test_smithy_swap.py
  • tests/test_smithy_system.py
  • tests/test_smithy_versions.py
  • tests/test_templates.py
  • tests/test_templates_telemt.py

Comment thread tests/test_models_dns.py
Comment thread tests/test_molds_utils.py Outdated
@wlix13
wlix13 force-pushed the feature/add-tests branch from 68b2350 to ec70c14 Compare July 25, 2026 22:02
@wlix13
wlix13 merged commit 29995c0 into main Jul 25, 2026
9 checks passed
@wlix13
wlix13 deleted the feature/add-tests branch July 25, 2026 22:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Changes to dependencies tests Testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant