Add target list CLI option
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
"""Tests for CLI target-list argument parsing."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib
|
||||
import sys
|
||||
from types import SimpleNamespace
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
cli_main: Any = importlib.import_module("strix.interface.main")
|
||||
|
||||
|
||||
def _stub_settings(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setattr(
|
||||
cli_main,
|
||||
"load_settings",
|
||||
lambda: SimpleNamespace(runtime=SimpleNamespace(max_local_copy_mb=1024)),
|
||||
)
|
||||
|
||||
|
||||
def test_parse_arguments_accepts_target_list_file(
|
||||
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
target_list = tmp_path / "targets.txt"
|
||||
target_list.write_text(
|
||||
"https://test1.com/\n"
|
||||
"\n"
|
||||
"http://test2.com:5789/\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
_stub_settings(monkeypatch)
|
||||
monkeypatch.setattr(sys, "argv", ["strix", "--target-list", str(target_list), "-n"])
|
||||
|
||||
args = cli_main.parse_arguments()
|
||||
|
||||
assert [target["original"] for target in args.targets_info] == [
|
||||
"https://test1.com/",
|
||||
"http://test2.com:5789/",
|
||||
]
|
||||
assert [target["type"] for target in args.targets_info] == [
|
||||
"web_application",
|
||||
"web_application",
|
||||
]
|
||||
|
||||
|
||||
def test_parse_arguments_combines_target_and_target_list(
|
||||
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
target_list = tmp_path / "targets.txt"
|
||||
target_list.write_text("http://test2.com:5789/\n", encoding="utf-8")
|
||||
_stub_settings(monkeypatch)
|
||||
monkeypatch.setattr(
|
||||
sys,
|
||||
"argv",
|
||||
["strix", "-t", "https://test1.com/", "--target-list", str(target_list)],
|
||||
)
|
||||
|
||||
args = cli_main.parse_arguments()
|
||||
|
||||
assert [target["original"] for target in args.targets_info] == [
|
||||
"https://test1.com/",
|
||||
"http://test2.com:5789/",
|
||||
]
|
||||
|
||||
|
||||
def test_parse_arguments_rejects_resume_with_target_list(
|
||||
tmp_path: Path, monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
|
||||
) -> None:
|
||||
target_list = tmp_path / "targets.txt"
|
||||
target_list.write_text("https://test1.com/\n", encoding="utf-8")
|
||||
monkeypatch.setattr(
|
||||
sys,
|
||||
"argv",
|
||||
["strix", "--resume", "old-run", "--target-list", str(target_list)],
|
||||
)
|
||||
|
||||
with pytest.raises(SystemExit):
|
||||
cli_main.parse_arguments()
|
||||
|
||||
assert (
|
||||
"Cannot combine --resume with --target/--target-list/--mount"
|
||||
in capsys.readouterr().err
|
||||
)
|
||||
@@ -19,6 +19,7 @@ from strix.interface.utils import (
|
||||
dedupe_local_targets,
|
||||
directory_size_bytes,
|
||||
find_oversized_local_targets,
|
||||
read_target_list_file,
|
||||
)
|
||||
|
||||
|
||||
@@ -157,6 +158,42 @@ def test_build_mount_targets_info_rejects_empty_path(empty: str) -> None:
|
||||
build_mount_targets_info([empty])
|
||||
|
||||
|
||||
def test_read_target_list_file_strips_blank_lines(tmp_path: Path) -> None:
|
||||
target_list = tmp_path / "targets.txt"
|
||||
target_list.write_text(
|
||||
"\n"
|
||||
" https://test1.com/ \n"
|
||||
"\n"
|
||||
"http://test2.com:5789/\n"
|
||||
" \n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
assert read_target_list_file(str(target_list)) == [
|
||||
"https://test1.com/",
|
||||
"http://test2.com:5789/",
|
||||
]
|
||||
|
||||
|
||||
def test_read_target_list_file_rejects_empty_file(tmp_path: Path) -> None:
|
||||
target_list = tmp_path / "targets.txt"
|
||||
target_list.write_text(" \n\n", encoding="utf-8")
|
||||
|
||||
with pytest.raises(ValueError, match="is empty"):
|
||||
read_target_list_file(str(target_list))
|
||||
|
||||
|
||||
def test_read_target_list_file_rejects_missing_path(tmp_path: Path) -> None:
|
||||
with pytest.raises(ValueError, match="not an existing file"):
|
||||
read_target_list_file(str(tmp_path / "missing.txt"))
|
||||
|
||||
|
||||
@pytest.mark.parametrize("empty", ["", " "])
|
||||
def test_read_target_list_file_rejects_empty_path(empty: str) -> None:
|
||||
with pytest.raises(ValueError, match="must not be empty"):
|
||||
read_target_list_file(empty)
|
||||
|
||||
|
||||
def test_dedupe_keeps_distinct_targets_in_order() -> None:
|
||||
targets = [
|
||||
_local_target("/a"),
|
||||
|
||||
Reference in New Issue
Block a user