working command structure and advanced llm Integration
This commit is contained in:
1
tests/env/callback_test.txt
vendored
Normal file
1
tests/env/callback_test.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Hello World
|
||||
1
tests/env/empty_data.bin
vendored
Normal file
1
tests/env/empty_data.bin
vendored
Normal file
@@ -0,0 +1 @@
|
||||
just some plain text without any flags here
|
||||
0
tests/env/empty_test.txt
vendored
Normal file
0
tests/env/empty_test.txt
vendored
Normal file
1
tests/env/flag_data.bin
vendored
Normal file
1
tests/env/flag_data.bin
vendored
Normal file
@@ -0,0 +1 @@
|
||||
garbage_data_here_flag{f0rens1cs_1s_fun}more_garbage
|
||||
1
tests/env/mismatch_image.png
vendored
Normal file
1
tests/env/mismatch_image.png
vendored
Normal file
@@ -0,0 +1 @@
|
||||
%PDF-1.4 header info
|
||||
2
tests/env/test_file.png
vendored
Normal file
2
tests/env/test_file.png
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
<EFBFBD>PNG
|
||||
|
||||
|
After Width: | Height: | Size: 8 B |
3
tests/env/test_image.png
vendored
Normal file
3
tests/env/test_image.png
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<EFBFBD>PNG
|
||||
|
||||
Extra bytes here
|
||||
|
After Width: | Height: | Size: 24 B |
@@ -1,6 +1,8 @@
|
||||
from pathlib import Path
|
||||
import toml
|
||||
from ctf.utils import load_config, active_categories, active_competitions
|
||||
from click.testing import CliRunner
|
||||
from ctf.utils import load_config, active_categories
|
||||
from ctf.forensics import forensics_group, inspect
|
||||
|
||||
# Define the persistent test environment path
|
||||
TEST_ENV = Path("tests/env")
|
||||
@@ -8,13 +10,13 @@ TEST_ENV = Path("tests/env")
|
||||
def test_load_config_static():
|
||||
"""
|
||||
Verifies load_config using the persistent test file.
|
||||
Demonstrates: Reading from a specific relative Path.
|
||||
"""
|
||||
config_file = TEST_ENV / "config.toml"
|
||||
test_data = {
|
||||
"Competition": {"name": "PersistentComp"},
|
||||
"Enviroment": {"data_dir": str(TEST_ENV.absolute())}
|
||||
}
|
||||
config_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
with open(config_file, "w") as f:
|
||||
toml.dump(test_data, f)
|
||||
|
||||
@@ -24,25 +26,76 @@ def test_load_config_static():
|
||||
def test_active_categories_static():
|
||||
"""
|
||||
Verifies active_categories using the pre-created 'comp1' folder.
|
||||
Demonstrates: Path.iterdir() behavior on a real directory.
|
||||
"""
|
||||
comp_dir = TEST_ENV / "comp1"
|
||||
comp_dir.mkdir(parents=True, exist_ok=True)
|
||||
(comp_dir / "web").mkdir(exist_ok=True)
|
||||
(comp_dir / "pwn").mkdir(exist_ok=True)
|
||||
|
||||
cats = active_categories(comp_dir)
|
||||
cat_names = [c.name for c in cats]
|
||||
|
||||
# We expect 'web' and 'pwn' which were created in the setup step
|
||||
assert "web" in cat_names
|
||||
assert "pwn" in cat_names
|
||||
|
||||
def test_active_competitions_static():
|
||||
# --- Direct Function Callback Tests ---
|
||||
|
||||
def test_inspect_callback_success():
|
||||
"""
|
||||
Verifies active_competitions skips the 'tools' folder in TEST_ENV.
|
||||
Demonstrates: Guard clauses and directory filtering.
|
||||
Verifies that calling the inspect command's callback directly returns
|
||||
the correct FileMetadata dataclass with expected values.
|
||||
"""
|
||||
# Note: active_competitions takes a string path
|
||||
comps = active_competitions(str(TEST_ENV))
|
||||
comp_names = [p.name for p in comps.keys()]
|
||||
test_file = TEST_ENV / "callback_test.txt"
|
||||
with open(test_file, "wb") as f:
|
||||
f.write(b"Hello World")
|
||||
|
||||
# Using inspect.callback to invoke the underlying undecorated function
|
||||
meta = inspect.callback(str(test_file))
|
||||
|
||||
assert "comp1" in comp_names
|
||||
assert "comp2" in comp_names
|
||||
assert "tools" not in comp_names # The 'tools' folder exists but should be ignored
|
||||
assert meta.filename == "callback_test.txt"
|
||||
assert meta.size == 11
|
||||
assert meta.magic == "48656C6C" # Hex for "Hell"
|
||||
assert meta.extension == ".txt"
|
||||
|
||||
def test_inspect_callback_empty_file():
|
||||
"""
|
||||
Tests the boundary case of an empty (0-byte) file.
|
||||
Verifies that the parser handles it gracefully without raising exceptions.
|
||||
"""
|
||||
test_file = TEST_ENV / "empty_test.txt"
|
||||
with open(test_file, "wb") as f:
|
||||
pass
|
||||
|
||||
meta = inspect.callback(str(test_file))
|
||||
|
||||
assert meta.filename == "empty_test.txt"
|
||||
assert meta.size == 0
|
||||
assert meta.magic == "" # Empty string as no bytes could be read
|
||||
assert meta.extension == ".txt"
|
||||
|
||||
# --- CLI Integration Tests ---
|
||||
|
||||
def test_forensics_inspect_cli_success():
|
||||
"""
|
||||
Verifies that 'forensics inspect' successfully runs via the CLI and prints
|
||||
the metadata in a formatted table.
|
||||
"""
|
||||
runner = CliRunner()
|
||||
test_file = TEST_ENV / "test_file.png"
|
||||
with open(test_file, "wb") as f:
|
||||
f.write(b"\x89PNG\r\n\x1a\n")
|
||||
|
||||
result = runner.invoke(forensics_group, ["inspect", str(test_file)])
|
||||
assert result.exit_code == 0
|
||||
assert "Metadata: test_file.png" in result.output
|
||||
assert "Size" in result.output
|
||||
assert "89504E47" in result.output # Hex representation of PNG signature
|
||||
|
||||
def test_forensics_inspect_cli_missing_file():
|
||||
"""
|
||||
Verifies that the CLI fails gracefully when a non-existent file path is specified.
|
||||
"""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(forensics_group, ["inspect", "non_existent_file.png"])
|
||||
assert result.exit_code != 0
|
||||
assert "does not exist" in result.output
|
||||
|
||||
Reference in New Issue
Block a user