Skip to content

Fix runtime dependency handling and verify production scanner path - #344

Closed
somethingwithproof wants to merge 3 commits into
Cacti:developfrom
somethingwithproof:fix/runtime-dependency-contract
Closed

Fix runtime dependency handling and verify production scanner path#344
somethingwithproof wants to merge 3 commits into
Cacti:developfrom
somethingwithproof:fix/runtime-dependency-contract

Conversation

@somethingwithproof

@somethingwithproof somethingwithproof commented Sep 2, 2026

Copy link
Copy Markdown
Member

Fixes #343

What this does

  • centralizes Composer runtime bootstrapping and fails closed with actionable errors
  • uses PSR-4 for new MacTrack runtime code
  • validates plugin enablement and the resolver entry point when dependencies are absent
  • adds a PHP 8.3 Docker gate for the full Pest suite and 100% line coverage of all new runtime code
  • adds a production-path Docker test using current Cacti develop, MariaDB, and a live Net-SNMP agent
  • runs both the real mactrack_scanner.php entry point and the real poller_mactrack.php scheduler-to-worker path, then verifies persisted scan state
  • installs locked Cacti and MacTrack production dependencies inside Docker from a clean checkout

Validation

  • tests/docker/run-tests.sh: 14 tests passed; new runtime code 100.00% covered; Composer validation passed
  • clean tests/e2e/run-mactrack-e2e.sh: both lock files installed inside Docker, then Cacti installation, plugin installation, live SNMP scan, poller subprocess scan, database assertions, and missing-dependency failure path passed on PHP 8.3
  • actionlint: passed
  • git diff --check: passed

CI follow-up

The clean GitHub runner exposed two assumptions hidden by an existing local worktree: no archive extractor in the image, and incomplete committed Cacti autoload artifacts. The image now includes unzip, and the bootstrap installs both Cacti and MacTrack lock files before execution. The same production test passes locally from clean dependency state; the pushed commits rerun GitHub CI.

@somethingwithproof

Copy link
Copy Markdown
Member Author

Superseded by #345. Plugin directories carry no composer.json, so the fail-closed bootstrap here is the wrong direction; the Docker production-path harness will come back as its own PR.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The new dependency bootstrap can still fatally error in the presence of an unreadable autoload.php, and the new production probe has a concrete argument/row-validation bug that should be fixed before merging.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR hardens MacTrack’s runtime dependency handling so missing Composer installs fail closed with actionable diagnostics (instead of fatal errors), and adds Docker-based CI coverage that exercises the real production scanner/poller path against a live SNMP agent.

Changes:

  • Introduce a centralized DependencyBootstrap helper and wire it into setup.php and mactrack_resolver.php to report missing/unloadable Composer dependencies and exit cleanly.
  • Add a dedicated runtime test suite + 100% coverage gate for the new runtime/bootstrap code, plus a production-path Docker E2E that runs the real scanner and poller and asserts persisted scan state.
  • Update CI workflows to run the new Docker suites and install locked dependencies in clean checkouts.
File summaries
File Description
tests/Unit/test_device_type_sql_safety.php Updates string-signature assertions to detect the new dependency bootstrap integration.
tests/Pest/Unit/Runtime/fixtures/working-autoload.php Fixture autoloader that defines a required class for positive-path tests.
tests/Pest/Unit/Runtime/fixtures/throwing-autoload.php Fixture autoloader that throws to test failure reporting.
tests/Pest/Unit/Runtime/fixtures/empty-autoload.php Fixture autoloader with no classes to test “required class missing” handling.
tests/Pest/Unit/Runtime/DependencyBootstrapTest.php Unit tests validating dependency bootstrap behavior and messaging.
tests/e2e/snmpd.conf SNMP agent config for production-path Docker E2E.
tests/e2e/mactrack_production_probe.php Seeds test device/type and asserts scanner/poller persistence against SNMP fixture.
tests/e2e/Dockerfile Moves E2E image to PHP 8.3, adds unzip and Composer binary.
tests/e2e/docker-compose.yml Adds an SNMP agent service and healthcheck dependency for E2E.
tests/e2e/bootstrap-mactrack.sh Installs locked dependencies and runs scanner + poller + missing-deps resolver checks.
tests/docker/run-tests.sh Convenience wrapper to build/run the Docker test image.
tests/docker/Dockerfile Docker test runner for full Pest suite + runtime 100% coverage + composer validate.
src/Runtime/DependencyBootstrap.php New centralized runtime Composer bootstrap with error reporting and required-class checks.
setup.php Uses DependencyBootstrap to block enablement when runtime dependencies aren’t usable.
phpunit.runtime.xml PHPUnit config for runtime-only suite and coverage include for src/Runtime.
mactrack_resolver.php Uses DependencyBootstrap to fail closed (non-fatally) when Composer deps are absent/unloadable.
composer.json Adds PSR-4 autoload mapping for new runtime code + runtime coverage script.
CHANGELOG.md Notes issue #343 change.
.github/workflows/plugin-ci-workflow.yml Adds production-path job; improves MySQL init command usage.
.github/workflows/code-quality.yml Adds Docker runtime coverage job.
.dockerignore Avoids sending .git, cache, and vendor/ into Docker builds.
Review details
  • Files reviewed: 21/21 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +22 to +26
if (!is_file($autoloadPath)) {
$reporter('Mactrack requires Composer dependencies. Run composer install --no-dev in the plugin directory.');

return false;
}
Comment on lines +43 to +60
$deviceId = filter_var($argv[2] ?? null, FILTER_VALIDATE_INT);

if ($deviceId === false) {
fwrite(STDERR, "Production probe requires a numeric device id\n");
exit(2);
}

$device = db_fetch_row_prepared(
'SELECT snmp_status, snmp_sysDescr, device_type_id, last_rundate, last_runmessage
FROM mac_track_devices WHERE device_id = ?',
[$deviceId]
);

$passed = (int) ($device['snmp_status'] ?? 0) === HOST_UP
&& str_contains((string) ($device['snmp_sysDescr'] ?? ''), 'Linux')
&& (int) ($device['device_type_id'] ?? 0) > 0
&& ($device['last_rundate'] ?? '0000-00-00 00:00:00') !== '0000-00-00 00:00:00';

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug composer Dependabot composer updates QA Bug found in QA

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: make Composer runtime dependencies release-safe and prove scanner execution

2 participants