Commit Graph
11 Commits
Author SHA1 Message Date
maziggy a3c1878f11 chore(deps): floor-pin sqlalchemy >=2.0.38, pin ruff exactly, align CI lint
sqlalchemy 2.0.38 switched the aiosqlite file-db pool from NullPool to
AsyncAdaptedQueuePool; _create_engine() passes pool_size/max_overflow on the
SQLite branch, so anything older dies at import. Postgres installs are
unaffected -- the branch is dead there.

The CI lint job ran `pip install ruff` (newest) while requirements-dev.txt
said >=0.8.0, so CI and contributors enforced different rule sets: ruff 0.8.4
reports 32 errors on a tree current ruff calls clean, 30 of them the since-
removed UP038. Pin ruff exactly and have CI install that pin.
2026-07-09 16:29:39 +02:00
maziggy 0b43ac0d25 chore(deps): floor-pin pydantic-settings >=2.14.2 + msgpack >=1.2.1 for clean pip-audit
pip-audit flagged two advisories at the resolved versions in the venv.
  Neither is reachable in shipped Bambuddy, but the pins are taken so
  the audit stays clean and a future reachable advisory in either
  package isn't masked by existing noise.

  pydantic-settings 2.14.2 patches GHSA-4xgf-cpjx-pc3j —
  NestedSecretsSettingsSource with secrets_nested_subdir=True followed
  symlinks pointing outside the configured secrets_dir, reading
  out-of-tree files into settings values and bypassing the documented
  secrets_dir_max_size cap. Affected: >=2.12.0, <2.14.2. Bambuddy uses
  pydantic-settings only for env-var-backed config; the secrets-dir
  loader is not used (grep clean on NestedSecretsSettingsSource /
  secrets_nested_subdir / secrets_dir under backend/).

  msgpack 1.2.1 patches GHSA-6v7p-g79w-8964 — reusing an Unpacker
  instance after it caught an error can crash with SEGV, which is a
  DoS vector on untrusted input. msgpack is not a runtime dep of
  Bambuddy; it enters the tree only as a transitive of CacheControl,
  itself pulled by pip-audit (the very tool that surfaced the
  advisory). Pin placed in requirements-dev.txt next to pip-audit so
  it travels with the security-scan tooling rather than implying a
  runtime use.
2026-06-25 15:27:17 +02:00
maziggy ca08f1f340 fix(test): stop sys.modules-deleting backend.app.main in test_code_quality
+ ci: shard backend tests 4-way + drop -v for ~3.5x wall-clock speedup

  Root cause of the 4 CI failures on PR #1514 (all in
  test_print_start_assigns_printer_id_to_vp_archive.py +
  test_timelapse_baseline_restart_recovery.py): test_all_modules_importable
  in test_code_quality.py was deleting backend.app.main from sys.modules
  and re-importing it via importlib.import_module. That created NEW
  module-level dicts (_timelapse_baselines, _expected_prints,
  _active_prints, …) and re-ran root_logger.addHandler — hence the
  duplicate log lines at the same microsecond in captured stderr.

  Any sibling test that bound those names via "from backend.app.main
  import _timelapse_baselines" before the reimport now held a reference
  to the OLD dict; production code (reached via "from backend.app.main
  import on_print_start") resolved the symbol through the NEW module
  instance. Production mutated the new dict, the test read the old one,
  the assertion saw None / un-mutated mock_archive.

  Locally with -n 30, xdist load-balanced test_code_quality.py to a
  different worker process so the collision never happened (which is
  why the suite was green for me). CI's -n auto = -n 2 on ubuntu-latest
  made the collision deterministic.

  Fix: drop the "del sys.modules[name]" step. importlib.import_module
  already returns the cached module if cached, or runs the import
  machinery if not — either way, any import-time error surfaces. The
  "fresh import" framing was theatre; in practice every module in the
  list is already imported by other tests/fixtures before this test
  runs, so we were never actually getting a fresh import anyway — just
  destruction.

  CI workflow tightening (separate concern, same PR since both touch
  the test infrastructure):

  - Dropped -v from the pytest invocation. 5300+ "PASSED foo::bar"
    lines per worker were eating ~30-60s of stdout I/O on 2-vCPU
    runners. --tb=short is sufficient for failure context.
  - Sharded backend-tests into a 4-way matrix via pytest-split (new
    dev dep). Each shard runs ~1326 tests in ~95s on a 2-vCPU runner;
    all 4 run in parallel so wall-clock drops from 362s -> ~100s.
  - fail-fast: false on the matrix so a single failing shard doesn't
    hide failures in the other three — PRs see the complete failure
    picture in one push.
2026-05-24 12:51:24 +02:00
maziggy fc116f2f82 Removed unused i18next-http-backend 2026-04-23 08:51:12 +02:00
maziggy ffec267df1 Updated requirements-dev.txt 2026-04-22 19:44:59 +02:00
maziggy 407c9f84cf Bump pyOpenSSL and pyasn1 to fix 3 CVEs
pyOpenSSL 25.3.0 → 26.0.0 (CVE-2026-27448, CVE-2026-27459)
  pyasn1 0.6.2 → 0.6.3 (CVE-2026-30922)

  No breaking changes — Python 3.7 drop is irrelevant (we use 3.13),
  cryptography >=46.0.0 requirement already satisfied (we have 46.0.5),
  and we don't use set_tlsext_servername_callback (the behavioral change).
2026-03-22 13:24:36 +01:00
maziggy 5d0d249f1d Fix CI backend-tests failing to collect FTP test suite
CI only installed requirements.txt, missing pyOpenSSL from
requirements-dev.txt. This caused an ImportError on
TLS_FTPHandler during test collection, blocking all
unit/services tests. Also adds pytest-timeout to dev deps
instead of ad-hoc pip install in CI.
2026-02-10 17:50:32 +01:00
maziggy f2468077fe Add mock FTPS server and comprehensive FTP test suite (67 tests)
FTP bugs have been the #1 recurring issue across releases (0.1.8+).
This adds a real implicit FTPS mock server and 67 test cases covering
every known failure mode — connection, upload, download, delete, storage
info, model-specific SSL behavior, async wrappers, and failure injection.

New files:
- mock_ftp_server.py: implicit FTPS server on pyftpdlib with failure injection
- conftest.py: FTP test fixtures (certs, server, client factory)
- test_bambu_ftp.py: 67 tests across 10 test classes

Also adds pyOpenSSL to requirements-dev.txt (needed by pyftpdlib
TLS_FTPHandler in the Docker test image).
2026-02-07 10:55:05 +01:00
maziggy 53bd4fadb3 Fix safe security findings: hashlib, log injection, broad excepts
- Add usedforsecurity=False to MD5 (AMS fingerprint) and SHA1 (git blob
  hash) calls to silence Bandit B303 / CodeQL weak-crypto findings
- Convert ~996 f-string logging calls to parameterized %s-style across
  55 files to prevent log injection (Bandit G201 / CodeQL log-injection)
- Narrow ~199 broad except Exception blocks to specific types:
  OperationalError for DB migrations, OSError for network/file cleanup,
  (OSError, ftplib.error_reply) for FTP, and targeted tuples for
  ZIP/XML/JSON parsing — 36 intentionally left broad (mixed async,
  re-raise patterns)
2026-02-06 11:37:59 +01:00
maziggy 964be0eb26 Improved Docker tests 2026-02-05 10:28:06 +01:00
maziggy 58c98b1075 Added docker test suite
Test Summary:
  - Build tests: 3 passed (image build, backend imports, static files)
  - Backend unit tests: 378 passed (9 docker tests excluded)
  - Frontend unit tests: 137 passed
  - Integration tests: 9 passed (health, API endpoints, persistence, WebSocket)

  Changes made to fix the Docker test suite:
  1. Added curl to the production Dockerfile for integration tests
  2. Removed deprecated version attribute from docker-compose.test.yml
  3. Added --pull flag to all build commands to ensure fresh images
  4. Added explicit build step before starting integration container
  5. Fixed WebSocket test to accept 200 as a valid response
  6. Excluded docker-marked tests from backend unit test runs (-m "not docker")
2025-12-14 09:15:49 +01:00