Parse rsync --stats output into structured run metrics for file counts, transferred bytes, literal data, matched data, speedup, and estimated link-dest savings. Store collected stats on backup run results and successful snapshot metadata, including snapshot data usage and backup-root capacity details for future dashboard graphs and disk-full projections. Render the collected metrics on run and snapshot detail pages, with tests covering parsing, metadata persistence, and UI output.
61 lines
2.2 KiB
Python
61 lines
2.2 KiB
Python
from __future__ import annotations
|
|
|
|
import os
|
|
from pathlib import Path
|
|
from tempfile import TemporaryDirectory
|
|
|
|
from django.test import SimpleTestCase
|
|
|
|
from pobsync.run_stats import parse_rsync_stats, tree_usage
|
|
|
|
|
|
class RunStatsTests(SimpleTestCase):
|
|
def test_parse_rsync_stats_extracts_counts_bytes_and_savings(self) -> None:
|
|
stats = parse_rsync_stats(
|
|
"""
|
|
Number of files: 1,234 (reg: 1,200, dir: 34)
|
|
Number of created files: 12 (reg: 10, dir: 2)
|
|
Number of deleted files: 3
|
|
Number of regular files transferred: 8
|
|
Total file size: 1.50M bytes
|
|
Total transferred file size: 24.00K bytes
|
|
Literal data: 24.00K bytes
|
|
Matched data: 976.00K bytes
|
|
File list size: 8.00K
|
|
Total bytes sent: 10.00K
|
|
Total bytes received: 2.00K
|
|
sent 10.00K bytes received 2.00K bytes 1.20K bytes/sec
|
|
total size is 1.50M speedup is 125.00
|
|
"""
|
|
)
|
|
|
|
self.assertEqual(stats["files_total"], 1234)
|
|
self.assertEqual(stats["files_created"], 12)
|
|
self.assertEqual(stats["files_deleted"], 3)
|
|
self.assertEqual(stats["files_transferred"], 8)
|
|
self.assertEqual(stats["total_file_size_bytes"], 1_500_000)
|
|
self.assertEqual(stats["total_transferred_file_size_bytes"], 24_000)
|
|
self.assertEqual(stats["literal_data_bytes"], 24_000)
|
|
self.assertEqual(stats["matched_data_bytes"], 976_000)
|
|
self.assertEqual(stats["bytes_sent_received"], 12_000)
|
|
self.assertEqual(stats["bytes_per_second"], 1_200)
|
|
self.assertEqual(stats["speedup"], 125.0)
|
|
self.assertEqual(stats["link_dest_estimated_savings_bytes"], 976_000)
|
|
self.assertEqual(stats["link_dest_estimated_savings_ratio"], 0.976)
|
|
|
|
def test_tree_usage_reports_hardlinked_files(self) -> None:
|
|
with TemporaryDirectory() as tmp:
|
|
root = Path(tmp)
|
|
source = root / "source"
|
|
linked = root / "linked"
|
|
source.write_bytes(b"abc")
|
|
os.link(source, linked)
|
|
|
|
stats = tree_usage(root)
|
|
|
|
self.assertEqual(stats["files"], 2)
|
|
self.assertEqual(stats["apparent_size_bytes"], 6)
|
|
self.assertEqual(stats["hardlinked_files"], 2)
|
|
self.assertEqual(stats["hardlinked_apparent_size_bytes"], 6)
|
|
self.assertEqual(stats["hardlink_apparent_ratio"], 1.0)
|