mirror of
https://github.com/danbulant/cushy
synced 2026-06-19 14:31:04 +00:00
Trying to make Mac CI fail gracefully
This message may be repeated multiple times as I work on the CI configuration. Refs #129
This commit is contained in:
parent
5556d2ea6d
commit
d7fde0815f
5 changed files with 96 additions and 33 deletions
9
.github/workflows/rust.yml
vendored
9
.github/workflows/rust.yml
vendored
|
|
@ -45,4 +45,11 @@ jobs:
|
|||
# fixed purely by updating the rust version.
|
||||
if: matrix.version == 'stable'
|
||||
run: |
|
||||
cargo test --all-features --all-targets
|
||||
cargo test --all-features --all-targets -- --nocapture
|
||||
env:
|
||||
# When running on Mac OS CI, it's pretty common to not get an adapter
|
||||
# returned. We don't want errors specifically caused by not being able
|
||||
# to create a wgpu Adapter to cause unit test failures on CI. Long
|
||||
# term it would be nice to have a reliable way to run Mac CI with a
|
||||
# GPU adapter available.
|
||||
NO_ADAPTER: ${{ matris.os == "macos-stable" && "github-ci" || "" }}
|
||||
|
|
@ -2,35 +2,33 @@ use std::time::Duration;
|
|||
|
||||
use cushy::animation::easings::EaseInOutSine;
|
||||
use cushy::widget::MakeWidget;
|
||||
use cushy::window::VirtualRecorderError;
|
||||
use figures::units::Px;
|
||||
use figures::{Point, Size};
|
||||
|
||||
#[macro_use]
|
||||
mod shared;
|
||||
|
||||
fn ui() -> impl MakeWidget {
|
||||
"Hello World".into_button().centered()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut recorder = ui()
|
||||
.build_recorder()
|
||||
.size(Size::new(320, 240))
|
||||
.finish()
|
||||
.unwrap();
|
||||
fn main() -> Result<(), VirtualRecorderError> {
|
||||
let mut recorder = ui().build_recorder().size(Size::new(320, 240)).finish()?;
|
||||
let initial_point = Point::new(Px::new(140), Px::new(150));
|
||||
recorder.set_cursor_position(initial_point);
|
||||
recorder.set_cursor_visible(true);
|
||||
recorder.refresh().unwrap();
|
||||
recorder.refresh()?;
|
||||
let mut animation = recorder.record_animated_png(60);
|
||||
animation
|
||||
.animate_cursor_to(
|
||||
Point::new(Px::new(160), Px::new(120)),
|
||||
Duration::from_millis(250),
|
||||
EaseInOutSine,
|
||||
)
|
||||
.unwrap();
|
||||
animation.wait_for(Duration::from_millis(500)).unwrap();
|
||||
animation
|
||||
.animate_cursor_to(initial_point, Duration::from_millis(250), EaseInOutSine)
|
||||
.unwrap();
|
||||
animation.wait_for(Duration::from_millis(500)).unwrap();
|
||||
animation.write_to("examples/offscreen-apng.png").unwrap();
|
||||
animation.animate_cursor_to(
|
||||
Point::new(Px::new(160), Px::new(120)),
|
||||
Duration::from_millis(250),
|
||||
EaseInOutSine,
|
||||
)?;
|
||||
animation.wait_for(Duration::from_millis(500))?;
|
||||
animation.animate_cursor_to(initial_point, Duration::from_millis(250), EaseInOutSine)?;
|
||||
animation.wait_for(Duration::from_millis(500))?;
|
||||
animation.write_to("examples/offscreen-apng.png")
|
||||
}
|
||||
|
||||
adapter_required_test!(main);
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
use cushy::widget::MakeWidget;
|
||||
use cushy::window::VirtualRecorderError;
|
||||
use figures::Size;
|
||||
|
||||
#[macro_use]
|
||||
mod shared;
|
||||
|
||||
fn ui() -> impl MakeWidget {
|
||||
"Hello World".into_button().centered()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
fn main() -> Result<(), VirtualRecorderError> {
|
||||
// The default recorder generated solid, rgb images.
|
||||
let recorder = ui()
|
||||
.build_recorder()
|
||||
.size(Size::new(320, 240))
|
||||
.finish()
|
||||
.unwrap();
|
||||
let recorder = ui().build_recorder().size(Size::new(320, 240)).finish()?;
|
||||
recorder.image().save("examples/offscreen.png").unwrap();
|
||||
|
||||
// Creating a recorder with alpha makes the virtual window transparent.
|
||||
|
|
@ -19,12 +19,9 @@ fn main() {
|
|||
.build_recorder()
|
||||
.with_alpha()
|
||||
.size(Size::new(320, 240))
|
||||
.finish()
|
||||
.unwrap();
|
||||
.finish()?;
|
||||
recorder.image().save("examples/offscreen.png").unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn runs() {
|
||||
main();
|
||||
}
|
||||
adapter_required_test!(main);
|
||||
|
|
|
|||
39
examples/shared/mod.rs
Normal file
39
examples/shared/mod.rs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/// This macro creates a unit test that calls the named function, and
|
||||
/// potentially ignores a `NoAdapter` error.
|
||||
///
|
||||
/// # Background
|
||||
///
|
||||
/// On GitHub CI, it seems fairly common for the MacOS runners to be configured
|
||||
/// in such a way that wgpu returns no adapters from a request with the default
|
||||
/// settings. The default settings appear to imply as high of flexibility as
|
||||
/// possible, and sometimes the runners succeed in returning an adapter.
|
||||
///
|
||||
/// Because of these spurious failures, this macro checks for the environment
|
||||
/// variable `NO_ADAPTER`. If it is set to a value, a warning will be printed
|
||||
/// instead of panicking.
|
||||
#[macro_export]
|
||||
macro_rules! adapter_required_test {
|
||||
($name:ident) => {
|
||||
#[test]
|
||||
fn runs() {
|
||||
let no_adapter_setting = std::env::var("NO_ADAPTER");
|
||||
match ($name(), no_adapter_setting) {
|
||||
(Ok(()), _) => {}
|
||||
(Err(cushy::window::VirtualRecorderError::NoAdapter), Ok(no_adapter))
|
||||
if !no_adapter.is_empty() =>
|
||||
{
|
||||
let prefix = match no_adapter.as_ref() {
|
||||
"github-ci" => "::warning::",
|
||||
_ => "",
|
||||
};
|
||||
println!(
|
||||
"{prefix}Ignoring {}:{}: no graphics adapters available",
|
||||
file!(),
|
||||
stringify!($name)
|
||||
);
|
||||
}
|
||||
(Err(err), _) => unreachable!("Error testing example: {err}"),
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -3607,6 +3607,28 @@ impl From<io::Error> for VirtualRecorderError {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for VirtualRecorderError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
VirtualRecorderError::NoAdapter => {
|
||||
f.write_str("no compatible graphics adapters were found")
|
||||
}
|
||||
VirtualRecorderError::RequestDevice(err) => {
|
||||
write!(f, "error requesting graphics device: {err}")
|
||||
}
|
||||
VirtualRecorderError::TooLarge => {
|
||||
f.write_str("the rendered surface is too large for this cpu architecture")
|
||||
}
|
||||
VirtualRecorderError::MapBuffer(err) => {
|
||||
write!(f, "error reading rendered graphics data: {err}")
|
||||
}
|
||||
VirtualRecorderError::PngEncode(err) => write!(f, "error encoding png: {err}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for VirtualRecorderError {}
|
||||
|
||||
/// A unique identifier of an input device.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
||||
pub enum DeviceId {
|
||||
|
|
|
|||
Loading…
Reference in a new issue