Run CLI tests, integration tests, fuzz tests, stress tests, and benchmark Rust vs TypeScript performance — the complete test suite.
- Node.js 18+, Rust toolchain, Python 3.8+
- Solana CLI (
solana-keygen)
# Verify tools are available
which solana-keygen cargo node python3tests/
├── benchmarks/
│ ├── compare_implementations.sh # Rust vs TS vs CLI speed
│ └── scaling_test.sh # Multi-prefix scaling
├── cli/
│ ├── test_generation.sh # Key generation via CLI
│ └── test_verification.sh # Keypair verification
├── integration/
│ ├── test_keypair_validity.sh # Cryptographic correctness
│ ├── test_output_compatibility.sh # Cross-language format match
│ └── test_security_properties.sh # Security invariants
├── fuzz/
│ ├── fuzz_validation.py # Input validation edge cases
│ └── fuzz_file_operations.py # File handling edge cases
├── stress/
│ ├── rapid_generation.sh # Burst generation
│ └── long_running.sh # Endurance testing
└── fixtures/
├── README.md
└── invalid-inputs.txt # Known-bad inputs
Test that solana-keygen grind, Rust, and TypeScript all produce valid keypairs:
bash tests/cli/test_generation.shWhat it verifies:
- Keypair file is created at expected path
- JSON array has exactly 64 bytes
- Each byte is 0-255
solana-keygen pubkeycan extract the public key- Public key matches the requested prefix
# Example: manual CLI generation test
PREFIX="ab"
solana-keygen grind --starts-with "${PREFIX}:1" --no-bip39-passphrase
# Verify the output
FILE=$(ls ${PREFIX}*.json | head -1)
PUBKEY=$(solana-keygen pubkey "$FILE")
echo "$PUBKEY" | grep -q "^${PREFIX}" && echo "PASS: Prefix match" || echo "FAIL: Prefix mismatch"Verify cryptographic correctness of generated keypairs:
bash tests/integration/test_keypair_validity.sh# 1. Public key extraction
solana-keygen pubkey keypair.json
# 2. Keypair verification (solana-keygen)
solana-keygen verify <PUBKEY> keypair.json
# 3. JSON structure validation
jq 'length == 64 and all(. >= 0 and . <= 255)' keypair.json
# 4. Message signing + verification
# Signs a test message, verifies signature matches public keyVerify Rust and TypeScript generators produce identical output formats:
bash tests/integration/test_output_compatibility.shThis ensures:
- Both generators output JSON arrays of 64 integers
- Byte values are in valid range (0-255)
- Generated keypairs are loadable by
@solana/web3.jsandsolana-sdk - Public keys derived from the same secret key match across languages
Verify security invariants hold across all generators:
bash tests/integration/test_security_properties.sh| Property | Test |
|---|---|
| No duplicate keys | Generate N keys, verify all public keys are unique |
| Proper permissions | Generated files have 0600 permissions |
| No key reuse | Same prefix generates different keys each run |
| Entropy quality | Keys pass basic randomness checks |
| Clean shutdown | No key material left in temp files |
Test input validation with adversarial inputs:
python3 tests/fuzz/fuzz_validation.py# The fuzzer tests these input categories against all generators:
test_cases = [
# Invalid Base58 characters (must be rejected)
("0abc", "Zero (not in Base58)", True),
("Oabc", "Capital O (not in Base58)", True),
("Iabc", "Capital I (not in Base58)", True),
("labc", "Lowercase L (not in Base58)", True),
# Valid Base58 prefixes (must be accepted)
("Pump", "Valid prefix", False),
("abc", "Simple valid prefix", False),
# Edge cases
("a" * 44, "Max length Base58 address", True),
("a" * 100, "Impossibly long prefix", True),
# Injection attacks (all must be rejected)
("../../../etc/passwd", "Path traversal", True),
("; rm -rf /", "Shell injection", True),
("$(whoami)", "Command substitution", True),
("${PATH}", "Variable expansion", True),
("' OR 1=1 --", "SQL injection", True),
# Unicode and special characters
("中文abc", "CJK characters", True),
("αβγ", "Greek characters", True),
("\x00abc", "Null byte", True),
("\nabc", "Newline", True),
]python3 tests/fuzz/fuzz_file_operations.pyTests edge cases in file I/O:
- Writing to read-only directories
- Paths with special characters
- Symlink following
- Race conditions in file creation
Compare performance across all three implementations:
bash tests/benchmarks/compare_implementations.sh# Configuration
ITERATIONS=3
TEST_PREFIX="ab" # 2-char prefix for consistent comparison
# Tests each implementation:
# 1. solana-keygen grind (CLI)
# 2. Rust vanity generator (cargo run)
# 3. TypeScript vanity generator (npx ts-node)
# Measures:
# - Wall clock time per key
# - Average across iterations
# - Keys/second throughput| Implementation | Speed | Notes |
|---|---|---|
| Rust generator | 100K+ keys/sec | Multi-threaded (rayon) |
CLI (solana-keygen grind) |
~50K keys/sec | Multi-threaded (built-in) |
| TypeScript generator | ~1K keys/sec | Single-threaded; educational |
Test how performance changes with prefix length:
bash tests/benchmarks/scaling_test.sh# Tests prefixes of increasing length:
# "a" → ~instant
# "ab" → fast
# "abc" → seconds
# "abcd" → minutes
# Each additional character ≈ 58x harderbash tests/stress/rapid_generation.shGenerates many keys in rapid succession to test:
- Memory leaks
- File handle exhaustion
- Disk I/O bottlenecks
- Thread pool stability (Rust)
bash tests/stress/long_running.shRuns the generator continuously to detect:
- Memory growth over time
- Performance degradation
- System resource exhaustion
# Run the complete test suite
bash docs/run-all-tests.sh
# Or run categories individually:
bash tests/cli/test_generation.sh
bash tests/cli/test_verification.sh
bash tests/integration/test_keypair_validity.sh
bash tests/integration/test_output_compatibility.sh
bash tests/integration/test_security_properties.sh
python3 tests/fuzz/fuzz_validation.py
python3 tests/fuzz/fuzz_file_operations.py
bash tests/benchmarks/compare_implementations.shFollow the existing pattern:
#!/usr/bin/env bash
set -euo pipefail
PASSED=0
FAILED=0
# Helper
assert_eq() {
local expected="$1" actual="$2" label="$3"
if [[ "$expected" == "$actual" ]]; then
echo " PASS: $label"
PASSED=$((PASSED + 1))
else
echo " FAIL: $label (expected: $expected, got: $actual)"
FAILED=$((FAILED + 1))
fi
}
# Your test
echo "Testing: my feature"
RESULT=$(my-command --flag)
assert_eq "expected_output" "$RESULT" "My test case"
# Summary
echo ""
echo "Results: $PASSED passed, $FAILED failed"
[[ "$FAILED" -eq 0 ]] && exit 0 || exit 1- See Tutorial 37 for security audit tools