Files
NetAlertX/test/docker_tests/test_docker_compose_scenarios.json
Adam Outler 19cc5b0406 Unit tests
2026-01-03 01:13:47 +00:00

496 lines
18 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"tests": [
{
"file": "conftest.py",
"testname": "build_netalertx_test_image",
"conditions": "normal",
"expected_results": [
"* Docker test image 'netalertx-test' is built using docker buildx before any docker-based tests run",
"* If docker buildx fails, all docker tests are skipped with failure message"
]
},
{
"file": "test_container_environment.py",
"testname": "test_nonroot_custom_uid_logs_note",
"conditions": [
"* Container run with arbitrary non-root UID/GID (1001:1001 or 1502:1502)",
"* Fresh named volume at /data"
],
"expected_results": [
"* Container logs message about current UID/GID",
"* Log contains 'expected UID' guidance",
"* Container exits with returncode 0"
]
},
{
"file": "test_container_environment.py",
"testname": "test_missing_capabilities_triggers_warning",
"conditions": [
"* All capabilities dropped (cap_drop: ALL)",
"* No NET_ADMIN, NET_RAW, NET_BIND_SERVICE"
],
"expected_results": [
"* 'exec /bin/sh: operation not permitted' error in output",
"* Non-zero return code"
]
},
{
"file": "test_container_environment.py",
"testname": "test_running_as_root_is_blocked",
"conditions": [
"* Container run as user: 0 (root)"
],
"expected_results": [
"* Warning 'NetAlertX is running as ROOT' in output",
"* Message 'Permissions fixed for read-write paths.' in output",
"* Container exits with returncode 0 (warns but continues)"
]
},
{
"file": "test_container_environment.py",
"testname": "test_missing_host_network_warns",
"conditions": [
"* Container run without network_mode: host (bridge/default network)"
],
"expected_results": [
"* Warning 'not running with --network=host' in output"
]
},
{
"file": "test_container_environment.py",
"testname": "test_missing_app_conf_triggers_seed",
"conditions": [
"* Fresh named volume with no app.conf file"
],
"expected_results": [
"* 'Default configuration written to' message in output",
"* Container exits with returncode 0"
]
},
{
"file": "test_container_environment.py",
"testname": "test_missing_app_db_triggers_seed",
"conditions": [
"* Named volume with app.conf but no app.db file"
],
"expected_results": [
"* Database file /data/db/app.db is created",
"* Container exits with returncode 0"
]
},
{
"file": "test_container_environment.py",
"testname": "test_custom_port_without_writable_conf",
"conditions": [
"* Custom PORT=24444 and LISTEN_ADDR=127.0.0.1 environment variables set",
"* Nginx config mount (/tmp/nginx/active-config) is read-only (mode=500)"
],
"expected_results": [
"* 'Unable to write to' message in output",
"* Reference to '/tmp/nginx/active-config/netalertx.conf' in output",
"* Non-zero return code"
]
},
{
"file": "test_container_environment.py",
"testname": "test_excessive_capabilities_warning",
"conditions": [
"* Container run with extra capabilities beyond required (SYS_ADMIN, NET_BROADCAST)"
],
"expected_results": [
"* 'Excessive capabilities detected' message in output",
"* 'bounding caps:' list in output"
]
},
{
"file": "test_container_environment.py",
"testname": "test_appliance_integrity_read_write_mode",
"conditions": [
"* Container root filesystem is read-write (not read-only mode)"
],
"expected_results": [
"* 'Container is running as read-write, not in read-only mode' warning in output"
]
},
{
"file": "test_container_environment.py",
"testname": "test_zero_permissions_app_db_dir",
"conditions": [
"* /data/db directory has chmod 000 (no permissions)"
],
"expected_results": [
"* Mounts table shows ❌ for writeable status on /data/db",
"* 'Configuration issues detected' message in output",
"* Non-zero return code"
]
},
{
"file": "test_container_environment.py",
"testname": "test_zero_permissions_app_config_dir",
"conditions": [
"* /data/config directory has chmod 000 (no permissions)"
],
"expected_results": [
"* Mounts table shows ❌ for writeable status on /data/config",
"* 'Configuration issues detected' message in output",
"* Non-zero return code"
]
},
{
"file": "test_container_environment.py",
"testname": "test_mandatory_folders_creation",
"conditions": [
"* Plugins log directory (/tmp/log/plugins) is missing"
],
"expected_results": [
"* 'Creating Plugins log' message in output",
"* Mandatory folders are automatically created"
]
},
{
"file": "test_container_environment.py",
"testname": "test_writable_config_validation",
"conditions": [
"* app.conf is a directory instead of a regular file"
],
"expected_results": [
"* 'ATTENTION: Path is not a regular file.' warning in output"
]
},
{
"file": "test_container_environment.py",
"testname": "test_mount_analysis_ram_disk_performance",
"conditions": [
"* Persistent paths (/data/db, /data/config) mounted on tmpfs RAM disk"
],
"expected_results": [
"* Mounts table shows ✅ writeable, ✅ mount, ❌ ramdisk, ❌ dataloss for db and config paths",
"* 'Configuration issues detected' message in output",
"* Non-zero return code"
]
},
{
"file": "test_container_environment.py",
"testname": "test_mount_analysis_dataloss_risk",
"conditions": [
"* Persistent database/config paths mounted on non-persistent tmpfs filesystem"
],
"expected_results": [
"* Mounts table shows dataloss risk warnings for persistent paths",
"* 'Configuration issues detected' message in output",
"* Non-zero return code"
]
},
{
"file": "test_container_environment.py",
"testname": "test_restrictive_permissions_handling",
"conditions": [
"* Directory mounted with restrictive permissions (root:root, 755)"
],
"expected_results": [
"* Non-root user case: fails to write or shows 'Permission denied'/'Unable to write'",
"* Root user case: 'NetAlertX is running as ROOT' and 'Permissions fixed for read-write paths' messages",
"* After root fix: netalertx user can write to directory"
]
},
{
"file": "test_docker_compose_scenarios.py",
"testname": "test_missing_capabilities_compose",
"conditions": [
"* Docker compose with cap_drop: ALL (all capabilities dropped)",
"* Uses docker-compose.missing-caps.yml"
],
"expected_results": [
"* 'exec /root-entrypoint.sh: operation not permitted' error in output",
"* Non-zero return code"
]
},
{
"file": "test_docker_compose_scenarios.py",
"testname": "test_custom_port_with_unwritable_nginx_config_compose",
"conditions": [
"* Custom PORT=24444 environment variable",
"* Unwritable nginx config mount",
"* Uses docker-compose.mount-test.active_config_unwritable.yml"
],
"expected_results": [
"* 'unable to write' or 'nginx' message in output",
"* 'failed to chown' message in output",
"* 'cap_chown' reference in output",
"* 'missing-capabilities.md' documentation link in output",
"* Container exits with returncode 0 (warns but continues)"
]
},
{
"file": "test_docker_compose_scenarios.py",
"testname": "test_host_network_compose",
"conditions": "normal",
"expected_results": [
"* Container starts successfully with host networking",
"* No 'not running with --network=host' warning",
"* Container exits with returncode 0"
]
},
{
"file": "test_docker_compose_scenarios.py",
"testname": "test_normal_startup_no_warnings_compose",
"conditions": "normal",
"expected_results": [
"* 'Startup pre-checks' message in output",
"* No ❌ symbols in output",
"* /data row in mounts table shows ✅ for readable and writeable",
"* No 'Write permission denied' message",
"* No 'CRITICAL' messages",
"* No ⚠️ warning symbols",
"* No 'arning' or 'rror' text (case insensitive partial match for Warning/Error)"
]
},
{
"file": "test_docker_compose_scenarios.py",
"testname": "test_ram_disk_mount_analysis_compose",
"conditions": [
"* /data path mounted as tmpfs (RAM disk)",
"* Persistent data on non-persistent storage"
],
"expected_results": [
"* 'Configuration issues detected' message in output",
"* /data path appears in mounts table",
"* Non-zero return code due to dataloss risk"
]
},
{
"file": "test_docker_compose_scenarios.py",
"testname": "test_dataloss_risk_mount_analysis_compose",
"conditions": [
"* Persistent /data path mounted on tmpfs with uid=20211,gid=20211",
"* Non-persistent filesystem for persistent data"
],
"expected_results": [
"* 'Configuration issues detected' message in output",
"* /data path appears in output",
"* Non-zero return code due to dataloss risk"
]
},
{
"file": "test_entrypoint.py",
"testname": "test_skip_tests_env_var",
"conditions": [
"* SKIP_TESTS=1 environment variable set"
],
"expected_results": [
"* 'Skipping startup checks as SKIP_TESTS is set.' message in stdout",
"* No ' --> ' check output markers",
"* Container exits with returncode 0"
]
},
{
"file": "test_entrypoint.py",
"testname": "test_app_conf_override_from_graphql_port",
"conditions": [
"* GRAPHQL_PORT=20212 environment variable set",
"* APP_CONF_OVERRIDE is not set",
"* SKIP_TESTS=1 to skip checks"
],
"expected_results": [
"* 'APP_CONF_OVERRIDE detected' message in stderr",
"* No 'Setting APP_CONF_OVERRIDE to' message in stdout",
"* Container exits with returncode 0"
]
},
{
"file": "test_entrypoint.py",
"testname": "test_app_conf_override_not_overridden",
"conditions": [
"* Both GRAPHQL_PORT=20212 and APP_CONF_OVERRIDE={\"OTHER\":\"value\"} set",
"* SKIP_TESTS=1 to skip checks"
],
"expected_results": [
"* No 'Setting APP_CONF_OVERRIDE to' message (existing override preserved)",
"* Container exits with returncode 0"
]
},
{
"file": "test_entrypoint.py",
"testname": "test_no_app_conf_override_when_no_graphql_port",
"conditions": [
"* GRAPHQL_PORT is not set",
"* SKIP_TESTS=1 to skip checks"
],
"expected_results": [
"* No 'Setting APP_CONF_OVERRIDE to' message",
"* Container exits with returncode 0"
]
},
{
"file": "test_mount_diagnostics_pytest.py",
"testname": "test_mount_diagnostic",
"conditions": [
"* Parameterized test for each mount configuration scenario",
"* Scenarios: no-mount, ramdisk, mounted, unwritable for each path (db, config, api, log, run, active_config)",
"* Additional noread scenarios: data_noread, db_noread, tmp_noread, api_noread"
],
"expected_results": [
"* For issue scenarios: diagnostic table shows appropriate ❌/✅/ symbols",
"* For issue scenarios: troubleshooting URL present in output",
"* For issue scenarios: ⚠️ warning symbol in output",
"* For good config scenarios: table output with 'Path' header",
"* For good config scenarios: no ⚠️ warning symbol",
"* Container exit code matches expected (usually 0)"
]
},
{
"file": "test_mount_diagnostics_pytest.py",
"testname": "test_table_parsing",
"conditions": "normal",
"expected_results": [
"* parse_mount_table correctly parses sample mount diagnostic table",
"* assert_table_row correctly validates row values",
"* ✅=True, ❌=False, =None emoji mapping works"
]
},
{
"file": "test_mount_diagnostics_pytest.py",
"testname": "test_cap_chown_required_when_caps_dropped",
"conditions": [
"* CAP_CHOWN capability is missing",
"* Uses docker-compose.mount-test.cap_chown_missing.yml"
],
"expected_results": [
"* Container continues with warnings (exit code 0)",
"* 'failed to chown' message in logs",
"* 'CAP_CHOWN' reference in logs",
"* Troubleshooting URL present in logs"
]
},
{
"file": "test_ports_available.py",
"testname": "test_ports_available_normal_case",
"conditions": [
"* PORT=99991 and GRAPHQL_PORT=99992 (non-conflicting, unused ports)"
],
"expected_results": [
"* No 'Configuration Warning: Both ports are set to' message",
"* No 'Port Warning: Application port' message",
"* No 'Port Warning: GraphQL API port' message",
"* Container exits with returncode 0"
]
},
{
"file": "test_ports_available.py",
"testname": "test_ports_conflict_same_number",
"conditions": [
"* PORT=20211 and GRAPHQL_PORT=20211 (both set to same port)"
],
"expected_results": [
"* 'Configuration Warning: Both ports are set to 20211' message",
"* 'The Application port ($PORT) and the GraphQL API port' message",
"* 'are configured to use the' and 'same port. This will cause a conflict.' messages",
"* Container exits with returncode 0 (warns but continues)"
]
},
{
"file": "test_ports_available.py",
"testname": "test_ports_in_use_warning",
"conditions": [
"* Dummy container already occupying ports 20211 and 20212",
"* PORT=20211 and GRAPHQL_PORT=20212 configured"
],
"expected_results": [
"* 'Port Warning: Application port 20211 is already in use' message",
"* 'Port Warning: GraphQL API port 20212 is already in use' message",
"* Container exits with returncode 0 (warns but continues)"
]
},
{
"file": "test_puid_pgid.py",
"testname": "test_default_puid_pgid_ok",
"conditions": [
"* SKIP_TESTS=1 to skip startup checks",
"* Default PUID/PGID values"
],
"expected_results": [
"* Container exits with returncode 0"
]
},
{
"file": "test_puid_pgid.py",
"testname": "test_invalid_puid_pgid_rejected",
"conditions": [
"* Various invalid PUID/PGID values:",
" - PUID='0;rm -rf /' (shell injection attempt)",
" - PUID='$(id)' (command substitution attempt)",
" - PUID='-1' (negative value)",
" - PUID='99999999' (out of range)",
" - PGID='99999999' (out of range)"
],
"expected_results": [
"* Non-zero return code",
"* 'invalid characters' or 'out of range' message in output depending on test case"
]
},
{
"file": "test_puid_pgid.py",
"testname": "test_legacy_user_mode_skips_puid_pgid",
"conditions": [
"* PUID=1000 and PGID=1000 environment variables set",
"* Container run with --user 20211:20211 (legacy mode)"
],
"expected_results": [
"* 'PUID/PGID (1000:1000) will not be applied' message in output",
"* Container exits with returncode 0"
]
},
{
"file": "test_puid_pgid.py",
"testname": "test_synology_like_fresh_volume_is_primed",
"conditions": [
"* Fresh named volume with root-owned directories (simulating Synology behavior)",
"* PUID=1000 and PGID=1000 target ownership"
],
"expected_results": [
"* Container exits with returncode 0",
"* Volume ownership changed to 1000:1000 for /data, /data/config, /data/db"
]
},
{
"file": "test_puid_pgid.py",
"testname": "test_missing_cap_chown_fails_priming",
"conditions": [
"* Named volume with UID 1000 ownership",
"* PUID=20212, PGID=20212 (needs chown)",
"* CAP_CHOWN capability removed"
],
"expected_results": [
"* Container continues with warnings (exit code 0)",
"* 'failed to chown' message in output",
"* 'missing-capabilities' reference in output",
"* 'docs/docker-troubleshooting/missing-capabilities.md' documentation link"
]
},
{
"file": "test_docker_compose_scenarios.py",
"testname": "test_missing_net_admin_compose",
"conditions": [
"* docker-compose.missing-net-admin.yml",
"* Missing NET_ADMIN capability"
],
"expected_results": [
"* 'Raw network capabilities are missing' warning in output",
"* Container exits with returncode 0"
]
},
{
"file": "test_docker_compose_scenarios.py",
"testname": "test_missing_net_raw_compose",
"conditions": [
"* docker-compose.missing-net-raw.yml",
"* Missing NET_RAW capability"
],
"expected_results": [
"* 'Raw network capabilities are missing' warning in output",
"* Container exits with returncode 0"
]
}
]
}