diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 11ad51c82d..28a3c16a5b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,30 +42,11 @@ jobs: - uses: dtolnay/rust-toolchain@stable - name: Install Linux dependencies uses: ./.github/actions/install-linux-deps - # At some point this may be merged into `install-linux-deps`, but for now it is its own step. - - name: Install additional Linux dependencies for Vulkan - if: ${{ runner.os == 'linux' }} - run: | - sudo add-apt-repository ppa:kisak/turtle -y - sudo apt-get install --no-install-recommends libxkbcommon-x11-0 xvfb libgl1-mesa-dri libxcb-xfixes0-dev mesa-vulkan-drivers - name: Build & run tests # See tools/ci/src/main.rs for the commands this runs run: cargo run -p ci -- test env: RUSTFLAGS: "-C debuginfo=0 -D warnings" - - name: Build & run render assets tests through xvfb - if: ${{ runner.os == 'linux' }} - # See tools/ci/src/main.rs for the commands this runs - run: xvfb-run cargo run -p ci -- test-render-assets - env: - RUSTFLAGS: "-C debuginfo=0 -D warnings" - - name: Build & run render assets tests - # Windows crashes on this due to headless app - if: ${{ runner.os == 'macOS' }} - # See tools/ci/src/main.rs for the commands this runs - run: cargo run -p ci -- test-render-assets - env: - RUSTFLAGS: "-C debuginfo=0 -D warnings" ci: runs-on: ubuntu-latest diff --git a/.github/workflows/weekly.yml b/.github/workflows/weekly.yml index 9e5b0ff227..b4ddffdb9d 100644 --- a/.github/workflows/weekly.yml +++ b/.github/workflows/weekly.yml @@ -43,30 +43,11 @@ jobs: - uses: dtolnay/rust-toolchain@beta - name: Install Linux dependencies uses: ./.github/actions/install-linux-deps - # At some point this may be merged into `install-linux-deps`, but for now it is its own step. - - name: Install additional Linux dependencies for Vulkan - if: ${{ runner.os == 'linux' }} - run: | - sudo add-apt-repository ppa:kisak/turtle -y - sudo apt-get install --no-install-recommends libxkbcommon-x11-0 xvfb libgl1-mesa-dri libxcb-xfixes0-dev mesa-vulkan-drivers - name: Build & run tests # See tools/ci/src/main.rs for the commands this runs run: cargo run -p ci -- test env: RUSTFLAGS: "-C debuginfo=0 -D warnings" - - name: Build & run render assets tests through xvfb - if: ${{ runner.os == 'linux' }} - # See tools/ci/src/main.rs for the commands this runs - run: xvfb-run cargo run -p ci -- test-render-assets - env: - RUSTFLAGS: "-C debuginfo=0 -D warnings" - - name: Build & run render assets tests - # Windows crashes on this due to headless app - if: ${{ runner.os == 'macOS' }} - # See tools/ci/src/main.rs for the commands this runs - run: cargo run -p ci -- test-render-assets - env: - RUSTFLAGS: "-C debuginfo=0 -D warnings" lint: runs-on: ubuntu-latest diff --git a/tests/render_asset_leaks.rs b/tests/render_asset_leaks.rs deleted file mode 100644 index 5f4a42efac..0000000000 --- a/tests/render_asset_leaks.rs +++ /dev/null @@ -1,278 +0,0 @@ -//! Tests if touching mutably a asset that gets extracted to the render world -//! causes a leak - -use std::time::Duration; - -use bevy::{ - app::{App, PluginGroup, Startup, Update}, - asset::{Asset, Assets, Handle}, - color::Color, - diagnostic::{DiagnosticsStore, LogDiagnosticsPlugin}, - ecs::{ - resource::Resource, - system::{Commands, Res, ResMut}, - }, - math::primitives::Sphere, - pbr::{ - diagnostic::MaterialAllocatorDiagnosticPlugin, Material, PreparedMaterial, StandardMaterial, - }, - render::{ - diagnostic::{MeshAllocatorDiagnosticPlugin, RenderAssetDiagnosticPlugin}, - mesh::{Mesh, Meshable, RenderMesh}, - }, - utils::default, - window::{ExitCondition, WindowPlugin}, - winit::WinitPlugin, - DefaultPlugins, -}; -use bevy_render::{ - settings::{Backends, RenderCreation, WgpuSettings}, - RenderPlugin, -}; - -fn base_app() -> App { - let mut app = App::new(); - app.add_plugins(( - DefaultPlugins - .build() - .set(WindowPlugin { - primary_window: None, - exit_condition: ExitCondition::DontExit, - ..default() - }) - .set(RenderPlugin { - render_creation: RenderCreation::Automatic(WgpuSettings { - backends: Some(Backends::NOOP), - ..default() - }), - ..default() - }) - .disable::(), - LogDiagnosticsPlugin { - wait_duration: Duration::ZERO, - ..default() - }, - )); - app -} - -#[test] -fn check_mesh_leak() { - let mut app = base_app(); - app.add_plugins(( - RenderAssetDiagnosticPlugin::::new(" meshes"), - MeshAllocatorDiagnosticPlugin, - )) - .add_systems(Startup, mesh_setup) - .add_systems( - Update, - (touch_mutably::, crash_on_mesh_leak_detection), - ); - - app.finish(); - app.cleanup(); - - for _ in 0..100 { - app.update(); - } -} - -#[test] -fn check_standard_material_leak() { - let mut app = base_app(); - app.add_plugins(( - RenderAssetDiagnosticPlugin::>::new(" materials"), - MaterialAllocatorDiagnosticPlugin::::new(" standard materials"), - )) - .add_systems(Startup, mesh_setup) - .add_systems( - Update, - ( - touch_mutably::, - crash_on_material_leak_detection::, - ), - ); - - app.finish(); - app.cleanup(); - - for _ in 0..100 { - app.update(); - } -} - -#[test] -fn check_mesh_churn_leak() { - let mut app = base_app(); - app.add_plugins(( - RenderAssetDiagnosticPlugin::::new(" meshes"), - MeshAllocatorDiagnosticPlugin, - )) - .add_systems(Startup, mesh_setup) - .add_systems(Update, (churn::, crash_on_mesh_leak_detection)); - - app.finish(); - app.cleanup(); - - for _ in 0..100 { - app.update(); - } -} - -#[test] -fn check_standard_material_churn_leak() { - let mut app = base_app(); - app.add_plugins(( - RenderAssetDiagnosticPlugin::>::new(" materials"), - MaterialAllocatorDiagnosticPlugin::::new(" standard materials"), - )) - .add_systems(Startup, mesh_setup) - .add_systems( - Update, - ( - churn::, - crash_on_material_leak_detection::, - ), - ); - - app.finish(); - app.cleanup(); - - for _ in 0..100 { - app.update(); - } -} - -#[ignore = "FIXME Issue #18808"] -#[test] -fn check_mesh_churn_insert_leak() { - let mut app = base_app(); - app.add_plugins(( - RenderAssetDiagnosticPlugin::::new(" meshes"), - MeshAllocatorDiagnosticPlugin, - )) - .add_systems(Startup, mesh_setup) - .add_systems( - Update, - (churn_using_insert::, crash_on_mesh_leak_detection), - ); - - app.finish(); - app.cleanup(); - - for _ in 0..100 { - app.update(); - } -} - -#[test] -fn check_standard_material_churn_insert_leak() { - let mut app = base_app(); - app.add_plugins(( - RenderAssetDiagnosticPlugin::>::new(" materials"), - MaterialAllocatorDiagnosticPlugin::::new(" standard materials"), - )) - .add_systems(Startup, mesh_setup) - .add_systems( - Update, - ( - churn_using_insert::, - crash_on_material_leak_detection::, - ), - ); - - app.finish(); - app.cleanup(); - - for _ in 0..100 { - app.update(); - } -} - -#[derive(Resource)] -struct Leaker(Vec>); - -fn mesh_setup( - mut commands: Commands, - mut meshes: ResMut>, - mut materials: ResMut>, -) { - bevy::log::info!("Mesh setup"); - - let mut mesh_leaker = Vec::with_capacity(16); - for _ in 0..16 { - mesh_leaker.push(meshes.add(Sphere::new(1.).mesh().ico(79).unwrap())); - } - commands.insert_resource(Leaker(mesh_leaker)); - let mut material_leaker = Vec::with_capacity(1000); - for _ in 0..1000 { - material_leaker.push(materials.add(Color::WHITE)); - } - commands.insert_resource(Leaker(material_leaker)); -} - -fn touch_mutably(mut assets: ResMut>) { - for _ in assets.iter_mut() {} -} - -fn churn(mut assets: ResMut>, mut leaker: ResMut>) { - let all_ids = leaker.0.drain(..).collect::>(); - for id in all_ids { - let asset = assets.remove(id.id()).unwrap(); - leaker.0.push(assets.add(asset)); - } -} - -fn churn_using_insert(mut assets: ResMut>, leaker: Res>) { - for id in &leaker.0 { - let asset = assets.remove(id.id()).unwrap(); - assets.insert(id.id(), asset); - } -} - -fn crash_on_mesh_leak_detection(diagnostic_store: Res) { - if let (Some(render_meshes), Some(slab_size), Some(allocations)) = ( - diagnostic_store - .get_measurement( - &RenderAssetDiagnosticPlugin::::render_asset_diagnostic_path(), - ) - .filter(|diag| diag.value > 0.), - diagnostic_store - .get_measurement(MeshAllocatorDiagnosticPlugin::slabs_size_diagnostic_path()) - .filter(|diag| diag.value > 0.), - diagnostic_store - .get_measurement(MeshAllocatorDiagnosticPlugin::allocations_diagnostic_path()) - .filter(|diag| diag.value > 0.), - ) { - assert!( - allocations.value < render_meshes.value * 10., - "Detected leak" - ); - assert!( - slab_size.value < (1 << 30) as f64, - "Exceeded 1GB of allocations." - ); - } -} - -fn crash_on_material_leak_detection(diagnostic_store: Res) { - if let (Some(materials), Some(slab_size), Some(allocations)) = ( - diagnostic_store - .get_measurement( - &RenderAssetDiagnosticPlugin::>::render_asset_diagnostic_path(), - ) - .filter(|diag| diag.value > 0.), - diagnostic_store - .get_measurement(&MaterialAllocatorDiagnosticPlugin::::slabs_size_diagnostic_path()) - .filter(|diag| diag.value > 0.), - diagnostic_store - .get_measurement(&MaterialAllocatorDiagnosticPlugin::::allocations_diagnostic_path()) - .filter(|diag| diag.value > 0.), - ) { - assert!(allocations.value < materials.value * 10., "Detected leak"); - assert!( - slab_size.value < (1 << 30) as f64, - "Exceeded 1GB of allocations." - ); - } -} diff --git a/tools/ci/src/ci.rs b/tools/ci/src/ci.rs index f34a8bf6e4..8b8556d90a 100644 --- a/tools/ci/src/ci.rs +++ b/tools/ci/src/ci.rs @@ -76,7 +76,6 @@ impl CI { cmds.append(&mut commands::FormatCommand::default().prepare(sh, args)); cmds.append(&mut commands::ClippyCommand::default().prepare(sh, args)); cmds.append(&mut commands::TestCommand::default().prepare(sh, args)); - cmds.append(&mut commands::TestRenderAssetsCommand::default().prepare(sh, args)); cmds.append(&mut commands::TestCheckCommand::default().prepare(sh, args)); cmds.append(&mut commands::IntegrationTestCommand::default().prepare(sh, args)); cmds.append( @@ -110,7 +109,6 @@ enum Commands { Format(commands::FormatCommand), Clippy(commands::ClippyCommand), Test(commands::TestCommand), - TestRenderAssets(commands::TestRenderAssetsCommand), TestCheck(commands::TestCheckCommand), IntegrationTest(commands::IntegrationTestCommand), IntegrationTestCheck(commands::IntegrationTestCheckCommand), @@ -133,7 +131,6 @@ impl Prepare for Commands { Commands::Format(subcommand) => subcommand.prepare(sh, args), Commands::Clippy(subcommand) => subcommand.prepare(sh, args), Commands::Test(subcommand) => subcommand.prepare(sh, args), - Commands::TestRenderAssets(subcommand) => subcommand.prepare(sh, args), Commands::TestCheck(subcommand) => subcommand.prepare(sh, args), Commands::IntegrationTest(subcommand) => subcommand.prepare(sh, args), Commands::IntegrationTestCheck(subcommand) => subcommand.prepare(sh, args), diff --git a/tools/ci/src/commands/mod.rs b/tools/ci/src/commands/mod.rs index fffb5089af..9247ab2016 100644 --- a/tools/ci/src/commands/mod.rs +++ b/tools/ci/src/commands/mod.rs @@ -14,7 +14,6 @@ pub use integration_test_clean::*; pub use lints::*; pub use test::*; pub use test_check::*; -pub use test_render_assets::*; mod bench_check; mod clippy; @@ -32,4 +31,3 @@ mod integration_test_clean; mod lints; mod test; mod test_check; -mod test_render_assets; diff --git a/tools/ci/src/commands/test_render_assets.rs b/tools/ci/src/commands/test_render_assets.rs deleted file mode 100644 index 877655ed86..0000000000 --- a/tools/ci/src/commands/test_render_assets.rs +++ /dev/null @@ -1,23 +0,0 @@ -use crate::{args::Args, Prepare, PreparedCommand}; -use argh::FromArgs; -use xshell::cmd; - -/// Runs all tests (except for doc tests). -#[derive(FromArgs, Default)] -#[argh(subcommand, name = "test-render-assets")] -pub struct TestRenderAssetsCommand {} - -impl Prepare for TestRenderAssetsCommand { - fn prepare<'a>(&self, sh: &'a xshell::Shell, args: Args) -> Vec> { - let no_fail_fast = args.keep_going(); - let jobs = args.build_jobs(); - let test_threads = args.test_threads(); - let jobs_ref = jobs.as_ref(); - let test_threads_ref = test_threads.as_ref(); - - vec![PreparedCommand::new::( - cmd!(sh, "cargo test --test render_asset_leaks {no_fail_fast...} {jobs_ref...} -- {test_threads_ref...}"), - "Please fix failing tests in output above.", - )] - } -}