chore(release): final release commit for 0.1.0

this commit includes a whole lotta fuck yeah, a whole lotta we fuckin
got this, and a lot of "please change the future."

i hope it works.

Signed-off-by: Sienna Meridian Satterwhite <sienna@r3t.io>
This commit is contained in:
2026-02-06 20:10:51 +00:00
parent 854b858159
commit 9010ec5cf4
21 changed files with 4218 additions and 248 deletions

View File

@@ -14,7 +14,7 @@ mod test_utils;
use std::time::Duration;
use anyhow::Result;
use bevy::prelude::Transform;
use bevy::prelude::{App, FixedUpdate, Transform};
use libmarathon::networking::{
CurrentSession,
GossipBridge,
@@ -23,6 +23,14 @@ use libmarathon::networking::{
use test_utils::{TestContext, create_test_app_maybe_offline};
use uuid::Uuid;
/// Helper to ensure FixedUpdate runs (since it's on a fixed timestep)
fn update_with_fixed(app: &mut App) {
// Run Main schedule (which includes Update)
app.update();
// Explicitly run FixedUpdate to ensure systems there execute
app.world_mut().run_schedule(FixedUpdate);
}
// ============================================================================
// Session Lifecycle Tests
// ============================================================================
@@ -114,7 +122,7 @@ async fn test_join_request_sent() -> Result<()> {
// Create app offline
let mut app = create_test_app_maybe_offline(node_id, ctx.db_path(), None);
app.update();
update_with_fixed(&mut app);
// Create and insert GossipBridge
let bridge = GossipBridge::new(node_id);
@@ -128,7 +136,7 @@ async fn test_join_request_sent() -> Result<()> {
// Update to trigger send_join_request_once_system
// With the peer-wait logic, JoinRequest waits for peers or timeout
app.update(); // Start wait timer
update_with_fixed(&mut app); // Start wait timer
// Simulate 1-second timeout (first node case - no peers)
{
@@ -139,7 +147,7 @@ async fn test_join_request_sent() -> Result<()> {
}
// Update again - should send JoinRequest due to timeout
app.update();
update_with_fixed(&mut app);
// Verify JoinRequest was sent by checking JoinRequestSent resource
{
@@ -393,7 +401,7 @@ async fn test_join_request_waits_for_peers() -> Result<()> {
let bridge = GossipBridge::new(node_id);
let mut app = create_test_app_maybe_offline(node_id, ctx.db_path(), Some(bridge.clone()));
app.update();
update_with_fixed(&mut app);
// Transition to Joining
{
@@ -412,7 +420,7 @@ async fn test_join_request_waits_for_peers() -> Result<()> {
// Run for 10 frames (~166ms) - should NOT send JoinRequest yet (no peers)
for i in 0..10 {
app.update();
update_with_fixed(&mut app);
tokio::time::sleep(Duration::from_millis(16)).await;
let join_sent = app.world().resource::<libmarathon::networking::JoinRequestSent>();
@@ -560,7 +568,7 @@ async fn test_join_request_sends_after_timeout() -> Result<()> {
let bridge = GossipBridge::new(node_id);
let mut app = create_test_app_maybe_offline(node_id, ctx.db_path(), Some(bridge.clone()));
app.update();
update_with_fixed(&mut app);
// Transition to Joining
{
@@ -571,7 +579,7 @@ async fn test_join_request_sends_after_timeout() -> Result<()> {
println!("Initial state: Session=Joining, Peers=0");
// Run one frame to start the wait timer
app.update();
update_with_fixed(&mut app);
// Manually set wait_started to 1.1 seconds ago to simulate timeout
{
@@ -583,7 +591,7 @@ async fn test_join_request_sends_after_timeout() -> Result<()> {
}
// Run one frame - should send JoinRequest due to timeout
app.update();
update_with_fixed(&mut app);
{
let join_sent = app.world().resource::<libmarathon::networking::JoinRequestSent>();
@@ -627,7 +635,7 @@ async fn test_join_request_only_sent_once() -> Result<()> {
let bridge = GossipBridge::new(node_id);
let mut app = create_test_app_maybe_offline(node_id, ctx.db_path(), Some(bridge.clone()));
app.update();
update_with_fixed(&mut app);
// Transition to Joining and add a peer
{
@@ -644,7 +652,7 @@ async fn test_join_request_only_sent_once() -> Result<()> {
println!("Initial state: Session=Joining, Peers=1");
// Run frame - should send JoinRequest
app.update();
update_with_fixed(&mut app);
{
let join_sent = app.world().resource::<libmarathon::networking::JoinRequestSent>();
@@ -678,7 +686,7 @@ async fn test_join_request_only_sent_once() -> Result<()> {
// Run 20 more frames - should NOT send JoinRequest again
for i in 0..20 {
app.update();
update_with_fixed(&mut app);
tokio::time::sleep(Duration::from_millis(16)).await;
let app_bridge = app.world().resource::<libmarathon::networking::GossipBridge>();

View File

@@ -95,6 +95,17 @@ struct TestHealth {
use rusqlite::Connection;
/// Helper to ensure FixedUpdate and FixedPostUpdate run (since they're on a fixed timestep)
fn update_with_fixed(app: &mut App) {
use bevy::prelude::{FixedUpdate, FixedPostUpdate};
// Run Main schedule (which includes Update)
app.update();
// Explicitly run FixedUpdate to ensure systems there execute
app.world_mut().run_schedule(FixedUpdate);
// Explicitly run FixedPostUpdate to ensure delta generation executes
app.world_mut().run_schedule(FixedPostUpdate);
}
/// Check if an entity exists in the database
fn entity_exists_in_db(db_path: &PathBuf, entity_id: Uuid) -> Result<bool> {
let conn = Connection::open(db_path)?;
@@ -868,8 +879,8 @@ async fn test_lock_heartbeat_expiration() -> Result<()> {
// Update to allow lock propagation
for _ in 0..10 {
app1.update();
app2.update();
update_with_fixed(&mut app1);
update_with_fixed(&mut app2);
tokio::time::sleep(Duration::from_millis(100)).await;
}
@@ -899,7 +910,7 @@ async fn test_lock_heartbeat_expiration() -> Result<()> {
// Run cleanup system (which removes expired locks and broadcasts LockReleased)
println!("Running cleanup to expire locks...");
for _ in 0..10 {
app2.update();
update_with_fixed(&mut app2);
tokio::time::sleep(Duration::from_millis(100)).await;
}
@@ -1119,7 +1130,7 @@ async fn test_offline_to_online_sync() -> Result<()> {
}
// Update to trigger delta generation (offline)
app1.update();
update_with_fixed(&mut app1);
tokio::time::sleep(Duration::from_millis(50)).await;
// Verify clock incremented for spawn
@@ -1156,7 +1167,7 @@ async fn test_offline_to_online_sync() -> Result<()> {
}
}
app1.update();
update_with_fixed(&mut app1);
tokio::time::sleep(Duration::from_millis(50)).await;
let clock_after_second_spawn = {
@@ -1179,7 +1190,7 @@ async fn test_offline_to_online_sync() -> Result<()> {
}
}
app1.update();
update_with_fixed(&mut app1);
tokio::time::sleep(Duration::from_millis(50)).await;
let clock_after_modify = {
@@ -1197,7 +1208,7 @@ async fn test_offline_to_online_sync() -> Result<()> {
commands.entity(entity_b_bevy).insert(ToDelete);
}
app1.update();
update_with_fixed(&mut app1);
tokio::time::sleep(Duration::from_millis(50)).await;
let clock_after_delete = {
@@ -1262,8 +1273,8 @@ async fn test_offline_to_online_sync() -> Result<()> {
// Wait a bit more for tombstone to sync
for _ in 0..20 {
app1.update();
app2.update();
update_with_fixed(&mut app1);
update_with_fixed(&mut app2);
tokio::time::sleep(Duration::from_millis(100)).await;
}

View File

@@ -87,6 +87,17 @@ pub fn create_test_app_maybe_offline(node_id: Uuid, db_path: PathBuf, bridge: Op
app
}
/// Helper to ensure FixedUpdate and FixedPostUpdate run (since they're on a fixed timestep)
fn update_with_fixed(app: &mut App) {
use bevy::prelude::{FixedUpdate, FixedPostUpdate};
// Run Main schedule (which includes Update)
app.update();
// Explicitly run FixedUpdate to ensure systems there execute
app.world_mut().run_schedule(FixedUpdate);
// Explicitly run FixedPostUpdate to ensure delta generation executes
app.world_mut().run_schedule(FixedPostUpdate);
}
/// Wait for sync condition to be met, polling both apps
pub async fn wait_for_sync<F>(
app1: &mut App,
@@ -102,8 +113,8 @@ where
while start.elapsed() < timeout {
// Tick both apps
app1.update();
app2.update();
update_with_fixed(app1);
update_with_fixed(app2);
tick_count += 1;
if tick_count % 50 == 0 {