From bce0608e1f1cfa4da5109dfdbcfe331dd3c07fb7 Mon Sep 17 00:00:00 2001 From: Nathan Adams Date: Thu, 9 Nov 2023 15:36:46 +0100 Subject: [PATCH] tests: Move all wgpu code out of test framework, make it abstract over any/no renderer, and make wgpu option if imgtests isn't enabled --- Cargo.lock | 4 +- core/src/player.rs | 7 ++ tests/Cargo.toml | 7 +- tests/framework/Cargo.toml | 4 +- tests/framework/src/environment.rs | 62 +++++------- tests/framework/src/options.rs | 74 ++++---------- tests/framework/src/runner.rs | 65 +++++-------- tests/framework/src/test.rs | 18 +++- tests/tests/environment.rs | 123 ++++++++++++++++++++++++ tests/tests/external_interface/tests.rs | 11 ++- tests/tests/regression_tests.rs | 35 ++++--- tests/tests/shared_object/mod.rs | 15 ++- 12 files changed, 265 insertions(+), 160 deletions(-) create mode 100644 tests/tests/environment.rs diff --git a/Cargo.lock b/Cargo.lock index b2246ec0f..ac8535e2e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4271,7 +4271,6 @@ dependencies = [ "ruffle_core", "ruffle_input_format", "ruffle_render", - "ruffle_render_wgpu", "ruffle_socket_format", "ruffle_video_software", "serde", @@ -4922,8 +4921,11 @@ name = "tests" version = "0.1.0" dependencies = [ "anyhow", + "futures", + "image", "libtest-mimic", "ruffle_core", + "ruffle_render_wgpu", "ruffle_test_framework", "walkdir", ] diff --git a/core/src/player.rs b/core/src/player.rs index dc98d23f7..365b69aee 100644 --- a/core/src/player.rs +++ b/core/src/player.rs @@ -2270,6 +2270,13 @@ impl PlayerBuilder { self } + /// Sets the rendering backend of the player. + #[inline] + pub fn with_boxed_renderer(mut self, renderer: Box) -> Self { + self.renderer = Some(renderer); + self + } + /// Sets the storage backend of the player. #[inline] pub fn with_storage(mut self, storage: impl 'static + StorageBackend) -> Self { diff --git a/tests/Cargo.toml b/tests/Cargo.toml index adbbbb4d1..2d34c2b0c 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -11,16 +11,21 @@ version.workspace = true # Enable running image comparison tests. This is off by default, # since the images we compare against are generated on CI, and may # not match your local machine's Vulkan version / image output. -imgtests = ["ruffle_test_framework/imgtests"] +imgtests = ["ruffle_test_framework/ruffle_video_software", "ruffle_render_wgpu"] jpegxr = ["ruffle_test_framework/jpegxr"] lzma = ["ruffle_test_framework/lzma"] +[dependencies] +ruffle_render_wgpu = { path = "../render/wgpu", optional = true } + [dev-dependencies] ruffle_core = { path = "../core", features = ["deterministic", "timeline_debug", "avm_debug", "audio", "mp3", "default_font"] } ruffle_test_framework = { path = "framework" } libtest-mimic = "0.6.1" walkdir = "2.4.0" anyhow = "1.0.75" +image = { version = "0.24.7", default-features = false, features = ["png"] } +futures = "0.3.29" [[test]] name = "tests" diff --git a/tests/framework/Cargo.toml b/tests/framework/Cargo.toml index ba8c4f553..729df9e68 100644 --- a/tests/framework/Cargo.toml +++ b/tests/framework/Cargo.toml @@ -10,12 +10,11 @@ version.workspace = true [dependencies] futures = "0.3.29" ruffle_core = { path = "../../core", features = ["deterministic", "timeline_debug", "avm_debug", "audio", "mp3", "default_font"] } -ruffle_render_wgpu = { path = "../../render/wgpu" } ruffle_render = { path = "../../render" } ruffle_input_format = { path = "../input-format" } ruffle_socket_format = { path = "../socket-format" } ruffle_video_software = { path = "../../video/software", optional = true } -image = { version = "0.24.7", default-features = false, features = ["png"] } +image = { version = "0.24.7", default-features = false, features = ["png"] } regex = "1.10.2" url = "2.4.1" chrono = "0.4.31" @@ -32,6 +31,5 @@ anyhow = "1.0.75" async-channel = "1.9.0" [features] -imgtests = ["ruffle_video_software"] jpegxr = ["ruffle_core/jpegxr"] lzma = ["ruffle_core/lzma"] \ No newline at end of file diff --git a/tests/framework/src/environment.rs b/tests/framework/src/environment.rs index ca43b6f95..9c3d76d27 100644 --- a/tests/framework/src/environment.rs +++ b/tests/framework/src/environment.rs @@ -1,43 +1,33 @@ -use ruffle_render_wgpu::backend::request_adapter_and_device; -use ruffle_render_wgpu::descriptors::Descriptors; -use ruffle_render_wgpu::wgpu; -use std::sync::{Arc, OnceLock}; +use crate::options::RenderOptions; -/* - It can be expensive to construct WGPU, much less Descriptors, so we put it off as long as we can - and share it across tests in the same process. +pub use ruffle_render::backend::RenderBackend; - Remember: - `cargo test` will run all tests in the same process. - `cargo nextest run` will create a different process per test. +pub trait Environment { + /// Checks if this environment supports rendering the given test. + /// + /// This isn't a guarantee that it _will_ construct a renderer, + /// but rather a check that it theoretically _can_. + /// + /// This should be a cheap test to filter out test viability early, + /// without creating any expensive rendering overhead. + fn is_render_supported(&self, _requirements: &RenderOptions) -> bool { + false + } - For `cargo test` it's relatively okay if we spend the time to construct descriptors once, - but for `cargo nextest run` it's a big cost per test if it's not going to use it. -*/ - -fn create_wgpu_device() -> Option<(wgpu::Instance, wgpu::Adapter, wgpu::Device, wgpu::Queue)> { - let instance = wgpu::Instance::new(Default::default()); - futures::executor::block_on(request_adapter_and_device( - wgpu::Backends::all(), - &instance, - None, - Default::default(), - None, - )) - .ok() - .map(|(adapter, device, queue)| (instance, adapter, device, queue)) -} - -fn build_wgpu_descriptors() -> Option> { - if let Some((instance, adapter, device, queue)) = create_wgpu_device() { - Some(Arc::new(Descriptors::new(instance, adapter, device, queue))) - } else { + /// Creates a render backend for the given test. + /// + /// If [Self::is_render_supported] returned false, this won't be attempted. + fn create_renderer(&self, _width: u32, _height: u32) -> Option> { None } -} -pub fn wgpu_descriptors() -> Option<&'static Arc> { - // TODO: Use `std::sync::LazyLock` once it's stabilized? - static WGPU: OnceLock>> = OnceLock::new(); - WGPU.get_or_init(build_wgpu_descriptors).as_ref() + /// Gets the name of this environment, for use in test reporting. + /// + /// This name may be used in file paths, so it should contain appropriate characters for such. + fn name(&self) -> String; + + /// Capture the stage rendered out by the given render backend. + /// + /// The provided backend will have previously been created by [Environment::create_renderer]. + fn capture_renderer(&self, renderer: &mut Box) -> image::RgbaImage; } diff --git a/tests/framework/src/options.rs b/tests/framework/src/options.rs index c5def41b0..4b97d3b8c 100644 --- a/tests/framework/src/options.rs +++ b/tests/framework/src/options.rs @@ -1,5 +1,5 @@ use crate::backends::TestAudioBackend; -use crate::environment::wgpu_descriptors; +use crate::environment::Environment; use crate::image_trigger::ImageTrigger; use anyhow::{anyhow, Result}; use approx::assert_relative_eq; @@ -7,7 +7,6 @@ use regex::Regex; use ruffle_core::tag_utils::SwfMovie; use ruffle_core::{PlayerBuilder, ViewportDimensions}; use ruffle_render::quality::StageQuality; -use ruffle_render_wgpu::wgpu; use serde::Deserialize; use std::collections::{HashMap, HashSet}; use std::fs; @@ -141,6 +140,7 @@ impl PlayerOptions { &self, mut player_builder: PlayerBuilder, movie: &SwfMovie, + environment: &impl Environment, ) -> Result { if let Some(max_execution_duration) = self.max_execution_duration { player_builder = player_builder.with_max_execution_duration(max_execution_duration); @@ -161,27 +161,16 @@ impl PlayerOptions { }; if let Some(render_options) = &self.with_renderer { - use ruffle_render_wgpu::backend::WgpuRenderBackend; - use ruffle_render_wgpu::target::TextureTarget; + player_builder = player_builder.with_quality(match render_options.sample_count { + 16 => StageQuality::High16x16, + 8 => StageQuality::High8x8, + 4 => StageQuality::High, + 2 => StageQuality::Medium, + _ => StageQuality::Low, + }); - if let Some(descriptors) = wgpu_descriptors() { - if render_options.is_supported(&descriptors.adapter) { - let target = TextureTarget::new(&descriptors.device, (width, height)) - .map_err(|e| anyhow!(e.to_string()))?; - - player_builder = player_builder - .with_quality(match render_options.sample_count { - 16 => StageQuality::High16x16, - 8 => StageQuality::High8x8, - 4 => StageQuality::High, - 2 => StageQuality::Medium, - _ => StageQuality::Low, - }) - .with_renderer( - WgpuRenderBackend::new(descriptors.clone(), target) - .map_err(|e| anyhow!(e.to_string()))?, - ); - } + if let Some(renderer) = environment.create_renderer(width, height) { + player_builder = player_builder.with_boxed_renderer(renderer); } } @@ -189,7 +178,7 @@ impl PlayerOptions { player_builder = player_builder.with_audio(TestAudioBackend::default()); } - #[cfg(feature = "imgtests")] + #[cfg(feature = "ruffle_video_software")] if self.with_video { use ruffle_video_software::backend::SoftwareVideoBackend; player_builder = player_builder.with_video(SoftwareVideoBackend::new()) @@ -198,18 +187,12 @@ impl PlayerOptions { Ok(player_builder) } - pub fn can_run(&self, check_renderer: bool) -> bool { + pub fn can_run(&self, check_renderer: bool, environment: &impl Environment) -> bool { if let Some(render) = &self.with_renderer { // If we don't actually want to check the renderer (ie we're just listing potential tests), // don't spend the cost to create it - if check_renderer && !render.optional { - if let Some(descriptors) = wgpu_descriptors() { - if !render.is_supported(&descriptors.adapter) { - return false; - } - } else { - return false; - } + if check_renderer && !render.optional && !environment.is_render_supported(render) { + return false; } } true @@ -224,31 +207,27 @@ pub struct ImageComparison { pub trigger: ImageTrigger, } -#[cfg(feature = "imgtests")] fn calc_difference(lhs: u8, rhs: u8) -> u8 { (lhs as i16 - rhs as i16).unsigned_abs() as u8 } impl ImageComparison { - #[cfg(feature = "imgtests")] pub fn test( &self, name: &str, actual_image: image::RgbaImage, expected_image: image::RgbaImage, test_path: &Path, - adapter_info: wgpu::AdapterInfo, + environment_name: String, known_failure: bool, ) -> Result<()> { use anyhow::Context; - let suffix = format!("{}-{:?}", std::env::consts::OS, adapter_info.backend); - let save_actual_image = || { if !known_failure { // If we're expecting failure, spamming files isn't productive. actual_image - .save(test_path.join(format!("{name}.actual-{suffix}.png"))) + .save(test_path.join(format!("{name}.actual-{environment_name}.png"))) .context("Couldn't save actual image") } else { Ok(()) @@ -323,7 +302,7 @@ impl ImageComparison { difference_color, ) .context("Couldn't create color difference image")? - .save(test_path.join(format!("{name}.difference-color-{suffix}.png"))) + .save(test_path.join(format!("{name}.difference-color-{environment_name}.png"))) .context("Couldn't save color difference image")?; } @@ -343,7 +322,7 @@ impl ImageComparison { difference_alpha, ) .context("Couldn't create alpha difference image")? - .save(test_path.join(format!("{name}.difference-alpha-{suffix}.png"))) + .save(test_path.join(format!("{name}.difference-alpha-{environment_name}.png"))) .context("Couldn't save alpha difference image")?; } } @@ -367,8 +346,8 @@ impl ImageComparison { #[serde(default, deny_unknown_fields)] pub struct RenderOptions { optional: bool, - sample_count: u32, - exclude_warp: bool, + pub sample_count: u32, + pub exclude_warp: bool, } impl Default for RenderOptions { @@ -380,14 +359,3 @@ impl Default for RenderOptions { } } } - -impl RenderOptions { - pub fn is_supported(&self, adapter: &wgpu::Adapter) -> bool { - let info = adapter.get_info(); - // 5140 & 140 is WARP, https://learn.microsoft.com/en-us/windows/win32/direct3ddxgi/d3d10-graphics-programming-guide-dxgi#new-info-about-enumerating-adapters-for-windows-8 - if self.exclude_warp && cfg!(windows) && info.vendor == 5140 && info.device == 140 { - return false; - } - true - } -} diff --git a/tests/framework/src/runner.rs b/tests/framework/src/runner.rs index 28e005f71..ee5b46ec7 100644 --- a/tests/framework/src/runner.rs +++ b/tests/framework/src/runner.rs @@ -1,4 +1,5 @@ use crate::backends::{TestLogBackend, TestNavigatorBackend}; +use crate::environment::Environment; use crate::fs_commands::{FsCommand, TestFsCommandProvider}; use crate::image_trigger::ImageTrigger; use crate::options::ImageComparison; @@ -15,7 +16,7 @@ use ruffle_input_format::{ AutomatedEvent, InputInjector, MouseButton as InputMouseButton, TextControlCode as InputTextControlCode, }; -use ruffle_render_wgpu::descriptors::Descriptors; +use ruffle_render::backend::null::NullRenderer; use ruffle_socket_format::SocketEvent; use std::path::Path; use std::sync::{Arc, Mutex}; @@ -29,6 +30,7 @@ pub fn run_swf( socket_events: Option>, before_start: impl FnOnce(Arc>) -> Result<()>, before_end: impl FnOnce(Arc>) -> Result<()>, + environment: &impl Environment, ) -> Result { let base_path = Path::new(&test.output_path).parent().unwrap(); let mut executor = NullExecutor::new(); @@ -65,18 +67,20 @@ pub fn run_swf( let player = test .options .player_options - .setup(builder, &movie)? + .setup(builder, &movie, environment)? .with_movie(movie) .with_autoplay(true) //.tick() requires playback .build(); - let mut images = test.options.image_comparisons.clone(); + // If we set anything but a null renderer, then the Environment must have created a valid renderer. + let has_renderer = player + .lock() + .unwrap() + .renderer() + .downcast_ref::() + .is_none(); - let wgpu_descriptors = if cfg!(feature = "imgtests") && !images.is_empty() { - crate::environment::wgpu_descriptors() - } else { - None - }; + let mut images = test.options.image_comparisons.clone(); before_start(player.clone())?; @@ -142,10 +146,11 @@ pub fn run_swf( capture_and_compare_image( base_path, &player, - wgpu_descriptors, &name, image_comparison, test.options.known_failure, + environment, + has_renderer, )?; } else { return Err(anyhow!("Encountered fscommand to capture and compare image '{name}', but no [image_comparison] was set up for this.")); @@ -214,10 +219,11 @@ pub fn run_swf( capture_and_compare_image( base_path, &player, - wgpu_descriptors, &name, image_comparison, test.options.known_failure, + environment, + has_renderer, )?; } } @@ -234,10 +240,11 @@ pub fn run_swf( capture_and_compare_image( base_path, &player, - wgpu_descriptors, &name, image_comparison, test.options.known_failure, + environment, + has_renderer, )?; } @@ -260,48 +267,22 @@ pub fn run_swf( Ok(normalized_trace) } -#[cfg(not(feature = "imgtests"))] -fn capture_and_compare_image( - _base_path: &Path, - _player: &Arc>, - _wgpu_descriptors: Option<&Arc>, - _name: &str, - _image_comparison: ImageComparison, - known_failure: bool, -) -> Result<()> { - if known_failure { - // It's possible that the trace output matched but the image might not. - // If we aren't checking the image, pretend the match failed (which makes it actually pass, since it's expecting failure). - Err(anyhow!( - "Not checking images, pretending this failed since we don't know if it worked." - )) - } else { - Ok(()) - } -} - -#[cfg(feature = "imgtests")] fn capture_and_compare_image( base_path: &Path, player: &Arc>, - wgpu_descriptors: Option<&Arc>, name: &String, image_comparison: ImageComparison, known_failure: bool, + environment: &impl Environment, + has_renderer: bool, ) -> Result<()> { use anyhow::Context; - use ruffle_render_wgpu::backend::WgpuRenderBackend; - use ruffle_render_wgpu::target::TextureTarget; - if let Some(wgpu_descriptors) = wgpu_descriptors { + if has_renderer { let mut player_lock = player.lock().unwrap(); player_lock.render(); - let renderer = player_lock - .renderer_mut() - .downcast_mut::>() - .unwrap(); - let actual_image = renderer.capture_frame().expect("Failed to capture image"); + let actual_image = environment.capture_renderer(player_lock.renderer_mut()); let expected_image_path = base_path.join(format!("{name}.expected.png")); if expected_image_path.is_file() { @@ -314,7 +295,7 @@ fn capture_and_compare_image( actual_image, expected_image, base_path, - wgpu_descriptors.adapter.get_info(), + environment.name(), known_failure, )?; } else if !known_failure { diff --git a/tests/framework/src/test.rs b/tests/framework/src/test.rs index b56bc1465..6af391e1b 100644 --- a/tests/framework/src/test.rs +++ b/tests/framework/src/test.rs @@ -1,3 +1,4 @@ +use crate::environment::Environment; use crate::options::TestOptions; use crate::runner::run_swf; use crate::set_logger; @@ -49,6 +50,7 @@ impl Test { &self, before_start: impl FnOnce(Arc>) -> Result<()>, before_end: impl FnOnce(Arc>) -> Result<()>, + environment: &impl Environment, ) -> std::result::Result<(), libtest_mimic::Failed> { set_logger(); let injector = if self.input_path.is_file() { @@ -61,17 +63,27 @@ impl Test { } else { None }; - let output = run_swf(self, injector, socket_events, before_start, before_end)?; + let output = run_swf( + self, + injector, + socket_events, + before_start, + before_end, + environment, + )?; self.compare_output(&output)?; Ok(()) } - pub fn should_run(&self, check_renderer: bool) -> bool { + pub fn should_run(&self, check_renderer: bool, environment: &impl Environment) -> bool { if self.options.ignore { return false; } self.options.required_features.can_run() - && self.options.player_options.can_run(check_renderer) + && self + .options + .player_options + .can_run(check_renderer, environment) } pub fn compare_output(&self, actual_output: &str) -> Result<()> { diff --git a/tests/tests/environment.rs b/tests/tests/environment.rs new file mode 100644 index 000000000..7cf4a367a --- /dev/null +++ b/tests/tests/environment.rs @@ -0,0 +1,123 @@ +use image::RgbaImage; +use ruffle_test_framework::environment::{Environment, RenderBackend}; + +#[cfg(feature = "imgtests")] +use ruffle_test_framework::options::RenderOptions; + +#[cfg(feature = "imgtests")] +use ruffle_render_wgpu::{ + backend::{request_adapter_and_device, WgpuRenderBackend}, + descriptors::Descriptors, + target::TextureTarget, + wgpu, +}; + +#[cfg(feature = "imgtests")] +use {std::sync::Arc, std::sync::OnceLock}; + +pub struct NativeEnvironment; + +impl NativeEnvironment { + #[cfg(feature = "imgtests")] + fn descriptors(&self) -> Option<&Arc> { + WGPU.get_or_init(build_wgpu_descriptors).as_ref() + } +} + +impl Environment for NativeEnvironment { + #[cfg(feature = "imgtests")] + fn is_render_supported(&self, requirements: &RenderOptions) -> bool { + if let Some(descriptors) = self.descriptors() { + let adapter_info = descriptors.adapter.get_info(); + let is_warp = + cfg!(windows) && adapter_info.vendor == 5140 && adapter_info.device == 140; + + !requirements.exclude_warp || !is_warp + } else { + false + } + } + + #[cfg(feature = "imgtests")] + fn create_renderer(&self, width: u32, height: u32) -> Option> { + if let Some(descriptors) = self.descriptors() { + let target = TextureTarget::new(&descriptors.device, (width, height)).expect( + "WGPU Texture Target creation must not fail, everything was checked ahead of time", + ); + + Some(Box::new( + WgpuRenderBackend::new(descriptors.clone(), target) + .expect("WGPU Render backend creation must not fail, everything was checked ahead of time"), + )) + } else { + None + } + } + + #[cfg(not(feature = "imgtests"))] + fn name(&self) -> String { + std::env::consts::OS.to_string() + } + + #[cfg(feature = "imgtests")] + fn name(&self) -> String { + if let Some(descriptors) = self.descriptors() { + let adapter_info = descriptors.adapter.get_info(); + format!("{}-{:?}", std::env::consts::OS, adapter_info.backend) + } else { + std::env::consts::OS.to_string() + } + } + + #[cfg(not(feature = "imgtests"))] + fn capture_renderer(&self, _backend: &mut Box) -> RgbaImage { + panic!("Cannot capture renderer as imgtests are not enabled") + } + + #[cfg(feature = "imgtests")] + fn capture_renderer(&self, backend: &mut Box) -> RgbaImage { + let renderer = backend + .downcast_mut::>() + .unwrap(); + + renderer.capture_frame().expect("Failed to capture image") + } +} + +#[cfg(feature = "imgtests")] +static WGPU: OnceLock>> = OnceLock::new(); + +/* + It can be expensive to construct WGPU, much less Descriptors, so we put it off as long as we can + and share it across tests in the same process. + + Remember: + `cargo test` will run all tests in the same process. + `cargo nextest run` will create a different process per test. + + For `cargo test` it's relatively okay if we spend the time to construct descriptors once, + but for `cargo nextest run` it's a big cost per test if it's not going to use it. +*/ + +#[cfg(feature = "imgtests")] +fn create_wgpu_device() -> Option<(wgpu::Instance, wgpu::Adapter, wgpu::Device, wgpu::Queue)> { + let instance = wgpu::Instance::new(Default::default()); + futures::executor::block_on(request_adapter_and_device( + wgpu::Backends::all(), + &instance, + None, + Default::default(), + None, + )) + .ok() + .map(|(adapter, device, queue)| (instance, adapter, device, queue)) +} + +#[cfg(feature = "imgtests")] +fn build_wgpu_descriptors() -> Option> { + if let Some((instance, adapter, device, queue)) = create_wgpu_device() { + Some(Arc::new(Descriptors::new(instance, adapter, device, queue))) + } else { + None + } +} diff --git a/tests/tests/external_interface/tests.rs b/tests/tests/external_interface/tests.rs index 19f17e7d5..ac430e210 100644 --- a/tests/tests/external_interface/tests.rs +++ b/tests/tests/external_interface/tests.rs @@ -1,12 +1,15 @@ use crate::external_interface::ExternalInterfaceTestProvider; use ruffle_core::external::Value as ExternalValue; +use ruffle_test_framework::environment::Environment; use ruffle_test_framework::options::TestOptions; use ruffle_test_framework::set_logger; use ruffle_test_framework::test::Test; use std::collections::BTreeMap; use std::path::Path; -pub fn external_interface_avm1() -> Result<(), libtest_mimic::Failed> { +pub fn external_interface_avm1( + environment: &impl Environment, +) -> Result<(), libtest_mimic::Failed> { set_logger(); Test::from_options( TestOptions { @@ -59,10 +62,13 @@ pub fn external_interface_avm1() -> Result<(), libtest_mimic::Failed> { )); Ok(()) }, + environment, ) } -pub fn external_interface_avm2() -> Result<(), libtest_mimic::Failed> { +pub fn external_interface_avm2( + environment: &impl Environment, +) -> Result<(), libtest_mimic::Failed> { set_logger(); Test::from_options( TestOptions { @@ -106,5 +112,6 @@ pub fn external_interface_avm2() -> Result<(), libtest_mimic::Failed> { )); Ok(()) }, + environment, ) } diff --git a/tests/tests/regression_tests.rs b/tests/tests/regression_tests.rs index 72a08312a..ebbd29a35 100644 --- a/tests/tests/regression_tests.rs +++ b/tests/tests/regression_tests.rs @@ -2,6 +2,7 @@ //! //! Trace output can be compared with correct output from the official Flash Player. +use crate::environment::NativeEnvironment; use crate::external_interface::tests::{external_interface_avm1, external_interface_avm2}; use crate::shared_object::{shared_object_avm1, shared_object_avm2, shared_object_self_ref_avm1}; use anyhow::Context; @@ -11,6 +12,7 @@ use ruffle_test_framework::test::Test; use std::panic::{catch_unwind, resume_unwind}; use std::path::Path; +mod environment; mod external_interface; mod shared_object; @@ -55,9 +57,9 @@ fn main() { let test = Test::from_options_file(file.path(), name.clone()) .with_context(|| format!("Couldn't create test {name}")) .unwrap(); - let ignore = !test.should_run(!args.list); + let ignore = !test.should_run(!args.list, &NativeEnvironment); let mut trial = Trial::test(test.name.to_string(), move || { - let unwind_result = catch_unwind(|| test.run(|_| Ok(()), |_| Ok(()))); + let unwind_result = catch_unwind(|| test.run(|_| Ok(()), |_| Ok(()), &NativeEnvironment)); if test.options.known_failure { match unwind_result { Ok(Ok(())) => Err( @@ -83,20 +85,21 @@ fn main() { .collect(); // Manual tests here, since #[test] doesn't work once we use our own test harness - tests.push(Trial::test("shared_object_avm1", shared_object_avm1)); - tests.push(Trial::test( - "shared_object_self_ref_avm1", - shared_object_self_ref_avm1, - )); - tests.push(Trial::test("shared_object_avm2", shared_object_avm2)); - tests.push(Trial::test( - "external_interface_avm1", - external_interface_avm1, - )); - tests.push(Trial::test( - "external_interface_avm2", - external_interface_avm2, - )); + tests.push(Trial::test("shared_object_avm1", || { + shared_object_avm1(&NativeEnvironment) + })); + tests.push(Trial::test("shared_object_self_ref_avm1", || { + shared_object_self_ref_avm1(&NativeEnvironment) + })); + tests.push(Trial::test("shared_object_avm2", || { + shared_object_avm2(&NativeEnvironment) + })); + tests.push(Trial::test("external_interface_avm1", || { + external_interface_avm1(&NativeEnvironment) + })); + tests.push(Trial::test("external_interface_avm2", || { + external_interface_avm2(&NativeEnvironment) + })); tests.sort_unstable_by(|a, b| a.name().cmp(b.name())); diff --git a/tests/tests/shared_object/mod.rs b/tests/tests/shared_object/mod.rs index c85dac20c..6d66bb96b 100644 --- a/tests/tests/shared_object/mod.rs +++ b/tests/tests/shared_object/mod.rs @@ -1,10 +1,11 @@ use ruffle_core::backend::storage::{MemoryStorageBackend, StorageBackend}; +use ruffle_test_framework::environment::Environment; use ruffle_test_framework::options::TestOptions; use ruffle_test_framework::set_logger; use ruffle_test_framework::test::Test; use std::path::Path; -pub fn shared_object_avm1() -> Result<(), libtest_mimic::Failed> { +pub fn shared_object_avm1(environment: &impl Environment) -> Result<(), libtest_mimic::Failed> { set_logger(); // Test SharedObject persistence. Run an SWF that saves data // to a shared object twice and verify that the data is saved. @@ -29,6 +30,7 @@ pub fn shared_object_avm1() -> Result<(), libtest_mimic::Failed> { std::mem::swap(player.storage_mut(), &mut memory_storage_backend); Ok(()) }, + environment, )?; // Verify that the flash cookie matches the expected one @@ -58,12 +60,15 @@ pub fn shared_object_avm1() -> Result<(), libtest_mimic::Failed> { Ok(()) }, |_| Ok(()), + environment, )?; Ok(()) } -pub fn shared_object_self_ref_avm1() -> Result<(), libtest_mimic::Failed> { +pub fn shared_object_self_ref_avm1( + environment: &impl Environment, +) -> Result<(), libtest_mimic::Failed> { set_logger(); // Test SharedObject persistence. Run an SWF that saves data // to a shared object twice and verify that the data is saved. @@ -88,6 +93,7 @@ pub fn shared_object_self_ref_avm1() -> Result<(), libtest_mimic::Failed> { std::mem::swap(player.storage_mut(), &mut memory_storage_backend); Ok(()) }, + environment, )?; // Verify that the flash cookie matches the expected one @@ -117,12 +123,13 @@ pub fn shared_object_self_ref_avm1() -> Result<(), libtest_mimic::Failed> { Ok(()) }, |_| Ok(()), + environment, )?; Ok(()) } -pub fn shared_object_avm2() -> Result<(), libtest_mimic::Failed> { +pub fn shared_object_avm2(environment: &impl Environment) -> Result<(), libtest_mimic::Failed> { set_logger(); // Test SharedObject persistence. Run an SWF that saves data // to a shared object twice and verify that the data is saved. @@ -147,6 +154,7 @@ pub fn shared_object_avm2() -> Result<(), libtest_mimic::Failed> { std::mem::swap(player.storage_mut(), &mut memory_storage_backend); Ok(()) }, + environment, )?; // Verify that the flash cookie matches the expected one @@ -176,6 +184,7 @@ pub fn shared_object_avm2() -> Result<(), libtest_mimic::Failed> { Ok(()) }, |_player| Ok(()), + environment, )?; Ok(())