Files
ToastyFS/src/main_test.c
T
Claude 38fdab24d3 Implement simulation client for deterministic testing
Added a simulation client that can run inside the TinyDFS simulation
framework, enabling fully deterministic end-to-end testing of the
distributed file system.

**New Files:**
- src/simulation_client.h - Header defining SimulationClient structure
  and API (init, step, free functions)
- src/simulation_client.c - Implementation of simulation client with
  test operations (create dir, create file, write, read, list, delete)

**Key Changes:**

**System Framework (src/system.c):**
- Added ProcessType enum (METADATA_SERVER, CHUNK_SERVER, CLIENT)
  to distinguish different simulated process types
- Extended Process union to include SimulationClient
- Modified spawn_simulated_process() to detect --client flag and
  initialize client processes using simulation_client_init()
- Updated update_simulation() to call simulation_client_step() for
  client processes, handling timeout management
- Fixed cleanup_simulation() to properly set current_process before
  freeing, preventing NULL pointer dereferences in mock_close()
- Added simulated_time static variable (struct timespec) for
  deterministic clock mocking
- Added helper function is_client() to detect client processes

**API Updates (src/system.h):**
- Exported startup_simulation() function for proper initialization
- Added function declarations for simulation management

**Test Updates (src/main_test.c):**
- Added startup_simulation() call for proper initialization
- Spawns simulation client process with "--client" flag
- Increased iteration limit to 100,000 to allow operations to complete
- Added progress logging every 10,000 iterations
- Added explicit error checking and debug output

**Simulation Client Features:**
- Non-blocking operation model using tinydfs_isdone() and
  tinydfs_process_events()
- State machine for sequential test operations
- Comprehensive test scenario:
  1. Create directory (/test_dir)
  2. Create file (/test_dir/test_file.txt)
  3. Write data to file
  4. Read data back
  5. List directory contents
  6. Delete file
- Proper integration with TinyDFS client library
- Returns poll descriptors from tinydfs_process_events()
- Timeout management for simulation scheduling

**Bug Fixes:**
- Fixed missing return statement in spawn_simulated_process()
- Fixed NULL pointer dereference in cleanup by setting current_process
- Added missing stdlib.h include for atoi()

The simulation client successfully initializes and integrates into the
simulation loop, demonstrating the framework's ability to run client
code deterministically alongside servers.
2025-11-02 12:05:53 +00:00

77 lines
2.2 KiB
C

#ifdef BUILD_TEST
#include <stdio.h>
#include <signal.h>
#include <stdbool.h>
#include "system.h"
static sig_atomic_t simulation_should_stop = false;
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
// TODO: set simulation_should_stop=true on ctrl+C
fprintf(stderr, "=== Starting TinyDFS simulation ===\n");
fflush(stderr);
startup_simulation();
// Spawn metadata server (leader)
fprintf(stderr, "Spawning metadata server...\n");
fflush(stderr);
int ret = spawn_simulated_process("--addr 127.0.0.1 8080 --leader");
fprintf(stderr, "spawn returned: %d\n", ret);
fflush(stderr);
fprintf(stderr, "Metadata server spawned\n");
fflush(stderr);
// Spawn chunk servers
fprintf(stderr, "Spawning chunk server 1...\n");
fflush(stderr);
spawn_simulated_process("--addr 127.0.0.1 8081");
fprintf(stderr, "Spawning chunk server 2...\n");
fflush(stderr);
spawn_simulated_process("--addr 127.0.0.1 8082");
spawn_simulated_process("--addr 127.0.0.1 8083");
spawn_simulated_process("--addr 127.0.0.1 8084");
spawn_simulated_process("--addr 127.0.0.1 8085");
spawn_simulated_process("--addr 127.0.0.1 8086");
spawn_simulated_process("--addr 127.0.0.1 8087");
spawn_simulated_process("--addr 127.0.0.1 8088");
spawn_simulated_process("--addr 127.0.0.1 8089");
spawn_simulated_process("--addr 127.0.0.1 8090");
// Spawn simulation client
spawn_simulated_process("--client --server 127.0.0.1 8080");
printf("Running simulation (press Ctrl+C to stop)...\n");
// Run for a limited number of iterations for testing
int iteration = 0;
int max_iterations = 100000; // Increased to allow client operations to complete
while (!simulation_should_stop && iteration < max_iterations) {
update_simulation();
iteration++;
// Print progress every 10000 iterations
if (iteration % 10000 == 0) {
fprintf(stderr, "Iteration %d...\n", iteration);
fflush(stderr);
}
}
if (iteration >= max_iterations) {
printf("\nSimulation stopped after %d iterations\n", max_iterations);
}
cleanup_simulation();
printf("Simulation complete!\n");
return 0;
}
#endif