WDT_DEPS = $(RUNTEST_DEPS) \
stamp/cargo-wdt.debug
-AT_WDT_RUN = $(NAILING_CARGO_JUST_RUN) $(abspath $<) $(basename $(notdir $@))
+AT_WDT_RUN = $(NAILING_CARGO_JUST_RUN) $(abspath $<)
+
+AT_RUN = $(AT_WDT_RUN) $(basename $(notdir $@))
+WDT_RUN = $(AT_WDT_RUN) wdriver --test=$(basename $(notdir $@))
stamp/at-%.check: $(AT_DEPS)
- $(AT_WDT_RUN)
+ $(AT_RUN)
$(stamp)
stamp/wdt-%.check: $(WDT_DEPS)
- $(AT_WDT_RUN)
+ $(WDT_RUN)
$(stamp)
stamp/wdt-%.lcheck: $(WDT_DEPS)
- $(AT_WDT_RUN) --as-if=lwdt-$* --layout=Landscape
+ $(WDT_RUN) --as-if=lwdt-$* --layout=Landscape
$(stamp)
#---------- deployment ----------
#[structopt(flatten)]
pub tests: WantedTestsOpt,
+
+ #[structopt(long="--test")]
+ test_name: Option<String>,
}
#[derive(Debug)]
// ==================== principal actual setup code ====================
+pub type EarlyArgPredicate<'f> = &'f mut dyn FnMut(&OsStr) -> bool;
+
#[throws(AE)]
-pub fn reinvoke_via_bwrap(_opts: &Opts, current_exe: &str) -> Void {
+pub fn reinvoke_via_bwrap(_opts: &Opts, current_exe: &str,
+ early: EarlyArgPredicate<'_>) -> Void {
debug!("running bwrap");
let mut bcmd = Command::new("bwrap");
--dev-bind / / \
--tmpfs /tmp \
--die-with-parent".split(" "))
- .arg(current_exe)
- .arg("--no-bwrap")
- .args(env::args_os().skip(1));
+ .arg(current_exe);
+
+ let (early, late) = {
+ let mut still_early = true;
+ env::args_os().skip(1)
+ .partition::<Vec<_>,_>(|s| {
+ still_early &= early(&s);
+ still_early
+ })
+ };
+ bcmd.args(early);
+ bcmd.arg("--no-bwrap");
+ bcmd.args(late);
std::io::stdout().flush().context("flush stdout")?;
let e: AE = bcmd.exec().into();
if let Some(as_if) = &opts.as_if {
current_exe = as_if;
+ } else if let Some(test_name) = &opts.test_name {
+ current_exe = test_name;
}
let start_dir = getcwd()
// ==================== core entrypoint, for wdriver too ====================
#[throws(AE)]
-pub fn setup_core<O>(module_paths: &[&str]) ->
+pub fn setup_core<O>(module_paths: &[&str], early_args: EarlyArgPredicate) ->
(O, cleanup_notify::Handle, Instance, SetupCore)
where O: StructOpt + AsRef<Opts>
{
.to_owned();
if !opts.no_bwrap {
- reinvoke_via_bwrap(&opts, ¤t_exe)
+ reinvoke_via_bwrap(&opts, ¤t_exe, early_args)
.context("reinvoke via bwrap")?;
}
#[throws(AE)]
fn main() {
{
- let (opts, _cln, instance, mut su) = setup_core(&[module_path!()])?;
+ let (opts, _cln, instance, mut su) = setup_core(
+ &[module_path!()],
+ &mut |_|false
+ )?;
let spec = su.ds.game_spec_data()?;
let [alice, bob]: [Player; 2] = su.ds.setup_static_users(
default(),
pub use index_vec;
pub use lazy_init;
pub use lazy_static;
+pub use inventory;
pub use itertools;
pub use libc;
pub use log;
pub use std::convert::{Infallible, TryFrom, TryInto};
pub use std::env;
pub use std::error::Error;
+pub use std::ffi::OsStr;
pub use std::fmt::Formatter;
pub use std::fmt::Write as _;
pub use std::fmt::{self, Debug, Display};
structopt = "0.3"
strum = { version = "0.20", features = ['derive'] }
-[lib]
-name = "otter_webdriver_tests"
-path = "../wdriver.rs"
+[[bin]]
+name = "wdriver"
+path = "wdriver.rs"
+++ /dev/null
-.
\ No newline at end of file
+++ /dev/null
-.
\ No newline at end of file
#[throws(AE)]
pub fn setup(exe_module_path: &str) -> (Setup, Instance) {
let (opts, cln, instance, core) =
- apitest::setup_core(&[exe_module_path, "otter_webdriver_tests"])?;
+ apitest::setup_core(
+ &[exe_module_path, "otter_webdriver_tests"],
+ &mut |s: &OsStr| s.to_str().unwrap().starts_with("--test=")
+ )?;
prepare_xserver(&cln, &core.ds).always_context("setup X server")?;
f(usual)?;
info!("ok");
}
+
+// ==================== portmanteau binary ====================
+
+pub struct PortmanteauMember {
+ path: &'static str,
+ f: fn() -> Result<(), AE>,
+}
+inventory::collect!(PortmanteauMember);
+
+macro_rules! portmanteau_has {
+ ($path:literal, $mod:ident) => {
+ #[path = $path] mod $mod;
+ inventory::submit!(PortmanteauMember { path: $path, f: $mod::main });
+ }
+}
+
+#[throws(AE)]
+fn main(){
+ let arg = 'arg: loop {
+ for (ai, s) in env::args().enumerate() {
+ let plausible = |s: &str| s.starts_with("wdt-");
+
+ break 'arg if ai == 0 {
+ let s = s.rsplitn(2,'/').next().unwrap();
+ if ! plausible(s) { continue }
+ s
+ } else {
+ let s = s.strip_prefix("--test=")
+ .expect("found non-long-option looking for --test=wdt-*");
+ if ! plausible(s) {
+ panic!("found non --no-bwrap --wdt-* option looking for --wdt-*");
+ }
+ s
+ }.to_owned();
+ }
+ panic!("ran out of options looking for --test=wdt-*");
+ };
+
+ let f = inventory::iter::<PortmanteauMember>.into_iter()
+ .find_map(|pm| {
+ let n = pm.path.strip_suffix(".rs").unwrap();
+ if n == arg { Some(pm.f) } else { None }
+ })
+ .expect("unrecognosed wdt-* portanteau member");
+
+ f()?;
+}
+
+portmanteau_has!("wdt-altergame.rs", wdt_altergame);
+portmanteau_has!("wdt-hand.rs", wdt_hand);
+portmanteau_has!("wdt-simple.rs", wdt_simple);
// SPDX-License-Identifier: AGPL-3.0-or-later
// There is NO WARRANTY.
-use otter_webdriver_tests::*;
+use crate::*;
use otter::spec::LinkKind;
}
#[throws(AE)]
-fn main() { as_usual(tests, module_path!())? }
+pub fn main() { as_usual(tests, module_path!())? }
// SPDX-License-Identifier: AGPL-3.0-or-later
// There is NO WARRANTY.
-use otter_webdriver_tests::*;
+use crate::*;
struct Ctx {
su: Setup,
}
#[throws(AE)]
-fn main() { as_usual(tests, module_path!())? }
+pub fn main() { as_usual(tests, module_path!())? }
// SPDX-License-Identifier: AGPL-3.0-or-later
// There is NO WARRANTY.
-use otter_webdriver_tests::*;
+use crate::*;
struct Ctx {
su: Setup,
}
#[throws(AE)]
-fn main() { as_usual(tests, module_path!())? }
+pub fn main() { as_usual(tests, module_path!())? }