mirror of
https://github.com/trustedsec/hate_crack.git
synced 2026-03-12 21:23:05 -07:00
docs: rewrite TESTING.md and update README git hooks section
This commit is contained in:
20
README.md
20
README.md
@@ -351,15 +351,17 @@ uv run pytest --cov=hate_crack
|
||||
|
||||
### Git Hooks (prek)
|
||||
|
||||
Git hooks are managed by [prek](https://github.com/nicholasgasior/prek). Install hooks with:
|
||||
Git hooks are managed by [prek](https://github.com/j178/prek) (v0.3.3+). Install hooks with:
|
||||
|
||||
```bash
|
||||
prek install
|
||||
prek install --hook-type pre-push --hook-type post-commit
|
||||
```
|
||||
|
||||
This installs hooks defined in `prek.toml`:
|
||||
- **pre-push**: ruff check, ty check, pytest
|
||||
- **post-commit**: documentation audit
|
||||
This installs hooks defined in `prek.toml` using the pre-commit local-repo TOML schema:
|
||||
- **pre-push**: ruff, ty, pytest, pytest-lima
|
||||
- **post-commit**: audit-docs
|
||||
|
||||
Note: prek 0.3.3 expects `repos = [...]` at the top level. The old `[hooks.<stage>] commands = [...]` format is not supported.
|
||||
|
||||
### Optional Dependencies
|
||||
|
||||
@@ -582,6 +584,14 @@ HATE_CRACK_RUN_DOCKER_TESTS=1 uv run pytest tests/test_docker_script_install.py
|
||||
The Docker E2E test also downloads a small subset of rockyou and runs a basic
|
||||
hashcat crack to validate external tool integration.
|
||||
|
||||
Lima VM end-to-end test (macOS only, requires Lima):
|
||||
|
||||
```bash
|
||||
uv run pytest tests/test_lima_vm_install.py -v
|
||||
```
|
||||
|
||||
This test validates installation and execution within a lightweight Linux VM on macOS.
|
||||
|
||||
### Test Structure
|
||||
|
||||
- **tests/test_hashview.py**: Comprehensive test suite for HashviewAPI class with mocked API responses, including:
|
||||
|
||||
278
TESTING.md
278
TESTING.md
@@ -1,184 +1,144 @@
|
||||
# Testing Guide
|
||||
# Testing
|
||||
|
||||
## Overview
|
||||
The test suite uses mocked API responses and local fixtures so it can run without external services (Hashview, Hashmob, Weakpass). Most tests are fast and run entirely offline. Live network checks and system dependency checks are now opt-in via environment variables.
|
||||
|
||||
## Important: Asset Location
|
||||
|
||||
The application requires `hashcat-utils` and `princeprocessor` as subdirectories of the package. When installed via `make install`, these are vendored into the package automatically.
|
||||
|
||||
For development, run tests from the repository directory:
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
cd /path/to/hate_crack
|
||||
uv run pytest -v
|
||||
```
|
||||
|
||||
**Note:** `hcatPath` in `config.json` is for the **hashcat binary location** (optional if hashcat is in PATH), not for hate_crack assets.
|
||||
|
||||
## Changes Made
|
||||
|
||||
### 1. Test Files (Current)
|
||||
|
||||
**tests/test_hashview.py** (mocked Hashview API tests)
|
||||
- Added `unittest.mock` imports (Mock, patch, MagicMock)
|
||||
- Removed dependency on config.json file
|
||||
- Replaced all real API calls with mocked responses
|
||||
- Mock responses match the actual API response format (e.g., 'users' field as JSON string)
|
||||
- Includes comprehensive tests for:
|
||||
- Customer listing and validation
|
||||
- Authentication and authorization
|
||||
- Hashfile upload
|
||||
- Complete job creation workflow
|
||||
|
||||
**tests/test_api.py**
|
||||
- Tests for download functionality, 7z extraction triggers, exception handling, and progress bars
|
||||
- Uses mocked requests and filesystem operations
|
||||
|
||||
**tests/test_cli_menus.py**
|
||||
- Tests CLI menu flags (--hashview, --weakpass, --hashmob)
|
||||
- Skips by default unless respective TEST_REAL env vars are set
|
||||
|
||||
**tests/test_dependencies.py**
|
||||
- Checks local tool availability (7z, transmission-cli)
|
||||
- Skips missing dependency failures unless `HATE_CRACK_REQUIRE_DEPS=1` (or true/yes)
|
||||
|
||||
**tests/test_ui_menu_options.py**
|
||||
- Tests all menu option handlers (attacks 1-13, utilities 91-100)
|
||||
- Validates menu routing and function resolution
|
||||
|
||||
**tests/test_pipal.py** and **tests/test_pipal_integration.py**
|
||||
- Tests pipal analysis functionality and executable integration
|
||||
- Validates baseword parsing and output handling
|
||||
|
||||
**tests/test_submodule_hashcat_utils.py**
|
||||
- Verifies hashcat-utils submodule is initialized correctly
|
||||
|
||||
**tests/test_hashmob_connectivity.py**
|
||||
- Mocked Hashmob API connectivity test by default
|
||||
- Set `HASHMOB_TEST_REAL=1` to run against live Hashmob
|
||||
|
||||
### 2. Key Mock Patterns
|
||||
|
||||
```python
|
||||
# Example: Mocking list_customers response
|
||||
mock_response = Mock()
|
||||
mock_response.json.return_value = {
|
||||
'users': json.dumps([ # Note: 'users' is a JSON string in the real API
|
||||
{'id': 1, 'name': 'Test Customer'}
|
||||
])
|
||||
}
|
||||
mock_response.raise_for_status = Mock()
|
||||
api.session.get.return_value = mock_response
|
||||
```
|
||||
|
||||
### 3. Documentation
|
||||
|
||||
Updated `readme.md` with:
|
||||
- Testing section explaining how to run tests locally
|
||||
- Description of test structure
|
||||
|
||||
## Environment Variables for Live Tests
|
||||
|
||||
By default, external service checks are skipped. Enable them explicitly:
|
||||
|
||||
- `HASHMOB_TEST_REAL=1` — run live Hashmob tests (including connectivity and CLI menu flag)
|
||||
- `HASHVIEW_TEST_REAL=1` — run live Hashview CLI menu test
|
||||
- `WEAKPASS_TEST_REAL=1` — run live Weakpass CLI menu test
|
||||
- `HATE_CRACK_REQUIRE_DEPS=1` — fail if required system tools are missing
|
||||
- `HATE_CRACK_RUN_LIVE_TESTS=1` — run live Hashview upload tests (requires config.json credentials)
|
||||
- `HATE_CRACK_RUN_LIVE_HASHVIEW_TESTS=1` — run live Hashview wordlist upload tests
|
||||
- `HATE_CRACK_RUN_E2E=1` — run end-to-end local installation tests
|
||||
- `HATE_CRACK_RUN_DOCKER_TESTS=1` — run Docker-based end-to-end tests
|
||||
- `HATE_CRACK_RUN_LIMA_TESTS=1` — run Lima VM-based end-to-end tests (requires Lima installed)
|
||||
|
||||
When `HASHMOB_TEST_REAL` is enabled, tests will still skip if Hashmob returns errors like HTTP 523 (origin unreachable).
|
||||
|
||||
## Test Results
|
||||
|
||||
✅ 94 tests passing (as of current version, 15 typically skipped)
|
||||
⚡ Tests run in ~50 seconds on a typical dev machine
|
||||
|
||||
### Test Coverage
|
||||
|
||||
Highlights:
|
||||
1. Hashview API workflows (list customers, upload hashfile, create jobs, download left hashes)
|
||||
2. API download functionality (mocked downloads, 7z extraction, progress bars)
|
||||
3. CLI menu flags (--hashview, --weakpass, --hashmob)
|
||||
4. Dependency checks (7z, transmission-cli)
|
||||
5. Hashmob connectivity (mocked by default, opt-in live tests)
|
||||
6. Pipal integration and analysis
|
||||
7. UI menu options (all attack modes)
|
||||
8. Hashcat-utils submodule verification
|
||||
9. Docker and E2E installation tests (opt-in)
|
||||
10. Lima VM installation tests (opt-in)
|
||||
|
||||
## Benefits
|
||||
|
||||
1. **No Dependencies**: Tests run without needing a Hashview server or API credentials
|
||||
2. **Fast Execution**: Mocked tests complete in milliseconds
|
||||
3. **Reliable**: Tests won't fail due to network issues or server downtime
|
||||
4. **CI/CD Ready**: Can run in GitHub Actions and other CI environments
|
||||
5. **Portable**: Tests work anywhere Python is installed
|
||||
|
||||
## Running Tests
|
||||
|
||||
```bash
|
||||
# Run all tests
|
||||
uv run pytest -v
|
||||
|
||||
# Or via Makefile
|
||||
# Run all tests (auto-sets HATE_CRACK_SKIP_INIT when needed)
|
||||
make test
|
||||
|
||||
# Run tests with coverage
|
||||
uv run pytest --cov=hate_crack --cov-report=term-missing
|
||||
|
||||
# Or via Makefile
|
||||
# With coverage
|
||||
make coverage
|
||||
```
|
||||
|
||||
# Run specific test
|
||||
uv run pytest tests/test_hashview.py -v
|
||||
## Environment Variables
|
||||
|
||||
# Run a specific test method
|
||||
| Variable | Purpose |
|
||||
|----------|---------|
|
||||
| `HATE_CRACK_SKIP_INIT=1` | Skip binary/config validation at startup. Required in worktrees and CI where submodules are not built. `make test` sets this automatically. |
|
||||
| `HASHMOB_TEST_REAL=1` | Enable live Hashmob connectivity tests |
|
||||
| `HASHVIEW_TEST_REAL=1` | Enable live Hashview CLI menu tests |
|
||||
| `WEAKPASS_TEST_REAL=1` | Enable live Weakpass CLI menu tests |
|
||||
| `HATE_CRACK_REQUIRE_DEPS=1` | Fail if `7z` or `transmission-cli` are missing |
|
||||
| `HATE_CRACK_RUN_LIVE_TESTS=1` | Enable live Hashview upload test (requires valid credentials in `config.json`) |
|
||||
| `HATE_CRACK_RUN_LIVE_HASHVIEW_TESTS=1` | Enable live Hashview wordlist upload test |
|
||||
| `HATE_CRACK_RUN_E2E=1` | Enable local uv tool install E2E test |
|
||||
| `HATE_CRACK_RUN_DOCKER_TESTS=1` | Enable Docker-based E2E test |
|
||||
| `HATE_CRACK_RUN_LIMA_TESTS=1` | Enable Lima VM E2E test (macOS, requires `limactl`) |
|
||||
|
||||
## Running Tests Directly
|
||||
|
||||
```bash
|
||||
# All tests
|
||||
uv run pytest -v
|
||||
|
||||
# Single file
|
||||
HATE_CRACK_SKIP_INIT=1 uv run pytest tests/test_attacks_behavior.py -v
|
||||
|
||||
# Specific test
|
||||
uv run pytest tests/test_hashview.py::TestHashviewAPI::test_create_job_workflow -v
|
||||
|
||||
# Run live Hashmob checks
|
||||
# With coverage
|
||||
uv run pytest --cov=hate_crack --cov-report=term-missing
|
||||
```
|
||||
|
||||
## Test Files
|
||||
|
||||
### Unit / Offline Tests (always run)
|
||||
|
||||
No external services, binaries, or network access required.
|
||||
|
||||
| File | What it covers |
|
||||
|------|---------------|
|
||||
| `test_attacks_behavior.py` | Attack handler logic via mocked `ctx` |
|
||||
| `test_hashcat_wrappers.py` | Low-level hashcat subprocess wrappers |
|
||||
| `test_api.py` | Hashview, Weakpass, Hashmob API clients (mocked HTTP) |
|
||||
| `test_api_downloads.py` | Download helpers and file extraction |
|
||||
| `test_cli_menus.py` | CLI argument parsing and menu dispatch |
|
||||
| `test_cli_weakpass.py` | Weakpass CLI subcommands |
|
||||
| `test_hashview.py` | HashviewAPI class (mocked responses) |
|
||||
| `test_hashview_cli_subcommands.py` | Hashview CLI subcommand routing |
|
||||
| `test_hashview_cli_subcommands_subprocess.py` | Hashview subcommands via subprocess |
|
||||
| `test_ui_menu_options.py` | Menu option snapshot tests via `CLI_MODULE` |
|
||||
| `test_proxy.py` | `hate_crack.py` proxy to `hate_crack.main` |
|
||||
| `test_main_utils.py` | Utility functions in `main.py` |
|
||||
| `test_utils.py` | Shared utility helpers |
|
||||
| `test_ntlm_preprocessing.py` | NTLM hash preprocessing |
|
||||
| `test_ntlm_preprocessing_edge_cases.py` | Edge cases for NTLM preprocessing |
|
||||
| `test_fingerprint_expander_and_hybrid.py` | Fingerprint and hybrid attack helpers |
|
||||
| `test_hashcat_rules.py` | Hashcat rule parsing and analysis |
|
||||
| `test_asset_path_separation.py` | `hate_path` vs `hcatPath` path distinction |
|
||||
| `test_invalid_hcatpath.py` | Startup error on invalid hashcat path |
|
||||
| `test_version_check.py` | Update check logic |
|
||||
| `test_omen_attack.py` | OMEN attack handler |
|
||||
| `test_passgpt_attack.py` | PassGPT attack handler |
|
||||
| `test_pipal.py` | Pipal integration helpers |
|
||||
| `test_pipal_integration.py` | Pipal menu and output parsing |
|
||||
| `test_dependencies.py` | External dependency detection |
|
||||
| `test_hashmob_connectivity.py` | Hashmob connectivity check (mocked by default) |
|
||||
|
||||
### Opt-In Tests
|
||||
|
||||
#### Live API
|
||||
|
||||
```bash
|
||||
HASHMOB_TEST_REAL=1 uv run pytest tests/test_hashmob_connectivity.py -v
|
||||
HASHVIEW_TEST_REAL=1 uv run pytest tests/test_cli_menus.py -v
|
||||
WEAKPASS_TEST_REAL=1 uv run pytest tests/test_cli_weakpass.py -v
|
||||
```
|
||||
|
||||
# Require system deps (7z, transmission-cli)
|
||||
HATE_CRACK_REQUIRE_DEPS=1 uv run pytest tests/test_dependencies.py -v
|
||||
#### Live Hashview Upload
|
||||
|
||||
# Run end-to-end tests
|
||||
Requires valid `hashview_url` and `hashview_api_key` in `config.json`.
|
||||
|
||||
```bash
|
||||
HATE_CRACK_RUN_LIVE_TESTS=1 uv run pytest tests/test_upload_cracked_hashes.py -v
|
||||
HATE_CRACK_RUN_LIVE_HASHVIEW_TESTS=1 uv run pytest tests/test_upload_wordlist.py -v
|
||||
```
|
||||
|
||||
#### Submodules
|
||||
|
||||
Requires built submodules (`make` first).
|
||||
|
||||
```bash
|
||||
uv run pytest tests/test_submodule_hashcat_utils.py -v
|
||||
```
|
||||
|
||||
#### End-to-End
|
||||
|
||||
```bash
|
||||
# Local uv tool install (creates a temporary HOME)
|
||||
HATE_CRACK_RUN_E2E=1 uv run pytest tests/test_e2e_local_install.py -v
|
||||
|
||||
# Run Docker tests
|
||||
# Docker-based full install and basic hashcat crack
|
||||
HATE_CRACK_RUN_DOCKER_TESTS=1 uv run pytest tests/test_docker_script_install.py -v
|
||||
|
||||
# Run Lima VM tests
|
||||
# Prerequisite: brew install lima
|
||||
# Lima VM install (macOS only, requires: brew install lima)
|
||||
HATE_CRACK_RUN_LIMA_TESTS=1 uv run pytest tests/test_lima_vm_install.py -v
|
||||
|
||||
# Installed tool smoke test
|
||||
uv run pytest tests/test_installed_tool_execution.py -v
|
||||
uv run pytest tests/test_uv_tool_install_dryrun.py -v
|
||||
```
|
||||
|
||||
## Lima VM Tests
|
||||
The Lima test provisions a real Ubuntu 24.04 VM via [Lima](https://lima-vm.io/). The first run is slow (VM provisioning + apt-get). The VM is named uniquely per session and deleted in teardown - verify cleanup with `limactl list`.
|
||||
|
||||
`tests/test_lima_vm_install.py` runs hate_crack inside a real Ubuntu 24.04 VM via [Lima](https://lima-vm.io/). Unlike the Docker tests, this exercises a real kernel and full Ubuntu userspace, giving higher confidence that installation works on the distros users actually run.
|
||||
## Test Architecture
|
||||
|
||||
**Prerequisites:**
|
||||
- **`conftest.py`** - Provides the `hc_module` fixture via `load_hate_crack_module()`, which dynamically imports `hate_crack.py` with `HATE_CRACK_SKIP_INIT=1`. Each test gets an isolated module instance.
|
||||
- **`CLI_MODULE`** - Menu option tests patch against this reference to exercise the proxy layer between `hate_crack.py` and `hate_crack.main`.
|
||||
- **HTTP mocking** - API tests mock `requests` at the boundary. No real network calls in offline tests.
|
||||
- **Subprocess mocking** - Hashcat wrapper tests mock `subprocess.Popen`; no hashcat binary required.
|
||||
|
||||
## CI
|
||||
|
||||
GitHub Actions runs the offline test suite against Python 3.9-3.14 on every push and pull request. Opt-in tests are not run in CI.
|
||||
|
||||
Pre-push hooks (via [prek](https://github.com/j178/prek)) run `ruff`, `ty`, and `pytest` locally before each push:
|
||||
|
||||
```bash
|
||||
brew install lima
|
||||
# Install hooks
|
||||
prek install --hook-type pre-push --hook-type post-commit
|
||||
|
||||
# Run manually
|
||||
prek run
|
||||
```
|
||||
|
||||
**Run:**
|
||||
|
||||
```bash
|
||||
HATE_CRACK_RUN_LIMA_TESTS=1 uv run pytest tests/test_lima_vm_install.py -v
|
||||
```
|
||||
|
||||
**Note:** The first run takes several minutes - the VM provision script runs `apt-get install` for hashcat and all build dependencies. Subsequent runs on the same machine are faster if Lima caches the base image.
|
||||
|
||||
The VM is created with a unique name per test session and deleted automatically in teardown. To verify cleanup: `limactl list`.
|
||||
|
||||
## Note on Real API Testing
|
||||
|
||||
While these mocked tests validate the code logic, you may still want to occasionally run integration tests against a real Hashview instance to ensure the API hasn't changed. The test files can be easily modified to toggle between mocked and real API calls if needed.
|
||||
|
||||
Reference in New Issue
Block a user