Hướng dẫn Kiểm thử
Chạy kiểm thử
Cảnh báo
Chạy tất cả các bài kiểm thử đồng thời có thể gây lỗi do giới hạn về tài nguyên hệ thống. Khuyên dùng chạy theo từng file hoặc các nhóm nhỏ độc lập.
Chạy Unit Test (Kiểm thử Đơn vị)
Chạy Integration Test (Kiểm thử Tích hợp)
Chạy Scenario Test (Kiểm thử Kịch bản)
Chạy Benchmark Test (Kiểm thử Hiệu năng)
python -m pytest tests --benchmark-only -v --benchmark-save=benchmark_report
python -m pytest tests --benchmark-only -v --benchmark-histogram=benchmark_report
Chạy Tất cả Kiểm thử
for test_file in $(find tests/unit tests/integration tests/scenarios -name 'test_*.py' | sort); do
python -m pytest "$test_file" -v || break
done
Các test integration consensus, 2PC, luồng dữ liệu và recovery dùng SQLite và journal trong thư mục tạm riêng cho từng test. Chúng không yêu cầu dịch vụ PostgreSQL trong .env của ứng dụng; test live-backend chuyên biệt kiểm tra PostgreSQL.
Các cổng kiểm tra CI bắt buộc
CI cài theo uv.lock bằng uv sync --frozen --extra dev và chạy từng file test tuần tự. Job PostgreSQL 16/Redis 7.4 riêng tạo database cô lập và các role audit-manifest tách biệt, sau đó dùng --fail-on-skip cho những contract backend bắt buộc. Test backend cục bộ vẫn có thể bỏ qua khi thiếu URL dịch vụ; kiểm tra daemon IPFS cần daemon đang chạy riêng.
Cổng ty bắt buộc kiểm tra toàn bộ package hierachain/. Cấu hình bỏ qua lỗi mypy cũ không áp dụng cho cổng này. Chạy cùng phép kiểm tra ở máy cục bộ:
Benchmark throughput bền vững bằng Docker
Chạy benchmark từ source hiện tại với PostgreSQL 16, giới hạn 1 CPU, 1 GiB RAM và bật ghi journal bền vững:
Có thể đổi workload bằng BENCHMARK_EVENTS, BENCHMARK_BATCH_SIZE,
BENCHMARK_CPUS và BENCHMARK_MEMORY. Fsync journal luôn được bật.
Hãy chạy down -v trước khi cần benchmark với
database sạch; xóa phần còn lại của Compose bằng:
Bộ kiểm thử runtime chuyên biệt cho Docker
Chạy các kiểm tra xác định cho image, dependency native, replay journal và PostgreSQL adapter mà không cần khởi động cluster bốn node:
Profile này khởi động PostgreSQL 16 riêng và lưu journal append-only tại
/app/data. Fsync journal luôn được bật. Có thể đổi giới hạn container bằng
DOCKER_TEST_CPUS hoặc DOCKER_TEST_MEMORY.
Kiểm thử Áp lực (Stress Testing)
Kiểm thử Áp lực với Docker
Stress ở chế độ production cần HRC_API_KEY trong .env gốc hoặc môi trường, dùng key đã được cấp trong HRC_API_KEYS_SOURCE_FILE với quyền chains, eventsvà proofs (hoặc all). Không đưa key vào log hay báo cáo. Launcher kiểm tra có cấu hình key trước triển khai; pytest kiểm tra truy cập chain có xác thực trên từng node trước khi chạy test. Thiếu key, phản hồi 401/403/429 hoặc node không kết nối được sẽ dừng phiên test. Client HTTP và WebSocket dùng cùng key và HRC_API_KEY_NAME (mặc định X-API-Key).
Stage source của Docker xuất constraint dependency từ uv.lock; stage production cài wheel và công cụ test theo constraint đó rồi chạy pip check. Build lại image sau khi đổi lockfile.
Sau khi sửa source, build lại wheel và image. Lệnh build wheel xóa thư mục sinh tự động build/ để module đã xóa không còn sót trong cache setuptools:
bash -c 'source docker/lib/common.sh; build_wheel'
docker build --target production -t hierachain:latest -f docker/Dockerfile .
Khi cluster đã dùng image mới, chạy với --reuse để giữ deployment và volume. Lệnh stress mặc định triển khai lại và xóa volume. Kiểm tra riêng từng file trước khi chạy toàn bộ suite:
docker compose --env-file .env -f docker/docker-compose.yml --profile stress-test run --rm stress-tester python -m pytest docker/stress/test_real_network.py -v
bash docker/hierachain.sh stress docker --reuse
Fixture crypto ký event/block và cung cấp public key tin cậy. Benchmark assert kết quả xác minh thành công. Khi chỉ kiểm tra crypto cục bộ không cần preflight mạng, đặt REAL_REQUESTS=false; kết quả này không xác minh dịch vụ thật.
--duration điều khiển các test đọc TEST_DURATION; đây không phải giới hạn thời gian của toàn bộ suite. Tsunami flood đầy đủ vẫn yêu cầu 5.000 event. Pha gửi có ngân sách STRESS_TIMEOUT riêng (mặc định 120 giây), sau bước chờ node và tạo chain. Worker dừng khi hết giờ, batch còn trong hàng đợi bị hủy và request HTTP đang chạy dùng thời gian còn lại, không retry trong flood. Lần chạy chưa đủ event báo timed_out cùng unattempted_events và không đạt tiêu chí chấp nhận. Launcher hiển thị kết quả từng test, traceback lỗi ngắn và mười test chậm nhất. Live log, log đã capture trên console và stack thread theo thời gian được ẩn mặc định; log INFO vẫn được capture trong báo cáo HTML, cùng kết quả XML.
HTTP 200 từ /api/ledger/health xác nhận tiến trình còn hoạt động; /api/ledger/ready kiểm tra recovery của hệ phân cấp. Stress dùng /api/ledger/ready mà không chuyển sang liveness; bước chờ node chia sẻ timeout cho các request và không tự retry HTTP. Bước tạo chain yêu cầu đủ mọi node đã cấu hình, còn poison setup probe từng node một lần. Bootstrap hệ phân cấp thất bại sẽ đóng storage pool, journal của coordinator và các sub-chain đã khởi động. Request đồng thời với bootstrap nhận HTTP 503 ngay; lần khởi tạo thất bại chờ năm giây trước khi thử lại. Event đã ký cho phép trường sender cấp ngoài, trong khi nội dung nghiệp vụ vẫn phải qua kiểm tra thuật ngữ; API admin vẫn bắt buộc xác minh chữ ký. Khi khởi động, orderer kiểm tra liên kết block đã lưu trước khi replay journal. Lỗi Chain link BROKEN cần khôi phục từ dữ liệu tin cậy hoặc được chấp thuận rõ ràng để reset dữ liệu test có thể bỏ. Build lại image không sửa block đã lưu. Sub-chain chờ replay journal hoàn tất, không hủy backlog hợp lệ sau mười giây; lỗi processor hoặc shutdown vẫn dừng bootstrap. Rehydration của sub-chain cập nhật trạng thái cục bộ mà không ghi lùi chỉ số block hoặc cache của orderer đang hoạt động.
Block của sub-chain được hoàn tất consensus, tuân thủ khoảng thời gian tối thiểu của consensus và ký header bằng khóa tin cậy trước khi orderer lưu. Consumer xác minh và áp dụng block đã commit mà không đổi index, hash, event hay chữ ký, và không ghi lại block. Lỗi consensus hoặc storage không được tăng chỉ số block hoặc đưa block vào commit queue. Consumer và lệnh flush đồng thời lấy block theo đúng thứ tự. Test throughput consensus qua HTTP chờ tối đa 120 giây để mọi event nghiệp vụ đã nhận được commit, loại event consensus PoA trong mỗi block mới khỏi số đếm. Throughput tính cả thời gian chờ commit, nên test restart tiếp theo không nhận backlog từ test throughput đã pass. Recovery vẫn yêu cầu primary vừa restart phải ledger-ready trong 60 giây; các test này dùng chain PoA generic và không chứng minh view change của giao thức BFT.
Setup stress IPFS tạo chain generic qua ledger client dùng chung và yêu cầu thành công trên mọi node đích. Event truyền entity_id trực tiếp vào POST /api/ledger/chains/{chain_name}/events; không cần endpoint đăng ký entity riêng.
Chạy kiểm thử áp lực trong các container Docker với cấu hình gồm 4 node HieraChain (mỗi node giới hạn 1 CPU, 1GiB RAM):
-
Xây dựng cấu hình và chạy stress test với báo cáo định dạng HTML:
-
Chạy stress test trên mạng thực tế (gửi các yêu cầu HTTP thực tế tới các node):
-
Chạy không cần xuất báo cáo HTML:
-
Dừng và dọn dẹp các container:
Các báo cáo kết quả được lưu tại thư mục log/report/.
Kiểm thử Áp lực với Kubernetes
Script triển khai chung sử dụng cluster Kubernetes đã có. Với OrbStack cục bộ:
orbctl start k8s
bash docker/hierachain.sh stress k8s --duration 15
bash docker/hierachain.sh stress k8s --reuse --duration 15
Lệnh đầu build và triển khai bốn node dùng SQLite, bốn pod IPFS riêng tư,
Redis và gateway. Triển khai giữ nguyên PVC và khóa hiện có; identity K8s được
tạo riêng với identity Docker. Các workload và toàn bộ pod node/IPFS phải
ready trước khi kiểm thử. Cluster khác cần nạp image hierachain:latest hoặc
có image trong registry trước khi triển khai.
Pytest chạy trong cluster qua kubectl exec, nhắm vào DNS của cả bốn node và
kiểm tra API readiness trước khi thu thập bài test. API IPFS đã cấu hình cũng
phải truy cập được; nếu không, preflight trả lỗi. Báo cáo HTML và JUnit được chép về log/report/. Script xóa pod chạy test và trả lỗi pytest, không fallback
sang Docker. --duration điều khiển thời lượng các bài tải; toàn bộ suite còn
có bài chaos và recovery lâu hơn. Bài chỉ dành cho Docker có thể skip trên K8s;
cần xem lý do được ghi trong báo cáo.
Các manifest này dùng HRC_ENV=test, tắt xác thực và cấp NET_ADMIN cho pod
node để mô phỏng lỗi mạng. Runner chỉ có quyền trong namespace để get/delete
và exec vào bốn pod node. Chỉ dùng cho kiểm thử cô lập. setup k8s --force và
down k8s xóa namespace cùng PVC; setup k8s mặc định giữ dữ liệu.
Các Kịch bản Hỗ trợ Developer (Developer Scripts)
Thư mục scripts/ chứa các công cụ tiện ích hỗ trợ nhà phát triển.
Phân tích Tĩnh (Static Analysis)
# Run default
python -m scripts.static_analysis
# Export results to file
python -m scripts.static_analysis --output analysis_report.json
Rà quét & Kiểm tra Bảo mật (Security Auditing)
Rà quét mã nguồn và các thư viện phụ thuộc bằng các công cụ chuyên dụng:
-
Bandit (Phân tích bảo mật mã nguồn tĩnh SAST cho Python):
-
pip-audit (Rà quét lỗ hổng CVE trong các thư viện phụ thuộc):
-
Cổng Bandit trong CI (phát hiện mức High làm job thất bại):
Job Bandit trong CI còn lưu báo cáo JSON đầy đủ, gồm cả các phát hiện mức Medium và Low. Workflow CodeQL hiện có bổ sung phân tích bảo mật Python. Bandit thay dependency Semgrep cục bộ; bộ quy tắc của hai công cụ không có độ bao phủ giống nhau. Cần đối chiếu mã nguồn trước khi coi một phát hiện là lỗ hổng đã xác nhận.
Kiểm thử Hiệu năng (Benchmarking)
-
Hiệu năng Băm (So sánh băm cây Merkle vs băm JSON):
-
Đo lường Băng thông (Đo tốc độ xử lý sự kiện):
Xác minh Lưu trữ (Storage Verification)
-
Xác minh tính Bền vững Lưu trữ (Kiểm tra độ bền lưu trữ cục bộ):
Cấu hình Pytest (trích xuất từ pyproject.toml)
testpaths = ["tests/unit", "tests/integration", "tests/scenarios"]python_files = "test_*.py"python_classes = "Test*"python_functions = "test_*"-
Các Marker:
critical,high,medium,lowintegration,recovery,stress
Ví dụ chạy kiểm thử theo Marker
python -m pytest tests/integration/test_data_flow.py -v -m critical
python -m pytest tests/integration/test_data_flow.py -v -m integration
Các Nguyên tắc Kiểm thử
- Tập trung vào hành vi API công khai của từng mô-đun.
- Kiểm thử tất cả các trường hợp biên (edge cases) và kịch bản lỗi.
- Đảm bảo các bài kiểm thử độc lập và có thể chạy theo marker.
Định hướng Phân bổ Kiểm thử
- Unit: kiểm thử các lớp/hàm độc lập (core, security, storage...).
- Integration: kiểm thử các luồng hoàn chỉnh đầu-cuối qua API Ledger/business.
- Scenarios: các kịch bản nghiệp vụ thực tế (ví dụ: tạo sub-chain → ghi sự kiện → gửi proof → truy vết thực thể).