From 8a1a18194279bf90f3a143f576d046bf8b849cd3 Mon Sep 17 00:00:00 2001 From: cinnaboot Date: Wed, 22 Apr 2026 11:22:11 -0400 Subject: [PATCH] refactor: clean test dump output with TestOutput struct Replace manual buffer management (malloc/free/snprintf) with a simple stack-allocated TestOutput helper. Uses dump_simulation_state's 4-param API with a single dump_state() method. Verification stays as individual INFO() calls outside the loop. --- tests/test_rendezvous.cpp | 75 +++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/tests/test_rendezvous.cpp b/tests/test_rendezvous.cpp index 9c6d862..91e31f7 100644 --- a/tests/test_rendezvous.cpp +++ b/tests/test_rendezvous.cpp @@ -27,6 +27,18 @@ static int find_spacecraft_by_name(SimulationState* sim, const char* name) { return -1; } +// ── Test-only output helper ────────────────────────────────────────────────── + +struct TestOutput { + char buf[32768]; + int offset = 0; + + void dump_state(SimulationState* sim, const char* label) { + int n = dump_simulation_state(sim, label, buf + offset, sizeof(buf) - offset); + if (n > 0) offset += n; + } +}; + TEST_CASE("Config loading for Hohmann transfer", "[rendezvous_hohmann][config]") { const double TIME_STEP = 30.0; @@ -502,55 +514,38 @@ SCENARIO("Hohmann transfer rendezvous with validation", "[rendezvous_hohmann][in int arr_idx = add_maneuver_to_simulation(sim, &arrival); REQUIRE(arr_idx >= 0); - // Dump initial state - dump_simulation_state(sim, "INITIAL STATE"); + // Compute expected step count from analytical times + const double expected_duration = wait_time + hohmann.transfer_time; + const int expected_steps = static_cast(expected_duration / sim->dt); + // Safety limit: 1 year — prevents infinite loops if calculation is wrong + const double SAFETY_LIMIT_SECONDS = 3600.0 * 24.0 * 365.0; - // Run simulation - double sim_time = 0.0; - const double DT = 1.0; - const int MAX_STEPS = 700000; + TestOutput out; bool transfer_complete = false; - for (int i = 0; i < MAX_STEPS; i++) { + for (int i = 0; i < expected_steps + 1000; i++) { update_simulation(sim); - sim_time += DT; - // Dump state at key milestones - if (i == 0) { - dump_simulation_state(sim, "T=0 (initial)"); - } - if (i == int(wait_time / DT)) { - dump_simulation_state(sim, "JUST BEFORE DEPARTURE"); - } - if (i == int(wait_time / DT) + 1) { - dump_simulation_state(sim, "AFTER DEPARTURE BURN"); - } - if (i == int(arrival_time / DT)) { - dump_simulation_state(sim, "JUST BEFORE ARRIVAL"); + if (sim->time > SAFETY_LIMIT_SECONDS) { + INFO("\n=== SAFETY LIMIT REACHED ==="); + INFO("sim->time: " << sim->time << " s (limit: " << SAFETY_LIMIT_SECONDS << " s)"); + break; } + + if (i == 0) out.dump_state(sim, "T=0 (initial)"); + if (i == static_cast(wait_time / sim->dt)) out.dump_state(sim, "JUST BEFORE DEPARTURE"); + if (i == static_cast(wait_time / sim->dt) + 1) out.dump_state(sim, "AFTER DEPARTURE BURN"); + if (i == static_cast(arrival_time / sim->dt)) out.dump_state(sim, "JUST BEFORE ARRIVAL"); if (sim->maneuvers[arr_idx].executed && !transfer_complete) { - dump_simulation_state(sim, "AFTER ARRIVAL BURN"); + out.dump_state(sim, "AFTER ARRIVAL BURN"); transfer_complete = true; break; } } - INFO("\n=== FINAL STATE ==="); - INFO("Final time: " << sim_time << " s"); - INFO("Departure executed: " << sim->maneuvers[dep_idx].executed); - INFO("Arrival executed: " << sim->maneuvers[arr_idx].executed); - dump_simulation_state(sim, "FINAL STATE"); - - // Verify maneuvers executed - REQUIRE(sim->maneuvers[dep_idx].executed); - REQUIRE(sim->maneuvers[arr_idx].executed); - // Verify rendezvous quality double final_radius = vec3_magnitude(chaser->local_position); double radius_error = fabs(final_radius - r2); - INFO("\nVerification:"); - INFO(" Radius error: " << radius_error << " m"); - INFO(" Chaser eccentricity: " << chaser->orbit.eccentricity); Vec3 chaser_vel = chaser->local_velocity; Vec3 target_vel = target->local_velocity; @@ -560,10 +555,22 @@ SCENARIO("Hohmann transfer rendezvous with validation", "[rendezvous_hohmann][in double separation_distance = vec3_magnitude(separation); double relative_velocity = vec3_magnitude(vec3_sub(chaser_vel, target_vel)); + INFO("\n=== FINAL STATE ==="); + INFO("Final time: " << sim->time << " s"); + INFO("Departure executed: " << sim->maneuvers[dep_idx].executed); + INFO("Arrival executed: " << sim->maneuvers[arr_idx].executed); + INFO("\nVerification:"); + INFO(" Radius error: " << radius_error << " m"); + INFO(" Chaser eccentricity: " << chaser->orbit.eccentricity); INFO(" Chaser speed: " << chaser_speed << " m/s"); INFO(" Target speed: " << target_speed << " m/s"); INFO(" Separation: " << separation_distance << " m"); INFO(" Relative velocity: " << relative_velocity << " m/s"); + INFO(out.buf); + + // Verify maneuvers executed + REQUIRE(sim->maneuvers[dep_idx].executed); + REQUIRE(sim->maneuvers[arr_idx].executed); REQUIRE_THAT(radius_error, WithinAbs(10.0, 10.0)); REQUIRE_THAT(chaser->orbit.eccentricity, WithinAbs(0.0, 0.001));