[--execute]`: dry run по умолчанию, local ↔ S3 и S3 ↔ S3 без удаления source. - Последовательное копирование с проверкой размера и полным SHA-256 readback destination; конфликтующий объект не перезаписывается. Временный диск — максимум один переносимый файл дополнительно к постоянному destination. - Durable migration journal позволяет продолжить прерванную операцию с теми же конфигурациями. Незавершённый или повреждённый journal блокирует startup; backend identity меняется только после проверки всех файлов. - Native `uploads`/`upload_stats`, slots и JWT сохраняются; поддерживаются native локальные файлы без Rust completion sidecar. Миграция требует остановки RustXMPP и Prosody, использующих общий `data_path`. - Multipart intent сохраняется до создания удалённого upload. Recovery находит потерянный UploadId через paginated listing и очищает только точный key принадлежащего slot. При сохранных metadata cleanup не зависит от lifecycle; lifecycle остаётся дополнительной защитой, а не гарантией. - Перед completion сохраняется durable marker. Неопределённый результат completion при отсутствии подтверждённого объекта помещает только этот slot в quarantine: PUT 409, retention не удаляет его, maintenance повторяет сверку. Startup продолжается; сохраняется single-use семантика. - Добавлены network regressions миграции и расширены проверки multipart recovery, потерянных ответов, отмены запросов и конфликтов destination. Настройка, команды миграции, recovery и ограничения отката: [docs/HTTP-UPLOAD.md](docs/HTTP-UPLOAD.md). Команды, результаты и границы подтверждения, включая qualification реального object store и 10 GiB: [docs/VALIDATION-0.7.9.md](docs/VALIDATION-0.7.9.md). Итог: 265 тестов, нагрузка 500 TLS клиентов и native reference — успешно. Реальные 10 GiB через MinIO (описанный test adapter), 1280parts и полный SHA-256 пройдены; подробности — [VALIDATION-0.7.9](docs/VALIDATION-0.7.9.md).
127 lines
4.0 KiB
JSON
127 lines
4.0 KiB
JSON
{
|
|
"version": "0.7.8",
|
|
"date_utc": "2026-10-20",
|
|
"ordinary_tests": {
|
|
"passed": 262,
|
|
"failed": 0,
|
|
"ignored": 11
|
|
},
|
|
"fmt": "passed",
|
|
"clippy": "passed",
|
|
"release": "passed",
|
|
"native_module_tests": 8,
|
|
"native_federation_tests": 1,
|
|
"upload": {
|
|
"multi_component_network": "passed",
|
|
"independent_s3_protocol_fixture": "passed",
|
|
"large_https_local": {
|
|
"status": "passed",
|
|
"requested_bytes": 10737418240,
|
|
"python_chunk_bytes": 1048576,
|
|
"transport": "verified TLS HTTPS",
|
|
"storage": "local streaming file",
|
|
"rss_sample_interval_seconds": 0.05,
|
|
"free_disk_before_bytes": 14037065728,
|
|
"max_rss_bytes": {
|
|
"server": 18079744,
|
|
"client": 21168128
|
|
},
|
|
"rss_proc_status_paths": {
|
|
"server": "/proc/68012/status",
|
|
"client": "/proc/self/status"
|
|
},
|
|
"put_bytes": 10737418240,
|
|
"put_seconds": 14.389516601999276,
|
|
"sha256": "e4c296c41d3a9605f0348961e41ed835b5f42c220751ed2269a726951546c935",
|
|
"stored_bytes": 10737418240,
|
|
"allocated_bytes": 10737422336,
|
|
"free_disk_after_put_bytes": 2734645248,
|
|
"head_status": 200,
|
|
"get_bytes": 10737418240,
|
|
"get_read_calls": 10241,
|
|
"get_seconds": 69.22072244599985,
|
|
"get_sha256": "e4c296c41d3a9605f0348961e41ed835b5f42c220751ed2269a726951546c935",
|
|
"range_status": 206,
|
|
"range_offset": 4294967289,
|
|
"reuse_status": 409,
|
|
"over_quota_condition": "not-acceptable",
|
|
"temporary_files_cleaned": true,
|
|
"free_disk_after_cleanup_bytes": 12774170624,
|
|
"total_seconds": 84.19309745400096
|
|
},
|
|
"s3_cases": [
|
|
"independent SigV4 and session token",
|
|
"path/query escaping",
|
|
"multipart progress before input EOF",
|
|
"GET/HEAD/range/conditionals",
|
|
"init/part/completion/200-Error failures and abort/retry",
|
|
"committed object with lost completion response, live HEAD recovery",
|
|
"SIGKILL durable multipart recovery",
|
|
"old pending completed object before startup prune",
|
|
"quota, single use, expiry delete, credentials redaction, local backend isolation"
|
|
]
|
|
},
|
|
"load": {
|
|
"total_load_wall_seconds": 7.782,
|
|
"requested_resources": 500,
|
|
"authenticated_bound_resources": 500,
|
|
"connection_setup_concurrency": 50,
|
|
"setup_wall_seconds": 0.63,
|
|
"setup_latency": {
|
|
"samples": 500,
|
|
"median_ms": 57.454,
|
|
"p95_ms": 86.829,
|
|
"max_ms": 95.615
|
|
},
|
|
"ping_rounds": 10,
|
|
"ping_round_trip": {
|
|
"samples": 5000,
|
|
"median_ms": 14.241,
|
|
"p95_ms": 23.05,
|
|
"max_ms": 27.298
|
|
},
|
|
"accounts": 100,
|
|
"message_rounds": 10,
|
|
"messages_sent": 5000,
|
|
"messages_received": 5000,
|
|
"message_batch_seconds": 4.835,
|
|
"metrics_before": {
|
|
"rss_kib": 8056,
|
|
"cpu_seconds": 0.0,
|
|
"fd_count": 11
|
|
},
|
|
"metrics_connected": {
|
|
"rss_kib": 26868,
|
|
"cpu_seconds": 1.22,
|
|
"fd_count": 511
|
|
},
|
|
"metrics_after_workload": {
|
|
"rss_kib": 27456,
|
|
"cpu_seconds": 9.05,
|
|
"fd_count": 511
|
|
},
|
|
"metrics_two_seconds_after_disconnect": {
|
|
"rss_kib": 27648,
|
|
"cpu_seconds": 9.09,
|
|
"fd_count": 11
|
|
},
|
|
"sampled_peak_rss_kib": 27648,
|
|
"fd_delta_after_disconnect": 0,
|
|
"failures": [],
|
|
"scope": "One loopback host, 100 accounts with distinct resources, TLS+PLAIN, ping and directed messages; not a production benchmark or proof of no memory leaks.",
|
|
"mam": {
|
|
"archive_files": 100,
|
|
"records": 10000,
|
|
"expected_records": 10000
|
|
}
|
|
},
|
|
"release_binary_sha256": "f3226a6151122601d6a6e74ea2bcbbd24a41c29087debe223098bbf37e4126d1",
|
|
"limitations": [
|
|
"S3 tested with independent loopback protocol fixture, not AWS/MinIO deployment",
|
|
"Real 10 GiB test uses local backend; no real 10 GiB object-store upload",
|
|
"Bucket lifecycle AbortIncompleteMultipartUpload required for initiation crash window before upload ID journal",
|
|
"No automatic storage migration or arbitrary external driver",
|
|
"Production DNS, proxy, client UI and previous parity limitations unchanged"
|
|
]
|
|
}
|