Commit Graph

116 Commits

Author SHA1 Message Date
TapTap c55d89c40f fix: sendfile path now conditionally sends metadata 2026-07-05 20:52:18 +02:00
TapTap 1d90d3230e fix: make file_send_single_calls metadata conditional, add missing stdbool.h 2026-07-05 20:49:57 +02:00
TapTap 12ae8c7f7a test: add Standard (no metadata) case to test.py 2026-07-05 20:47:32 +02:00
TapTap 5fa0dc11e1 fix: address PR review comments
- Rename receive_file_receive -> file_receive (comment 62)
- Guard metadata receive with config->use_metadata in server.c (comment 63)
- Add NULL check after malloc in file_load_data (comment 66)
- Make chunk_serialize/chunk_deserialize metadata conditional on use_metadata param,
  thread through chunk_compress/chunk_decompress (comment 65)
- Add missing stdbool.h include to chunk.h
2026-07-05 20:45:34 +02:00
TapTap 660834d453 Merge branch 'main' into metadata-transfer, resolve conflicts
Conflicts resolved:
- config_create signature: added both use_metadata and use_sendfile params
- config_send/config_receive: wire protocol includes both use_metadata and use_sendfile
- client.c: config_create call updated, arg parsing includes both -M/--preserve and -f/--sendfile
- test_config.c: all three config_create calls updated
- file_send_sendfile: use file->data->size instead of removed struct stat
2026-07-05 20:29:04 +02:00
TapTap 1f75522d21 Merge pull request 'bench: add speedup metrics vs rsync and theoretical uncompressed throughput' (#11) from benchmark-metrics into main
Reviewed-on: #11
2026-07-05 20:26:18 +02:00
TapTap d4fdc16c9e bench: enable -M (metadata) in benchmark for fair rsync comparison 2026-07-05 20:23:31 +02:00
TapTap 1444eb0f59 Merge pull request 'Update opencode.json' (#12) from update-opencode.json into main
Reviewed-on: #12
2026-07-05 20:23:20 +02:00
TapTap 11b1765719 Update opencode.json 2026-07-05 20:23:04 +02:00
TapTap 4a1e666365 refactor: merge File/FileReceive, add optional metadata transfer with -M flag
- Remove FileReceive struct; use File everywhere with nullable FileMetadata*
- Remove struct stat from File; file size lives in Data->size (data_create_reserve)
- Add FileMetadata struct (mode, uid, gid, mtime) sent conditionally over wire
- Add -M / --preserve flag to client
- Restore permissions, ownership, timestamps on disk write
- Wire format uses per-file present flag for metadata (zero overhead when off)
2026-07-05 20:21:46 +02:00
TapTap b99b733025 bench: add speedup metrics vs rsync and theoretical uncompressed throughput 2026-07-05 19:57:53 +02:00
TapTap a1189e51eb Merge pull request 'bench: run rsync over localhost network for fair comparison' (#10) from networked-rsync into main
Reviewed-on: #10
2026-07-05 19:50:41 +02:00
TapTap 7d528b1b4d test: use temp dir for rsync error retry 2026-07-05 19:06:25 +02:00
TapTap 251d2a3407 test: simplify rsync daemon startup, capture stderr 2026-07-05 19:06:12 +02:00
TapTap 266c1e37c7 test: skip systemd-run boilerplate in rsync errors, add raw retry 2026-07-05 18:57:37 +02:00
TapTap b680a8dff4 test: fix indentation in rsync error handling 2026-07-05 18:46:45 +02:00
TapTap 895927fbad test: include stdout in rsync error output 2026-07-05 18:44:36 +02:00
TapTap 6a609c1b07 test: add text=True to rsync subprocess.run
Without text=True, stderr is bytes, and bytes.split('\n') throws
TypeError: a bytes-like object is required, not 'str'.
2026-07-05 18:42:35 +02:00
TapTap 1c26a7a712 test: robust netem setup and rsync daemon startup
- netem_apply now calls netem_reset() first to clear any leftover qdisc
- Rsync daemon startup polls TCP port instead of fixed sleep
- Dest dir cleared at start of run
2026-07-05 18:33:04 +02:00
TapTap 0c2364bd62 test: clear dest dir at start of run 2026-07-05 18:11:23 +02:00
TapTap 5170155112 bench: run rsync over localhost network for fair comparison
Previously rsync ran as a direct local copy (rsync -aH source/ dest/), bypassing the
loopback interface entirely. This meant tc netem latency/loss/rate limits were never
applied to rsync, making the comparison fundamentally unfair.

Now rsync goes through the network via an rsync daemon on localhost:
  rsync --daemon --no-detach --config=rsyncd.conf
  rsync rsync://localhost:PORT/source/ dest/

The daemon is started before rsync tests and killed afterward. Both the rsync client
and FastSync client run under the same systemd-run disk I/O limits when applicable.
2026-07-05 16:58:13 +02:00
TapTap f77e6bd16a Merge pull request 'bench: network profiles (LAN/WAN), jitter, packet loss, rsync comparison' (#9) from improved-benchmark into main
Reviewed-on: #9
2026-07-05 16:52:26 +02:00
TapTap 7a1c491f7f bench: default is LAN-only, --unlimited and --wan for exclusive profiles 2026-07-05 16:51:11 +02:00
TapTap a90e510424 bench: --wan runs only WAN, not also Unlimited 2026-07-05 16:48:45 +02:00
TapTap 39faff1c4c bench: LAN 20ms ±1ms, 0.1% loss 2026-07-05 16:47:35 +02:00
TapTap 89274c0fe2 bench: network profiles (LAN/WAN), jitter, packet loss, rsync comparison
- Replace single 'Throttled' suite with profiles: Unlimited, LAN (default),
  WAN (--wan flag)
- LAN: 1000mbit, 1ms ±0.1ms delay, 0% loss
- WAN: 100mbit, 50ms ±10ms delay, 1% loss (with --wan)
- Add jitter and packet loss to tc netem config
- Add rsync -aH (archive) and rsync -aHz (archive+compress) as comparison
- Fix verify_transfer to take the received directory directly
- --no-unlimited, --no-lan to skip profiles
- 36 tests total (10 FastSync + 2 rsync across 3 profiles)
2026-07-05 16:45:08 +02:00
TapTap 433a6952e5 Merge pull request 'feat: add -f/--sendfile for zero-copy file transfer' (#8) from sendfile-support into main
Reviewed-on: #8
2026-07-05 16:39:19 +02:00
TapTap a48b3e3a17 refactor: pass use_sendfile to config_create 2026-07-05 16:38:13 +02:00
TapTap d0c57ba2bb docs: update README with sendfile details and examples 2026-07-05 16:33:21 +02:00
TapTap 2fb7203c82 feat: sendfile works with -m, error on -f + -c/-s
- load_files_multithreaded skips file_load_data when sendfile is active
- -f + -m works: sendfile bypasses loader, sender uses sendfile directly
- -f combined with -c or -s prints error and exits with rc=1
- Add Sendfile + Multithreading test case
2026-07-05 16:31:08 +02:00
TapTap 01045d7d14 feat: add -f/--sendfile for zero-copy file transfer
- Add file_send_sendfile() using sendfile() syscall to send file
  content directly from fd to socket, bypassing userspace memory
- Add use_sendfile field to Config struct (default false)
- Add -f / --sendfile flag parsing in client.c
- sendfile path in send_chunk() used when -f is set without -c or -s
- send_files_multithreaded() falls back to single-threaded when
  sendfile is enabled (loader pipeline becomes unnecessary)
- Add Sendfile (-f) test case to test.py
2026-07-05 16:25:20 +02:00
TapTap e7c23c135b docs: update README with --source-dir/--dest-dir/--save-to-disk and test.py 2026-07-04 22:58:53 +02:00
TapTap 1c5099b963 Merge pull request 'test: auto-generate test files, verify content, CLI args, test_data dir' (#7) from improve-test-py into main
Reviewed-on: #7
2026-07-04 22:56:58 +02:00
TapTap 7cacce24e3 test: remove explicit compression level 0 from test case 2026-07-04 22:51:34 +02:00
TapTap 88a4d91c2e chore: ignore __pycache__ 2026-07-04 22:51:34 +02:00
TapTap f65cd02627 refactor: --source-dir, --dest-dir, --save-to-disk as CLI args
- Replace env var control (FASTSYNC_SOURCE_DIR, FASTSYNC_DEST_DIR,
  FASTSYNC_SAVE_TO_DISK) with explicit --source-dir, --dest-dir,
  --save-to-disk CLI arguments
- Keep env vars as fallback for backward compatibility
- Fix test.py: split '-c 0' into separate args ['-c', '0']
- Fix test.py: throttled suite failed because systemd-run didn't
  inherit env vars; now all settings are passed as CLI args
- Add env_name to exception/timeout result entries for correct display
2026-07-04 22:51:34 +02:00
TapTap b9d1a8c281 chore: ignore test_data/ directory 2026-07-04 22:51:31 +02:00
TapTap 4867e04677 fix: scanner mid-directory resume bug, -c -s protocol fix, 50 MB test data
- Fix scanner: when chunk fills up mid-directory, save DIR handle so
  remaining files in that directory are not skipped (pre-existing bug)
- Fix -c -s: add STATUS_CHUNK to protocol, send it before chunk data,
  handle it on the server side for both single and multithreaded paths
- Extract chunk_serialize/chunk_deserialize from chunk_compress/decompress
- Remove dead declarations (file_receive_from_buffer, etc.)
- Fix memory leak in receive_file_receive (free -> data_destroy)
- test.py generates ~50 MB of test data across bulk files
- All 8 integration tests + 7 unit tests pass
2026-07-04 22:51:31 +02:00
TapTap 7f6fa968ee test: auto-generate test files, verify content, CLI args, test_data dir
- test.py generates its own test files in test_data/ (small.txt, medium.txt,
  binary.bin, nested subtree)
- source and dest directories configurable via --source-dir / --dest-dir
- verifies all transferred files match originals byte-for-byte after each test
- waits for server to finish before verification (fixes race in multithreaded)
- all test data lives under test_data/ and is cleaned up unless --keep-data
2026-07-04 22:51:27 +02:00
TapTap 42870ec719 Merge pull request 'docs: update README with STATUS_CHUNK protocol and -s flag details' (#6) from update-readme into main
Reviewed-on: #6
2026-07-04 21:51:05 +02:00
TapTap 3146cd7cde docs: update README with STATUS_CHUNK protocol and -s flag details 2026-07-04 21:50:45 +02:00
TapTap b8186d4b52 Merge pull request 'feat: implement chunk serialization protocol with -s flag' (#5) from chunk-serialization into main
Reviewed-on: #5
2026-07-04 21:49:55 +02:00
TapTap 1d1f93f800 bench: add chunk serialization combos (-s, -c -s, -m -s, -m -c -s) to test.py 2026-07-04 21:47:49 +02:00
TapTap c4aeed9f4d feat: implement chunk serialization protocol with -s flag
- Extract chunk_serialize/chunk_deserialize from chunk_compress/chunk_decompress
- Add STATUS_CHUNK to wire protocol for chunk-mode transfers
- Client: -s sends chunk via STATUS_CHUNK (serialized or compressed+serialized)
- Server: handle STATUS_CHUNK in both single-threaded and multithreaded paths
- Fix memory leak in receive_file_receive (free->data_destroy)
- Remove dead declarations: file_receive_from_buffer, file_receive_decompress,
  file_compress, chunk_data_to_disk, unused #defines
2026-07-04 21:38:46 +02:00
TapTap e0f64e8d43 Merge pull request 'Add compression round-trip and scanner tests; fix 2 bugs found along the way' (#4) from add-tests into main
Reviewed-on: #4
2026-07-04 21:29:29 +02:00
TapTap 43c0a1395d Add compression and scanner tests; fix chunk_decompress data ownership bug, data_destroy NULL safety, chunk_compress memory leak 2026-07-04 21:25:34 +02:00
TapTap 38019e7e32 Merge pull request 'Fix config protocol mismatch and format string bugs' (#3) from fix-proto-and-format into main
Reviewed-on: #3
2026-07-04 21:12:10 +02:00
TapTap f189adcbff fix: config_send proto mismatch (use_compression→compression_level) and format string %d→%zu for size_t 2026-07-04 21:11:34 +02:00
TapTap a242a6c031 Merge pull request 'Fix critical issues and all tests' (#2) from fix-critical-issues into main
Reviewed-on: #2
2026-07-04 21:09:21 +02:00
TapTap fe8fca47b4 fix: re-apply socket.c file descriptor check after merge 2026-07-04 21:08:30 +02:00