it: Add runner and common tests

Still needs some work, but the idea should be clear.

Signed-off-by: John Nunley <dev@notgull.net>
This commit is contained in:
John Nunley
2024-03-03 21:54:23 -08:00
parent b3333b47e1
commit 25fab64f6e
8 changed files with 121 additions and 12 deletions

View File

@@ -264,7 +264,9 @@ name = "window"
resolver = "2"
members = [
"dpi",
"it/common-tests",
"it/gui-test",
"it/gui-test-runner",
"run-wasm",
]
@@ -279,3 +281,4 @@ async-io = "2.3.1"
gui-test = { path = "it/gui-test" }
mint = "0.5.6"
serde = { version = "1", features = ["serde_derive"] }
winit = { path = "." }

View File

@@ -0,0 +1,12 @@
[package]
name = "common-tests"
version = "0.1.0"
rust-version.workspace = true
repository.workspace = true
license.workspace = true
edition.workspace = true
[dependencies]
gui-test.workspace = true
macro_rules_attribute = "0.2.0"
winit.workspace = true

View File

@@ -0,0 +1,21 @@
//! Run the test.
use gui_test::{test, Harness};
use macro_rules_attribute::apply;
use winit::event_loop::EventLoop;
#[apply(test)]
fn initialize(harness: &mut Harness) {
let _test = harness.test("startup/shutdown");
let evl = EventLoop::new().unwrap();
evl.run(|_event, elwt| {
elwt.exit();
})
.unwrap();
}
gui_test::main! {
gui_test::remote::handler()
}

View File

@@ -0,0 +1,9 @@
[package]
name = "gui-test-runner"
version = "0.1.0"
rust-version.workspace = true
repository.workspace = true
license.workspace = true
edition.workspace = true
[dependencies]

View File

@@ -0,0 +1,59 @@
//! Runner for the `gui-test` system.
use std::env;
use std::process::{Command, Stdio};
fn main() {
let mut args = env::args();
// Get the test crate name.
let test_crate = args.nth(1).unwrap();
// Get the target.
let target_tag = args.next().unwrap();
// Split the target into the target and the tag.
let (target, tag) = {
let mut split = target_tag.splitn(1, ':');
let target = split.next().unwrap();
let tag = split.next();
(target, tag)
};
// Get the current target.
let current_target = current_target();
// For now, we only support building for the current target.
assert_eq!(target, current_target);
assert!(tag.is_none());
// Just run the crate.
if !Command::new("cargo")
.args(["run", "-p", &test_crate])
.output()
.unwrap()
.status
.success()
{
panic!("test failed");
}
}
/// Get the current target.
fn current_target() -> String {
let output = Command::new("rustc")
.arg("-vV")
.stdout(Stdio::piped())
.output()
.unwrap();
// Look for the line that starts with "host".
let stdout = String::from_utf8(output.stdout).unwrap();
for line in stdout.lines() {
if let Some(host) = line.strip_prefix("host: ") {
return host.to_string();
}
}
panic!("failed to find host: line in rustc output")
}

View File

@@ -1,7 +1,7 @@
//! A testing framework that can be run remotely.
pub mod stream;
pub mod remote;
pub mod stream;
pub mod user;
use serde::{Deserialize, Serialize};
@@ -23,7 +23,7 @@ pub use inventory as __inventory;
macro_rules! main {
($handler:expr) => {
fn main() {
$crate::__entry($harness)
$crate::__entry($handler)
}
};
}
@@ -62,7 +62,7 @@ pub struct __TestStart {
impl __TestStart {
/// Create a new test start.
#[doc(hidden)]
pub fn __new(name: &'static str, func: fn(&mut Harness)) -> Self {
pub const fn __new(name: &'static str, func: fn(&mut Harness)) -> Self {
Self { name, func }
}
}
@@ -290,6 +290,12 @@ pub trait TestHandler {
fn handle_test(&mut self, event: TestEvent);
}
impl<T: TestHandler + ?Sized> TestHandler for Box<T> {
fn handle_test(&mut self, event: TestEvent) {
(**self).handle_test(event)
}
}
/// An event produced by the test harness.
#[derive(Debug, Serialize, Deserialize)]
pub struct TestEvent {

View File

@@ -1,8 +1,8 @@
//! Create a test handler that can be run remotely.
use crate::TestHandler;
use crate::stream::WriteHandler;
use crate::user::UserHandler;
use crate::TestHandler;
use std::env;
use std::net::TcpStream;
@@ -11,16 +11,17 @@ use std::net::TcpStream;
pub fn handler() -> Box<dyn TestHandler + Send + 'static> {
// If GUI_TEST_UNIX_STREAM is enabled, use that as a Unix stream.
#[cfg(unix)]
if let Some(stream_path) = env::var_os("GUI_TEST_UNIX_STREAM")
.filter(|s| !s.is_empty()) {
let stream = std::os::unix::net::UnixStream::connect(stream_path).expect("unable to connect to gui-test handler");
if let Some(stream_path) = env::var_os("GUI_TEST_UNIX_STREAM").filter(|s| !s.is_empty()) {
let stream = std::os::unix::net::UnixStream::connect(stream_path)
.expect("unable to connect to gui-test handler");
return Box::new(WriteHandler::new(stream));
}
// If GUI_TEST_TCP_STREAM is enabled, use that as a TCP stream.
if let Some(tcp_ip) = env::var("GUI_TEST_TCP_STREAM")
.ok()
.filter(|s| !s.is_empty()) {
.filter(|s| !s.is_empty())
{
let stream = TcpStream::connect(tcp_ip).unwrap();
return Box::new(WriteHandler::new(stream));
}

View File

@@ -1,5 +1,5 @@
//! Write events to an output stream.
//!
//!
//! The format is as follows:
//! - First 8 bytes: big-endian length of payload.
//! - Next {len} bytes: JSON payload to deserialize from.
@@ -16,9 +16,7 @@ pub struct WriteHandler<W> {
impl<W: Write> WriteHandler<W> {
/// Create a new write handler.
pub fn new(writer: W) -> Self {
Self {
writer
}
Self { writer }
}
}