From 2ee0123b0090c89724e53a4c3eec14980f3e5496 Mon Sep 17 00:00:00 2001 From: Justin Bollinger Date: Mon, 4 May 2026 09:01:57 -0400 Subject: [PATCH] =?UTF-8?q?test(pcfg):=20tighten=20hcatPCFG=20test=20?= =?UTF-8?q?=E2=80=94=20patch=20globals,=20assert=20stdin=20pipe,=20drop=20?= =?UTF-8?q?unused?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_main_pcfg.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/test_main_pcfg.py b/tests/test_main_pcfg.py index 4bf0cfa..c606bd6 100644 --- a/tests/test_main_pcfg.py +++ b/tests/test_main_pcfg.py @@ -1,26 +1,18 @@ """Tests for PCFG attack subprocess construction in hate_crack.main.""" -import sys from pathlib import Path from unittest.mock import MagicMock, patch import pytest -PROJECT_ROOT = Path(__file__).resolve().parents[1] - - @pytest.fixture -def hc_main(monkeypatch): - """Load hate_crack.main with SKIP_INIT and stub external bits.""" - monkeypatch.setenv("HATE_CRACK_SKIP_INIT", "1") - if "hate_crack.main" in sys.modules: - del sys.modules["hate_crack.main"] - import hate_crack.main as m - return m +def main_module(hc_module): + """Return the underlying hate_crack.main module for direct patching.""" + return hc_module._main class TestHcatPCFG: - def test_builds_expected_subprocess(self, hc_main, tmp_path): + def test_builds_expected_subprocess(self, main_module, tmp_path): hash_file = str(tmp_path / "hashes.txt") Path(hash_file).write_text("dummy") @@ -34,8 +26,11 @@ class TestHcatPCFG: with patch("hate_crack.main.subprocess.Popen", side_effect=FakeProc), \ patch("hate_crack.main._run_hcat_cmd") as mock_run, \ - patch.object(hc_main, "generate_session_id", return_value="test_session"): - hc_main.hcatPCFG("0", hash_file) + patch.object(main_module, "hcatBin", "hashcat"), \ + patch.object(main_module, "hcatTuning", ""), \ + patch.object(main_module, "hcatPotfilePath", ""), \ + patch.object(main_module, "generate_session_id", return_value="test_session"): + main_module.hcatPCFG("0", hash_file) # First Popen call is the pcfg_guesser producer producer_args, producer_kwargs = captured_calls[0] @@ -43,9 +38,9 @@ class TestHcatPCFG: assert "python3" in producer_cmd[0] or producer_cmd[0].endswith("python3") assert any("pcfg_guesser.py" in part for part in producer_cmd) assert "--rule" in producer_cmd - assert producer_cmd[producer_cmd.index("--rule") + 1] == hc_main.pcfgRuleset + assert producer_cmd[producer_cmd.index("--rule") + 1] == main_module.pcfgRuleset assert "--limit" in producer_cmd - assert producer_cmd[producer_cmd.index("--limit") + 1] == str(hc_main.pcfgMaxCandidates) + assert producer_cmd[producer_cmd.index("--limit") + 1] == str(main_module.pcfgMaxCandidates) # _run_hcat_cmd was called with attack_name='PCFG' and the hashcat command assert mock_run.called @@ -59,3 +54,8 @@ class TestHcatPCFG: assert "-a" not in hashcat_cmd assert "-m" in hashcat_cmd assert hashcat_cmd[hashcat_cmd.index("-m") + 1] == "0" + + # Verify the producer is wired into hashcat's stdin via _run_hcat_cmd + assert kwargs["stdin"] is not None + assert kwargs["companion_procs"] is not None + assert len(kwargs["companion_procs"]) == 1