Commit Graph
18 Commits
Author SHA1 Message Date
cozisandClaude Opus 4.6 6b4f773052 Implement file_truncate for Windows and add missing Quakey mocks
file_truncate had a stub `return -1` on Windows, causing all
chunk_store_write calls to fail (every PUT returned TRANSFER_FAILED).
Implement it using SetFilePointer + SetEndOfFile.

Add mock_SetEndOfFile and mock_GetFileAttributesA to Quakey so the
simulation can exercise the Windows code paths against the mock
filesystem. Without these, SetEndOfFile was unmocked (link error) and
GetFileAttributesA called the real Win32 API on mock paths, making
chunk_store_exists always return false.

Verified: seeds 1-100 pass with 2000s simulation time.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 13:33:18 +01:00
cozis ef1d65ad2b Major refactoring 2026-02-25 10:44:43 +01:00
Claude b0cc529773 Fix GET request returning corrupted data for multi-chunk blobs
Four bugs caused data mismatches between PUT and GET operations:

1. chunk_store_exists() used file_open (O_CREAT) to check if a chunk
   file exists, which created empty files as a side effect. Servers
   would then read from these empty files and return uninitialized
   heap memory as chunk data. Fixed by using file_exists (access())
   instead.

2. Server's process_fetch_chunk checked `ret < 0` after
   chunk_store_read, missing the EOF case (ret == 0) from empty
   files. Changed to `ret <= 0`.

3. begin_transfers() == 0 was used as a completion check in both
   STEP_FETCH_CHUNK and STEP_STORE_CHUNK, but returning 0 only means
   "no new transfers started", not "all done". With concurrent chunk
   transfers, this caused premature completion, leaving in-flight
   transfers to hit UNREACHABLE. Fixed by using
   all_chunk_transfers_completed() instead.

4. choose_store_locations_for_chunk() returned [0, 1] for ALL chunks
   regardless of index, while GET fetches chunk i from servers
   (i+j) % num_servers. This made some chunks unreachable. Fixed by
   using (chunk_idx + j) % num_servers for store locations.

Also added SO_REUSEADDR to the server listen socket so restarting
the cluster doesn't fail with "Couldn't setup TCP listener", and
added a note on mock_access about the simulation mismatch.

https://claude.ai/code/session_01JniNxxDP4NbsDXNGmGNG7H
2026-02-21 22:31:33 +00:00
cozis b64517c20e Full rewrite with VSR support 2026-02-20 16:55:29 +01:00
cozis 1d6b11bcc3 Add signal queue to Quakey 2026-01-28 20:57:33 +01:00
cozis 3bb30dcd09 Implement pipe() mock 2026-01-27 22:57:45 +01:00
cozis d4c2137eaa Add allocation failure injection 2026-01-24 12:12:48 +01:00
cozis bf989864a3 Add random connect() letencies and disk bit corruption 2026-01-24 12:09:28 +01:00
cozis 07bc952cb9 Add fault injection of disk operations 2026-01-24 11:53:38 +01:00
cozis 7306bd1203 Add fault injection for partial read/writes and random send() delays 2026-01-24 11:40:45 +01:00
cozis 18817203bf Add second client to the simulation 2026-01-24 11:23:19 +01:00
Claude 282bb9632f Improve simulation coverage by adding multiple chunk servers
Two changes to improve code coverage in deterministic simulation testing:

1. Add 3 chunk servers (was 1) to match the replication factor
   - This enables testing of chunk replication and chunk-to-chunk
     server communication code paths in chunk_server.c
   - Covers: process_chunk_server_download_*, start_download,
     download_targets_* functions

2. Fix Quakey bug where events targeting a closed descriptor caused
   assertion failures
   - Added remove_events_targeting_desc() to clean up DISCONNECT and
     DATA events when a descriptor is freed
   - Modified desc_free() to accept Sim pointer and call cleanup
   - This was exposed by running multiple chunk servers which create
     more connection activity
2026-01-23 21:25:10 +00:00
Claude 6a3987d418 Fix DFS simulation infinite loop due to time event scheduling issues
Three related issues were causing the simulation to get stuck:

1. Network events (connect, disconnect, send_data) were scheduled with
   relative times instead of absolute times, causing events to be
   scheduled in the past once simulation time exceeded 10-100ms.

2. When DATA events couldn't be fully consumed (receiver buffer full),
   they stayed at their original time, preventing time from advancing.
   Now they are rescheduled to current_time + 10ms.

3. When poll_timeout was 0, WAKEUP events were created at current_time,
   causing an infinite loop where time never advanced. Now timeout=0
   sets timedout immediately without creating an event.
2026-01-23 20:26:52 +00:00
cozis 776f8c1015 Fix scheduling issue where time didn't advance if a host was always ready 2026-01-23 18:37:26 +01:00
cozis bde2d5a1ca Replace LittleFS with MockFS 2026-01-23 17:51:59 +01:00
cozis 028f25b942 Fix signed integer overflow in time calculation 2026-01-17 01:14:51 +01:00
cozis 6ef5e1a94c Fix simulation setup 2026-01-16 19:38:36 +01:00
cozis c10493881b Add Quakey 2026-01-16 14:45:09 +01:00