From d868d07d0bce1b57965928577426c877a689e069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Wed, 14 Apr 2021 21:40:36 +0000 Subject: [PATCH] run some examples on CI using swiftshader (#1826) From suggestion from Godot workflows: https://github.com/bevyengine/bevy/issues/1730#issuecomment-810321110 * Add a feature `bevy_debug` that will make Bevy read a debug config file to setup some debug systems * Currently, only one that will exit after x frames * Could add option to dump screen to image file once that's possible * Add a job in CI workflow that will run a few examples using [`swiftshader`](https://github.com/google/swiftshader) * This job takes around 13 minutes, so doesn't add to global CI duration |example|number of frames|duration| |-|-|-| |`alien_cake_addict`|300|1:50| |`breakout`|1800|0:44| |`contributors`|1800|0:43| |`load_gltf`|300|2:37| |`scene`|1800|0:44| --- .github/example-run/alien_cake_addict.ron | 3 ++ .github/example-run/breakout.ron | 3 ++ .github/example-run/contributors.ron | 3 ++ .github/example-run/load_gltf.ron | 3 ++ .github/example-run/scene.ron | 3 ++ .github/workflows/ci.yml | 36 +++++++++++++++++++++ Cargo.toml | 3 ++ crates/bevy_app/Cargo.toml | 3 ++ crates/bevy_app/src/app_builder.rs | 5 +++ crates/bevy_app/src/ci_testing.rs | 38 +++++++++++++++++++++++ crates/bevy_app/src/lib.rs | 3 ++ crates/bevy_internal/Cargo.toml | 3 ++ 12 files changed, 106 insertions(+) create mode 100644 .github/example-run/alien_cake_addict.ron create mode 100644 .github/example-run/breakout.ron create mode 100644 .github/example-run/contributors.ron create mode 100644 .github/example-run/load_gltf.ron create mode 100644 .github/example-run/scene.ron create mode 100644 crates/bevy_app/src/ci_testing.rs diff --git a/.github/example-run/alien_cake_addict.ron b/.github/example-run/alien_cake_addict.ron new file mode 100644 index 0000000000..d170958d73 --- /dev/null +++ b/.github/example-run/alien_cake_addict.ron @@ -0,0 +1,3 @@ +( + exit_after: Some(300) +) diff --git a/.github/example-run/breakout.ron b/.github/example-run/breakout.ron new file mode 100644 index 0000000000..78c040831e --- /dev/null +++ b/.github/example-run/breakout.ron @@ -0,0 +1,3 @@ +( + exit_after: Some(1800) +) diff --git a/.github/example-run/contributors.ron b/.github/example-run/contributors.ron new file mode 100644 index 0000000000..78c040831e --- /dev/null +++ b/.github/example-run/contributors.ron @@ -0,0 +1,3 @@ +( + exit_after: Some(1800) +) diff --git a/.github/example-run/load_gltf.ron b/.github/example-run/load_gltf.ron new file mode 100644 index 0000000000..d170958d73 --- /dev/null +++ b/.github/example-run/load_gltf.ron @@ -0,0 +1,3 @@ +( + exit_after: Some(300) +) diff --git a/.github/example-run/scene.ron b/.github/example-run/scene.ron new file mode 100644 index 0000000000..78c040831e --- /dev/null +++ b/.github/example-run/scene.ron @@ -0,0 +1,3 @@ +( + exit_after: Some(1800) +) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 21cc5bb6d8..c44437b8c9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -92,3 +92,39 @@ jobs: DEFAULT_BRANCH: master # Not needed here as only one Linter is used. #GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + run-examples: + runs-on: ubuntu-latest + + steps: + - name: Install dependencies + run: | + sudo apt-get update; + DEBIAN_FRONTEND=noninteractive sudo apt-get install --no-install-recommends -yq \ + libasound2-dev libudev-dev wget unzip xvfb; + + - uses: actions/checkout@v2 + + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + + - name: Setup swiftshader + run: | + wget https://github.com/qarmin/gtk_library_store/releases/download/3.24.0/swiftshader.zip; + unzip swiftshader.zip; + curr="$(pwd)/libvk_swiftshader.so"; + sed -i "s|PATH_TO_CHANGE|$curr|" vk_swiftshader_icd.json; + + - name: Build bevy + run: | + cargo build --no-default-features --features "bevy_dynamic_plugin,bevy_gilrs,bevy_gltf,bevy_wgpu,bevy_winit,render,png,hdr,x11,bevy_ci_testing" + + - name: Run examples + run: | + for example in .github/example-run/*.ron; do + example_name=`basename $example .ron` + echo "running $example_name - "`date` + time CI_TESTING_CONFIG=$example VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json DRI_PRIME=0 xvfb-run cargo run --example $example_name --no-default-features --features "bevy_dynamic_plugin,bevy_gilrs,bevy_gltf,bevy_wgpu,bevy_winit,render,png,hdr,x11,bevy_ci_testing" + sleep 10 + done diff --git a/Cargo.toml b/Cargo.toml index 36f8cd4933..1f85b05e79 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,6 +75,9 @@ x11 = ["bevy_internal/x11"] # enable rendering of font glyphs using subpixel accuracy subpixel_glyph_atlas = ["bevy_internal/subpixel_glyph_atlas"] +# enable systems that allow for automated testing on CI +bevy_ci_testing = ["bevy_internal/bevy_ci_testing"] + [dependencies] bevy_dylib = {path = "crates/bevy_dylib", version = "0.5.0", default-features = false, optional = true} bevy_internal = {path = "crates/bevy_internal", version = "0.5.0", default-features = false} diff --git a/crates/bevy_app/Cargo.toml b/crates/bevy_app/Cargo.toml index aecb5b1892..ddb68b458e 100644 --- a/crates/bevy_app/Cargo.toml +++ b/crates/bevy_app/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["bevy"] [features] trace = [] +bevy_ci_testing = ["ron"] default = ["bevy_reflect"] [dependencies] @@ -25,6 +26,8 @@ bevy_utils = { path = "../bevy_utils", version = "0.5.0" } # other serde = { version = "1.0", features = ["derive"] } +ron = { version = "0.6.2", optional = true } + [target.'cfg(target_arch = "wasm32")'.dependencies] wasm-bindgen = { version = "0.2" } diff --git a/crates/bevy_app/src/app_builder.rs b/crates/bevy_app/src/app_builder.rs index 7956c3d5d2..0acd946adb 100644 --- a/crates/bevy_app/src/app_builder.rs +++ b/crates/bevy_app/src/app_builder.rs @@ -33,6 +33,11 @@ impl Default for AppBuilder { .add_default_stages() .add_event::() .add_system_to_stage(CoreStage::Last, World::clear_trackers.exclusive_system()); + + #[cfg(feature = "bevy_ci_testing")] + { + crate::ci_testing::setup_app(&mut app_builder); + } app_builder } } diff --git a/crates/bevy_app/src/ci_testing.rs b/crates/bevy_app/src/ci_testing.rs new file mode 100644 index 0000000000..21e22bec04 --- /dev/null +++ b/crates/bevy_app/src/ci_testing.rs @@ -0,0 +1,38 @@ +use serde::Deserialize; + +use crate::{app::AppExit, AppBuilder}; +use bevy_ecs::system::IntoSystem; + +/// Configuration for automated testing on CI +#[derive(Deserialize)] +pub struct CiTestingConfig { + /// Number of frames after wich Bevy should exit + pub exit_after: Option, +} + +fn ci_testing_exit_after( + mut current_frame: bevy_ecs::prelude::Local, + ci_testing_config: bevy_ecs::prelude::Res, + mut app_exit_events: crate::EventWriter, +) { + if let Some(exit_after) = ci_testing_config.exit_after { + if *current_frame > exit_after { + app_exit_events.send(AppExit); + } + } + *current_frame += 1; +} + +pub(crate) fn setup_app(app_builder: &mut AppBuilder) -> &mut AppBuilder { + let filename = + std::env::var("CI_TESTING_CONFIG").unwrap_or_else(|_| "ci_testing_config.ron".to_string()); + let config: CiTestingConfig = ron::from_str( + &std::fs::read_to_string(filename).expect("error reading CI testing configuration file"), + ) + .expect("error deserializing CI testing configuration file"); + app_builder + .insert_resource(config) + .add_system(ci_testing_exit_after.system()); + + app_builder +} diff --git a/crates/bevy_app/src/lib.rs b/crates/bevy_app/src/lib.rs index e1b07208bc..a09968b7fa 100644 --- a/crates/bevy_app/src/lib.rs +++ b/crates/bevy_app/src/lib.rs @@ -4,6 +4,9 @@ mod plugin; mod plugin_group; mod schedule_runner; +#[cfg(feature = "bevy_ci_testing")] +mod ci_testing; + pub use app::*; pub use app_builder::*; pub use bevy_derive::DynamicPlugin; diff --git a/crates/bevy_internal/Cargo.toml b/crates/bevy_internal/Cargo.toml index a5add55a78..9d557aff5d 100644 --- a/crates/bevy_internal/Cargo.toml +++ b/crates/bevy_internal/Cargo.toml @@ -41,6 +41,9 @@ x11 = ["bevy_winit/x11"] # enable rendering of font glyphs using subpixel accuracy subpixel_glyph_atlas = ["bevy_text/subpixel_glyph_atlas"] +# enable systems that allow for automated testing on CI +bevy_ci_testing = ["bevy_app/bevy_ci_testing"] + [dependencies] # bevy bevy_app = { path = "../bevy_app", version = "0.5.0" }