Testing Pincer
This document outlines the testing architecture and procedures for the Pincer RPC server.
Why Python for Testing?
Using Python (specifically unittest.IsolatedAsyncioTestCase and websockets) allows us to perform black-box integration testing. By interacting with Pincer over WebSockets exactly as a real client would, we ensure that the compiled Rust binary and its RPC interface function correctly in real-world scenarios. It also allows us to quickly validate JSON-RPC structures without the boilerplate of a compiled test harness.
Test Suite Architecture
The test suite is located in the tests/ directory and is split into two parts:
tests/test_rpc.py: Tests the WebSocket JSON-RPC server daemon.tests/test_cli.py: Tests the direct Command Line Interface (CLI) downloads.
It utilizes Python’s built-in unittest module to minimize external dependencies.
What is Tested?
The test suite covers the active features exposed by the modular src/rpc/ backend, grouped into logical blocks:
- System & Info (
test_01_get_version,test_06_misc):pin.getVersion,pin.resolveUrl,pin.resolveTorrent,pin.saveSession
- Global Options (
test_02_global_options):pin.getGlobalOption,pin.changeGlobalOption
- Task Lifecycle (
test_03_lifecycle,test_08_pause_resume_integrity):pin.addUri,pin.addTorrent,pin.addMetalink,pin.tellStatus,pin.pause,pin.unpause,pin.changeOption,pin.getOption,pin.remove,pin.removeAndFile,pin.forceRemove
- Bulk Operations & Stats (
test_04_bulk_and_stats):pin.pauseAll,pin.unpauseAll,pin.tellActive,pin.tellWaiting,pin.tellStopped,pin.getGlobalStat
- Result Management (
test_05_cleanup):pin.purgeDownloadResult,pin.removeDownloadResult
- Security & Path Traversal (
test_07_path_traversal):- Path escaping mitigation and filename sanitization verification.
CLI Tests (tests/test_cli.py)
This suite tests the direct binary execution (pincer [URL] [OPTIONS]) without starting the daemon. It covers:
- Help & Version: Output of
--helpand--version. - Direct Downloads: Downloading a file directly via CLI arguments (
--out,--split,--dir, etc.) and verifying the file is written to disk successfully.
How to Run the Tests
The easiest and recommended way to run the entire test suite is using the automated test runner script.
Note
If your goal is to validate the codebase before cutting a new release, please refer to Build & Release. The automated release script delegates its checks directly to the unified test runner discussed below.
The Automated Test Runner (scripts/run_tests.py)
Pincer includes an all-in-one test runner script at scripts/run_tests.py. This script manages the entire lifecycle of CI verification, compilation, execution, and cleanup.
What the Runner Does:
- Conflicting Process Check: Automatically scans for and terminates any pre-existing running Pincer processes to prevent port bind conflicts on
6842. - CI Verification Checks:
- Runs
cargo fmt --all -- --check(attempts to auto-format usingcargo fmtif check fails). - Runs
cargo check --all-targetsto verify code compiles. - Runs
cargo clippy --all-targets -- -D warningsto verify zero lint warnings.
- Runs
- Build Stage: Builds the debug binary (
cargo build). - Session Cleanup: Removes any stale/leftover session file from
~/.pincer/pincer.session. - CLI Tests: Runs
tests/test_cli.pyto verify direct download functionality. - Background Server: Spawns Pincer in the background, waiting for it to spin up and bind the socket.
- RPC Tests: Runs
tests/test_rpc.pyto test websocket JSON-RPC methods end-to-end. - Server Shutdown: Properly terminates the background server.
- Cleanup Prompt: Asks if you want to clean up temporary test files in
tests/temporary.
How to Run:
# Ensure dependency is installed
pip install websockets
# Run the test suite
python3 scripts/run_tests.py
Running Tests Manually
If you prefer to run CLI or RPC tests independently:
RPC Tests (tests/test_rpc.py)
The Pincer server must be running in a separate process.
-
Start the Rust backend:
cargo runThe server should log that it is listening on
ws://0.0.0.0:6842/jsonrpc. -
In a separate terminal:
python3 -m unittest tests/test_rpc.py
CLI Tests (tests/test_cli.py)
These do not require the server to be running:
python3 -m unittest tests/test_cli.py