@ -4,7 +4,7 @@
Comprehensive test suite to capture and validate parent-child relationship bugs in orbital mechanics simulation.
**Date:** January 20, 2026
**Status:** Implementation phase
**Status:** Complete (Tests 1-3 resolved)
**Related:** `docs/mission_planning.md` FIXME section
---
@ -13,22 +13,35 @@ Comprehensive test suite to capture and validate parent-child relationship bugs
### Root Cause Identified
**The Bug:** In `tests/configs/earth_mars_simple.toml` , the spacecraft has placeholder values:
**The Bug (Fixed) :** In `tests/configs/earth_mars_simple.toml` , spacecraft had placeholder values:
- `position = {1.496e11, 0, 0}` (IDENTICAL to Earth)
- `velocity = {0, 0, 0}` (zero velocity)
- `SOI = ~17.3 meters` (calculated from mass=1kg)
**What Happens :**
1. Config loads with spacecraft at Earth's exact position
**What Happened :**
1. Config loaded with spacecraft at Earth's exact position
2. During `find_dominant_body(1)` for Earth:
- Checks all bodies
- Finds spacecraft at distance = 0
- `0 < 17.3` is TRUE
- Sets Earth's parent to spacecraft!
- Checks all bodies
- Finds spacecraft at distance = 0
- `0 < 17.3` is TRUE
- Sets Earth's parent to spacecraft!
**Why Test Works But GUI Fails :**
**Why Test Failed But GUI Failed Worse :**
- Test calls `initialize_spacecraft_leo()` → spacecraft moved to proper LEO orbit (200km from Earth)
- GUI never calls this → placeholder values cause bug
- GUI never called this → placeholder values caused immediate bug
### Solution Implemented
**Config Validation in `src/config_loader.cpp` :**
- Added validation loop after parsing bodies, before `initialize_bodies()`
- Validates that distance between body and parent ≥ parent.radius + body.radius
- Provides clear error message with actual and required distances
- Prevents loading invalid configs with bodies too close to their parents
**Config Fix in `tests/configs/earth_mars_simple.toml` :**
- Changed spacecraft position from `1.496e11` (same as Earth) to `1.49606571e11`
- This places spacecraft at proper LEO altitude: Earth position + 6,571,000 m
- 6,571 km = Earth radius (6,371 km) + 200 km altitude
---
@ -38,9 +51,13 @@ Comprehensive test suite to capture and validate parent-child relationship bugs
**Purpose:** Directly detect when Earth's parent becomes spacecraft (the exact bug from FIXME)
**Expected Behavior:**
- Before fix: **FAILS** on step 0 or 1
- After spacecraft fix: **PASSES**
**Actual Result:** ✅ **PASSES**
**How It Was Fixed:**
- Config validation now rejects bodies starting at parent's position
- Spacecraft properly positioned at LEO altitude (6,571 km from Earth center)
- `find_dominant_body()` never finds spacecraft at distance=0
- Earth's parent remains Sun throughout simulation
**Config:** `tests/configs/earth_mars_simple.toml`
@ -55,9 +72,12 @@ REQUIRE(sim->bodies[EARTH_IDX].parent_index != SPACECRAFT_IDX);
**Purpose:** Validate that massive bodies never become children of small bodies
**Expected Behavior:**
- Before fix: **FAILS** (mass hierarchy violations)
- After spacecraft fix: **PASSES**
**Actual Result:** ✅ **PASSES**
**How It Was Fixed:**
- Config validation ensures proper parent-child distance
- Mass hierarchy preserved throughout simulation
- Earth never becomes child of spacecraft or other bodies
**Config:** `tests/configs/earth_mars_simple.toml`
@ -83,15 +103,20 @@ if (child_mass > 1e20) { // Planet-scale
**Purpose:** Detect invalid config initialization (bodies starting too close together)
**Expected Behavior:**
- Before fix: **FAILS** (distance ≈ 0 between Earth and spacecraft)
- After spacecraft fix: **PASSES**
**Actual Result:** ✅ **PASSES**
**How It Was Fixed:**
- Test updated to use radius-based validation (matches config_loader logic)
- Spacecraft now at proper LEO position: 6,571,000 m from Earth center
- Validation: distance (6,571,000 m) ≥ Earth.radius + spacecraft.radius (6,372,000 m)
- Config validation catches any bodies positioned within parent's radius
**Config:** `tests/configs/earth_mars_simple.toml`
**Key Assertion:**
```cpp
REQUIRE(distance > 100000.0); // At least 100km separation
double min_distance = sim->bodies[EARTH_IDX].radius + sim->bodies[SPACECRAFT_IDX].radius;
REQUIRE(distance >= min_distance); // parent.radius + body.radius
```
---
@ -100,19 +125,24 @@ REQUIRE(distance > 100000.0); // At least 100km separation
**Purpose:** Edge case: two Earth-like planets positioned within each other's SOI
**Expected Behavior:**
- Before fix: **FAILS** (one planet becomes parent of the other)
- After spacecraft fix: **STILL FAILS** (separate issue)
**Actual Result:** ❌ **STILL FAILS** (separate issue, not fixed by spacecraft validation)
**Config:** `tests/configs/mutual_soi_close.toml`
**Setup:**
- PlanetA: mass = 5.972e24 kg, position = {1.496e11, 0, 0}
- PlanetB: mass = 5.972e24 kg, position = {1.501e11, 0, 0}
- Separation: 5e8 meters
- Planet SOI: ~9.24e8 meters
- Separation: 5e8 meters (500 million km)
- Planet SOI: ~9.25e8 meters (925 million km)
- **Both planets within each other's SOI**
**Why This Fails:**
- Both planets start with parent=0 (Sun)
- Both are within each other's SOI
- `find_dominant_body()` logic selects closest body within SOI
- Result: PlanetA selects PlanetB as parent, PlanetB selects PlanetA as parent
- Config validation passes (both are ≥ parent.radius + body.radius from Sun)
**Key Assertions:**
```cpp
// Both should orbit Sun (not each other)
@ -130,19 +160,19 @@ for (int parent : history.planet_b_parents) {
**Expected Behavior (Option A):**
- Both planets should continue orbiting Sun
- Neither should become the other's parent
- This requires future fix to `find_dominant_body()` logic
- Neither should become other's parent
- This requires future fix to `find_dominant_body()` logic (mass hierarchy check)
---
## Test Matrix
| Test Case | Config | Tests | Expected (Before Fix) | Expected (After Spacecraft Fix) |
| Test Case | Config | Tests | Expected (Before Fix) | **Actual Result** |
|-----------|--------|-------|----------------------|--------------------------------|
| **1. Earth→Spacecraft** | earth_mars_simple.toml | Parent assignment | **FAIL** | **PASS** |
| **2. Mass Hierarchy** | earth_mars_simple.toml | Mass ratios | **FAIL** | **PASS** |
| **3. Config Validation** | earth_mars_simple.toml | Separation distance | **FAIL** | **PASS** |
| **4. Mutual SOI** | mutual_soi_close.toml | Edge case behavior | **FAIL** | **FAIL** (separate issue) |
| **1. Earth→Spacecraft** | earth_mars_simple.toml | Parent assignment | **FAIL** | ** ✅ PASS** |
| **2. Mass Hierarchy** | earth_mars_simple.toml | Mass ratios | **FAIL** | ** ✅ PASS** |
| **3. Config Validation** | earth_mars_simple.toml | Separation distance | **FAIL** | ** ✅ PASS** |
| **4. Mutual SOI** | mutual_soi_close.toml | Edge case behavior | **FAIL** | ** ❌ FAIL** (separate issue) |
---
@ -160,10 +190,29 @@ Add to CMakeLists.txt or Makefile test targets
---
## Implementation Summary
**Solution Applied (Jan 20, 2026):**
1. **Config validation in `src/config_loader.cpp`** :
- Validates parent-child distances before initialization
- Requires distance ≥ parent.radius + body.radius
- Prevents loading invalid configs
2. **Config fix in `tests/configs/earth_mars_simple.toml`** :
- Spacecraft position corrected to proper LEO altitude
- Position: 1.49606571e11 m (Earth position + 6,571,000 m offset)
- Velocity calculated by `initialize_bodies()` using `semi_major_axis = 6.571e6`
3. **Test updates in `tests/test_invalid_parent_assignment.cpp`** :
- Test 3 updated to use radius-based validation
- Matches config_loader validation logic
---
## Future Work
### After Spacecraft Fix
Tests 1-3 should pass. Test 4 will continue to fail, documenting a separate issue.
### Current Status
Tests 1-3 are now passing. Test 4 continues to fail, documenting a separate mutual SOI issue.
### Potential Fixes for Test 4
1. Add mass hierarchy check to `find_dominant_body()`
@ -179,7 +228,13 @@ Tests 1-3 should pass. Test 4 will continue to fail, documenting a separate issu
---
## References
- `docs/mission_planning.md:125-135` - FIXME section describing the bug
- `tests/configs/earth_mars_simple.toml` - Config with placeholder spacecraft values
- `docs/mission_planning.md:125-135` - FIXME section describing bug (now resolved)
- `src/config_loader.cpp:138-157` - Config validation implementation
- `tests/configs/earth_mars_simple.toml` - Corrected spacecraft position (LEO altitude)
- `src/simulation.cpp:64-107` - `find_dominant_body()` implementation
- `src/simulation.cpp:212-233` - `initialize_bodies()` implementation
- `tests/test_invalid_parent_assignment.cpp` - Test suite implementation
## Commits
- `0239cc1` - Add test suite for invalid parent assignment bugs
- `899fa3b` - Add config validation for parent-child distances