fix unrelated test not using root-entrypoint properly.

This commit is contained in:
Adam Outler
2026-02-01 01:17:24 +00:00
parent 9d0627c5c3
commit 900e418be9
2 changed files with 28 additions and 25 deletions

View File

@@ -1,26 +1,28 @@
--- ---
name: testing-workflow name: testing-workflow
description: Guide for running tests within the NetAlertX environment. Detailed instructions for standard unit tests (fast), full suites (slow), and handling authentication. description: Read before running tests. Detailed instructions for single, astandard unit tests (fast), full suites (slow), and handling authentication. Tests must be run when a job is complete.
--- ---
# Testing Workflow # Testing Workflow
After code is developed, tests must be run to ensure the integrity of the final result.
**Crucial:** Tests MUST be run inside the container to access the correct runtime environment (DB, Config, Dependencies). **Crucial:** Tests MUST be run inside the container to access the correct runtime environment (DB, Config, Dependencies).
## 1. Standard Unit Tests (Recommended)
By default, run the standard unit test suite. This **excludes** slow tests marked with `docker` (requires socket access) or `feature_complete` (extended coverage). ## 1. Full Test Suite (MANDATORY DEFAULT)
Unless the user **explicitly** requests "fast" or "quick" tests, you **MUST** run the full test suite. **Do not** optimize for time. Comprehensive coverage is the priority over speed.
```bash ```bash
docker exec <CONTAINER_ID> bash -c "cd /workspaces/NetAlertX && pytest -m 'not docker and not feature_complete'" cd /workspaces/NetAlertX; pytest test/
``` ```
## 2. Full Test Suite (Slow) ## 2. Fast Unit Tests (Conditional)
To run **all** tests, including integration tests that require Docker socket access and extended feature coverage: **ONLY** use this if the user explicitly asks for "fast tests", "quick tests", or "unit tests only". This **excludes** slow tests marked with `docker` or `feature_complete`.
```bash ```bash
docker exec <CONTAINER_ID> bash -c "cd /workspaces/NetAlertX && pytest" cd /workspaces/NetAlertX; pytest test/ -m 'not docker and not feature_complete'
``` ```
## 3. Running Specific Tests ## 3. Running Specific Tests
@@ -28,12 +30,12 @@ docker exec <CONTAINER_ID> bash -c "cd /workspaces/NetAlertX && pytest"
To run a specific file or folder: To run a specific file or folder:
```bash ```bash
docker exec <CONTAINER_ID> bash -c "cd /workspaces/NetAlertX && pytest <path_to_test>" cd /workspaces/NetAlertX; pytest test/<path_to_test>
``` ```
*Example:* *Example:*
```bash ```bash
docker exec <CONTAINER_ID> bash -c "cd /workspaces/NetAlertX && pytest test/api_endpoints/test_mcp_extended_endpoints.py" cd /workspaces/NetAlertX; pytest test/api_endpoints/test_mcp_extended_endpoints.py
``` ```
## Authentication in Tests ## Authentication in Tests
@@ -41,12 +43,12 @@ docker exec <CONTAINER_ID> bash -c "cd /workspaces/NetAlertX && pytest test/api_
The test environment uses `API_TOKEN`. The most reliable way to retrieve the current token from a running container is: The test environment uses `API_TOKEN`. The most reliable way to retrieve the current token from a running container is:
```bash ```bash
docker exec <CONTAINER_ID> python3 -c "from helper import get_setting_value; print(get_setting_value('API_TOKEN'))" python3 -c "from helper import get_setting_value; print(get_setting_value('API_TOKEN'))"
``` ```
### Troubleshooting ### Troubleshooting
If tests fail with 403 Forbidden or empty tokens: If tests fail with 403 Forbidden or empty tokens:
1. Verify server is running and use the setup script (`/workspaces/NetAlertX/.devcontainer/scripts/setup.sh`) if required. 1. Verify server is running and use the setup script (`/workspaces/NetAlertX/.devcontainer/scripts/setup.sh`) if required.
2. Verify `app.conf` inside the container: `docker exec <ID> cat /data/config/app.conf` 2. Verify `app.conf` inside the container: `cat /data/config/app.conf`
3. Verify Python can read it: `docker exec <ID> python3 -c "from helper import get_setting_value; print(get_setting_value('API_TOKEN'))"` 3. Verify Python can read it: `python3 -c "from helper import get_setting_value; print(get_setting_value('API_TOKEN'))"`

View File

@@ -945,14 +945,14 @@ def test_missing_app_conf_triggers_seed(tmp_path: pathlib.Path) -> None:
"docker", "run", "--rm", "-v", f"{vol}:/data", "docker", "run", "--rm", "-v", f"{vol}:/data",
"alpine:3.22", "cat", "/data/config/app.conf" "alpine:3.22", "cat", "/data/config/app.conf"
], ],
capture_output=True, text=True capture_output=True, text=True, timeout=SUBPROCESS_TIMEOUT_SECONDS
) )
if check_conf.returncode == 0: assert check_conf.returncode == 0, f"Failed to read config. Stderr: {check_conf.stderr}, Stdout: {check_conf.stdout}"
match = re.search(r"SCAN_SUBNETS\s*=\s*(.*)", check_conf.stdout) match = re.search(r"SCAN_SUBNETS\s*=\s*(.*)", check_conf.stdout)
if match: if match:
val = match.group(1) val = match.group(1)
assert "interface=" in val, f"SCAN_SUBNETS should have interface: {val}" assert "interface=" in val, f"SCAN_SUBNETS should have interface: {val}"
assert val != "['--localnet']", "SCAN_SUBNETS should not be default localnet" assert val != "['--localnet']", "SCAN_SUBNETS should not be default localnet"
finally: finally:
_docker_volume_rm(vol) _docker_volume_rm(vol)
@@ -962,7 +962,6 @@ def test_missing_app_conf_triggers_seed(tmp_path: pathlib.Path) -> None:
# test passes if the config file was created. Full startup success is tested elsewhere. # test passes if the config file was created. Full startup success is tested elsewhere.
def test_first_run_dynamic_subnet(tmp_path: pathlib.Path) -> None: def test_first_run_dynamic_subnet(tmp_path: pathlib.Path) -> None:
"""Test dynamic subnet detection during first run config generation. """Test dynamic subnet detection during first run config generation.
@@ -972,11 +971,13 @@ def test_first_run_dynamic_subnet(tmp_path: pathlib.Path) -> None:
paths = _setup_mount_tree(tmp_path, "dynamic_subnet", seed_config=False) paths = _setup_mount_tree(tmp_path, "dynamic_subnet", seed_config=False)
mount_args = _build_volume_args_for_keys(paths, CONTAINER_TARGETS.keys()) mount_args = _build_volume_args_for_keys(paths, CONTAINER_TARGETS.keys())
_run_container( result_container = _run_container(
"dyn-subnet", "dyn-subnet",
volumes=mount_args, volumes=mount_args,
sleep_seconds=15, sleep_seconds=15,
user="0:0",
) )
assert result_container.returncode == 0, f"Container failed: {result_container.output}"
# Use docker to read the file to avoid permission issues (file is 600 root:root) # Use docker to read the file to avoid permission issues (file is 600 root:root)
# paths["app_config"] is the host absolute path # paths["app_config"] is the host absolute path
@@ -986,10 +987,10 @@ def test_first_run_dynamic_subnet(tmp_path: pathlib.Path) -> None:
"alpine:3.22", "alpine:3.22",
"cat", "/mnt/app.conf" "cat", "/mnt/app.conf"
] ]
result = subprocess.run(cmd, capture_output=True, text=True) read_result = subprocess.run(cmd, capture_output=True, text=True, timeout=SUBPROCESS_TIMEOUT_SECONDS)
assert result.returncode == 0, f"Could not read app.conf. Stderr: {result.stderr}" assert read_result.returncode == 0, f"Could not read app.conf. Stderr: {read_result.stderr}, Stdout: {read_result.stdout}"
content = result.stdout content = read_result.stdout
# Check that SCAN_SUBNETS was set to something other than the default fallback # Check that SCAN_SUBNETS was set to something other than the default fallback
# The default fallback in the script is ['--localnet'] if no interfaces found. # The default fallback in the script is ['--localnet'] if no interfaces found.