Skip to content

feat: configure hypothesis fuzzing and bandit security scanning#72

Merged
eman merged 6 commits intomainfrom
feat/security-and-fuzzing
Feb 13, 2026
Merged

feat: configure hypothesis fuzzing and bandit security scanning#72
eman merged 6 commits intomainfrom
feat/security-and-fuzzing

Conversation

@eman
Copy link
Copy Markdown
Owner

@eman eman commented Feb 7, 2026

Summary

This PR adds comprehensive security and fuzzing capabilities to the nwp500-python project:

  • Property-based testing: Added hypothesis fuzzing tests for DeviceStatus model validation
  • Security scanning: Configured bandit security linting in CI/CD pipeline
  • Enhanced test coverage: Property-based tests that validate temperature conversions, unit switching, and data parsing across various input combinations

Changes Made

Testing Infrastructure

  • Added hypothesis to testing requirements in setup.cfg
  • Created tests/test_mqtt_hypothesis.py with property-based fuzz tests for:
    • DeviceStatus model validation with varying temperature types (Celsius/Fahrenheit)
    • Temperature conversion accuracy (HalfCelsius, DeciCelsius)
    • Flow rate conversions between metric and imperial units
    • Edge case handling for boundary values

Security Enhancements

  • Added bandit environment to tox.ini for security linting
  • Added dedicated security job to GitHub Actions workflow
  • Configured bandit to scan for common security vulnerabilities

Code Quality

  • All linting issues resolved (ruff formatting, import sorting, line length)
  • Comprehensive test coverage with both traditional and property-based tests
  • All tests pass locally and in CI

Testing

  • Property-based tests use Hypothesis to generate comprehensive test data
  • Tests validate temperature conversions, unit switching, and data parsing
  • Security scanning passes with no high-severity issues
  • Full test suite passes (403 passed, 3 skipped)

Breaking Changes

None. This is a purely additive feature that enhances security and test coverage.

eman added 4 commits February 6, 2026 23:25
- Add hypothesis to testing requirements in setup.cfg
- Add property-based fuzz tests for DeviceStatus model in tests/test_mqtt_hypothesis.py
- Add bandit environment to tox.ini for security linting
- Add security job to GitHub Actions workflow to run bandit
- Fix import sorting and remove duplicate imports
- Fix line length violations (>80 characters)
- Remove trailing whitespace and blank line whitespace
- Ensure proper code formatting for CI compliance
- Fix line length violations in comments (>80 characters)
- Ensure all ruff linting checks pass
- All tests continue to pass locally
- Add .bandit configuration file to skip B101 (assert_used) warnings
- Update tox.ini bandit environment to use configuration file
- Security check now passes while maintaining security scanning for actual vulnerabilities
- Assert statements in CLI rich output are low-severity and acceptable for this use case
@eman eman requested a review from Copilot February 9, 2026 19:42
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds property-based fuzz testing with Hypothesis and introduces Bandit security scanning via tox and GitHub Actions to improve test robustness and CI security checks.

Changes:

  • Added Hypothesis as a testing dependency and introduced a new property-based fuzz test suite for DeviceStatus.
  • Added a bandit tox environment and a dedicated CI job to run security scanning.
  • Added a .bandit configuration file to control Bandit rule behavior.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tox.ini Adds a bandit tox env and includes it in the envlist for security scanning.
tests/test_mqtt_hypothesis.py Adds Hypothesis-based fuzz tests validating DeviceStatus parsing and unit conversions.
setup.cfg Adds hypothesis under testing extras.
.github/workflows/ci.yml Adds a separate CI job to run tox -e bandit.
.bandit Configures Bandit skips (currently B101).

eman added 2 commits February 9, 2026 11:58
- Fix flow rate test to use lenient tolerance (abs=0.01) instead of manual rounding
  This avoids brittle assumptions about the converter's rounding behavior and instead
  relies on pytest.approx() to account for the model's 2-decimal rounding

- Improve bandit security scanning configuration
  Replaced global B101 skip with file-specific skip for src/nwp500/cli/rich_output.py
  This maintains security scanning rigor while acknowledging that assert statements
  are acceptable for type-narrowing checks in CLI optional feature code

- Note: 'heLowerOnTDiffempSetting' field name retains the API's existing typo
  as documented in the model's alias - this is the correct key expected by the
  DeviceStatus model validation

All 403 tests passing, security and linting checks passing
Copy link
Copy Markdown
Owner Author

@eman eman left a comment

Choose a reason for hiding this comment

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

Addressing review comments:

  1. Line 96 - heLowerOnTDiffempSetting: This is the correct field name; it reflects an actual typo in the Navien cloud API payload. The model correctly handles this with an alias mapping "heLowerOnTDiffempSetting" to he_lower_on_diff_temp_setting. The test payload intentionally uses the API's typo to validate the model's alias handling.

  2. Lines 48 & 69 - recircOperationBusy: These are NOT duplicates. Line 48 defines operationBusy (on line 48, different key), and line 69 defines recircOperationBusy. The reviewer may have misread the line numbers. Both keys are needed in the test payload.

  3. Rounding in flow rate test: Updated to use pytest.approx(gpm_val, abs=0.01) with 0.01 tolerance instead of manual rounding. This is now tolerance-based and resilient to model rounding changes.

  4. .bandit Configuration: Updated from global B101 skip to file-specific skip targeting only src/nwp500/cli/rich_output.py where asserts are used for type-narrowing when rich library is available. This maintains security rigor for the rest of the codebase.

@eman
Copy link
Copy Markdown
Owner Author

eman commented Feb 9, 2026

Re: Line 96 - heLowerOnTDiffempSetting

This is the correct field name reflecting an actual typo in the Navien API payload. The model correctly handles this with an alias mapping "heLowerOnTDiffempSetting" to the snake_case field he_lower_on_diff_temp_setting. The test payload intentionally uses the API's typo key to validate the model's alias handling works correctly.

@eman
Copy link
Copy Markdown
Owner Author

eman commented Feb 9, 2026

Re: Lines 48 & 69 - recircOperationBusy

These are NOT duplicates. Line 48 defines operationBusy (different key), and line 69 defines recircOperationBusy. Both keys are needed in the test payload and serve different purposes in the device status model.

@eman
Copy link
Copy Markdown
Owner Author

eman commented Feb 9, 2026

Re: Flow rate test rounding

Updated to use pytest.approx(gpm_val, abs=0.01) with 0.01 tolerance instead of manual rounding. This is now tolerance-based and resilient to model rounding changes.

@eman
Copy link
Copy Markdown
Owner Author

eman commented Feb 9, 2026

Re: .bandit B101 global skip

Updated from global B101 skip to file-specific configuration targeting only src/nwp500/cli/rich_output.py where asserts are used for type-narrowing when the optional rich library is available. This maintains full security scanning rigor for the rest of the codebase.

@eman eman merged commit 2329e97 into main Feb 13, 2026
8 checks passed
@eman eman deleted the feat/security-and-fuzzing branch February 13, 2026 06:46
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.

2 participants