chiark / gitweb /
wip instances etc.
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 28 Dec 2020 22:44:44 +0000 (22:44 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 28 Dec 2020 22:44:44 +0000 (22:44 +0000)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Cargo.lock.example
src/commands.rs
src/mgmtchannel.rs
wdriver.rs
wdriver/Cargo.toml
wdriver/wdt-simple.rs

index 06efa28753c76a8c6169104aeab8756320b0fdca..1630ec4cdf66c18c4654107fcf9725d92172cb2f 100644 (file)
@@ -1579,6 +1579,7 @@ dependencies = [
  "env_logger",
  "fehler",
  "humantime",
+ "if_chain",
  "libc",
  "log 0.4.11",
  "nix 0.19.1",
index e71d895036a3d38283158f127a93efde9c8f768f..8216001120e912a572d4b428dd97acfbc75f3e36 100644 (file)
@@ -70,6 +70,7 @@ pub enum MgmtResponse {
 pub enum MgmtGameInstruction {
   Noop,
   Info,
+  /// For testing, mostly.
   Synch,
   SetTableSize(Pos),
   SetTableColour(ColourSpec),
index 038697295d74d7b09b8d2d53dde1f25596227002..efa0b772e193bff19ff0c9d7d825fc3280d02d3d 100644 (file)
@@ -17,6 +17,13 @@ pub struct MgmtChannel {
   write: BufWriter<Box<dyn Write>>,
 }
 
+impl Debug for MgmtChannel{ 
+  #[throws(fmt::Error)]
+  fn fmt(&self, f: &mut fmt::Formatter) {
+    f.write_str("MgmtChannel{...}")?
+  }
+}
+
 impl MgmtChannel {
   #[throws(AE)]
   pub fn connect(socket_path: &str) -> MgmtChannel {
index ff117ea81aa5f493dc0d310c89b7eb15f4c760fd..ed9658db16e63876a0346b8bf1769df19ccf0653 100644 (file)
@@ -8,6 +8,7 @@
 pub use anyhow::{anyhow, Context};
 pub use boolinator::Boolinator;
 pub use fehler::{throw, throws};
+pub use if_chain::if_chain;
 pub use log::{debug, error, info, trace, warn};
 pub use log::{log, log_enabled};
 pub use nix::unistd::LinkatFlags;
@@ -37,10 +38,12 @@ pub use std::process::{Command, Stdio};
 pub use std::thread::sleep;
 pub use std::time;
 
+pub use otter::commands::{MgmtCommand, MgmtResponse};
+pub use otter::commands::{MgmtGameInstruction, MgmtGameResponse};
+pub use otter::commands::{MgmtGameUpdateMode};
+pub use otter::global::InstanceName;
 pub use otter::mgmtchannel::MgmtChannel;
 
-use otter::config::DAEMON_STARTUP_REPORT;
-
 pub type T4d = t4::WebDriver;
 pub type WDE = t4::error::WebDriverError;
 
@@ -49,6 +52,9 @@ pub type AE = anyhow::Error;
 
 pub const URL : &str = "http://localhost:8000";
 
+use otter::config::DAEMON_STARTUP_REPORT;
+
+const TABLE : &str = "server::dummy";
 const CONFIG : &str = "server-config.toml";
 
 #[derive(Copy,Clone,Debug,Eq,PartialEq,Ord,PartialOrd)]
@@ -111,6 +117,7 @@ type WindowState = Option<String>;
 #[derive(Debug)]
 pub struct Setup {
   pub ds: DirSubst,
+  pub mgmt_conn: MgmtChannel,
   driver: T4d,
   current_window: WindowState,
   screenshot_count: ScreenShotCount,
@@ -126,6 +133,8 @@ pub struct DirSubst {
   pub src: String,
 }
 
+pub struct Instance(InstanceName);
+
 #[derive(Clone,Debug)]
 pub struct RawSubst(HashMap<String,String>);
 
@@ -571,13 +580,20 @@ impl DirSubst {
 }
 
 #[throws(AE)]
-pub fn prepare_game(ds: &DirSubst) {
-  ds.otter(&ds.ss(
+pub fn prepare_game(ds: &DirSubst, table: &str) -> InstanceName {
+  let subst = ds.also(&[("table", &table)]);
+  ds.otter(&subst.ss(
     "--account server:                                  \
      reset                                              \
      --reset-table @specs@/test.table.toml              \
-                   server::dummy @specs@/demo.game.toml \
+                   @table@ @specs@/demo.game.toml \
     ")?).context("reset table")?;
+
+  let instance : InstanceName = table.parse()
+    .with_context(|| table.to_owned())
+    .context("parse table name")?;
+
+  instance
 }
 
 #[throws(AE)]
@@ -618,6 +634,7 @@ fn prepare_thirtyfour() -> (T4d, ScreenShotCount, Vec<String>) {
 #[derive(Debug)]
 pub struct Window {
   name: String,
+  instance: InstanceName,
 }
 
 pub struct WindowGuard<'g> {
@@ -641,7 +658,8 @@ fn check_window_name_sanity(name: &str) -> &str {
 
 impl Setup {
   #[throws(AE)]
-  pub fn new_window<'s>(&'s mut self, name: &str) -> Window {
+  pub fn new_window<'s>(&'s mut self, instance: &Instance, name: &str)
+                        -> Window {
     let name = check_window_name_sanity(name)?;
     let window = (||{
 
@@ -665,7 +683,10 @@ impl Setup {
       ))
         .context("execute script to create window")?;
 
-      Ok::<_,AE>(Window { name: name.to_owned() })
+      Ok::<_,AE>(Window {
+        name: name.to_owned(),
+        instance: instance.0.clone(),
+      })
     })()
       .with_context(|| name.to_owned())
       .context("create window")?;
@@ -714,6 +735,28 @@ fn screenshot(driver: &T4d, count: &mut ScreenShotCount, slug: &str) {
     .context("take screenshot")?;
 }
 
+impl<'g> WindowGuard<'g> {
+  #[throws(AE)]
+  pub fn synch(&mut self) {
+    let cmd = MgmtCommand::AlterGame {
+      game: self.w.instance.clone(),
+      how: MgmtGameUpdateMode::Online,
+      insns: vec![ MgmtGameInstruction::Synch ],
+    };
+    let gen = if_chain!{
+      let resp = self.su.mgmt_conn.cmd(&cmd)?;
+      if let MgmtResponse::AlterGame {
+        error: None,
+        ref responses
+      } = resp;
+      if let [MgmtGameResponse::Synch(gen)] = responses[..];
+      then { gen }
+      else { throw!(anyhow!("unexpected resp to synch {:?}", resp)) }
+    };
+    dbg!(gen);
+  }
+}
+
 impl Drop for FinalInfoCollection {
   fn drop(&mut self) {
     nix::unistd::linkat(None, "Xvfb_screen0",
@@ -732,7 +775,10 @@ impl Drop for Setup {
         // here because we have &mut self.  If there is only one
         // Setup, there can be noone else with a Window with an
         // identical name to be interfered with by us.
-        let w = Window { name: name.clone() };
+        let w = Window {
+          name: name.clone(),
+          instance: TABLE.parse().context(TABLE)?,
+        };
         self.w(&w)?.screenshot("final")
           .context(name)
           .context("final screenshot")
@@ -746,7 +792,7 @@ impl Drop for Setup {
 }
 
 #[throws(AE)]
-pub fn setup(exe_module_path: &str) -> Setup {
+pub fn setup(exe_module_path: &str) -> (Setup, Instance) {
   env_logger::Builder::new()
     .format_timestamp_micros()
     .format_level(true)
@@ -776,8 +822,12 @@ pub fn setup(exe_module_path: &str) -> Setup {
   let ds = prepare_tmpdir(&opts, &current_exe)?;
 
   prepare_xserver(&cln, &ds).always_context("setup X server")?;
-  prepare_gameserver(&cln, &ds).always_context("setup game server")?;
-  prepare_game(&ds).context("setup game")?;
+
+  let mgmt_conn =
+    prepare_gameserver(&cln, &ds).always_context("setup game server")?;
+
+  let instance_name =
+    prepare_game(&ds, "TABLE").context("setup game")?;
 
   let final_hook = FinalInfoCollection;
 
@@ -785,21 +835,25 @@ pub fn setup(exe_module_path: &str) -> Setup {
   let (driver, screenshot_count, windows_squirreled) =
     prepare_thirtyfour().always_context("prepare web session")?;
 
-  Setup {
+  (Setup {
     ds,
+    mgmt_conn,
     driver,
     screenshot_count,
     current_window: None,
     windows_squirreled,
-    final_hook
-  }
+    final_hook,
+  },
+   Instance(
+     instance_name
+   ))
 }
 
 impl Setup {
   #[throws(AE)]
-  pub fn setup_static_users(&mut self) -> Vec<Window> {
+  pub fn setup_static_users(&mut self, instance: &Instance) -> Vec<Window> {
     #[throws(AE)]
-    fn mk(su: &mut Setup, u: StaticUser) -> Window {
+    fn mk(su: &mut Setup, instance: &Instance, u: StaticUser) -> Window {
       let nick: &str = u.into();
       let token = u.get_str("Token").expect("StaticUser missing Token");
       let subst = su.ds.also([("nick",  nick),
@@ -809,14 +863,14 @@ impl Setup {
                        --account server:@nick@       \
                        --fixed-token @token@         \
                        join-game server::dummy")?)?;
-      let w = su.new_window(nick)?;
+      let w = su.new_window(instance, nick)?;
       let url = subst.subst("@url@/?@token@")?;
       su.w(&w)?.get(url)?;
       su.w(&w)?.screenshot("initial")?;
       w
     }
     StaticUser::iter().map(
-      |u| mk(self, u)
+      |u| mk(self, instance, u)
         .with_context(|| format!("{:?}", u))
         .context("make static user")
     )
index d849678eb3ea08564c6b28b5aa476bca9b44a465..56ff362a3c9e196e0c59fd83957ac2bfe45cb09a 100644 (file)
@@ -18,6 +18,7 @@ boolinator = "2"
 env_logger = "0.8"
 fehler = "1"
 humantime = "2"
+if_chain = "1"
 log = "0.4"
 libc = "0.2"
 nix = "0.19"
index 60d6bfaac0d6e8e6b2133107497db49ba10a1f0c..232ba3086bd7375adeb87b111d5573690a1fcdb8 100644 (file)
@@ -6,9 +6,9 @@ use otter_webdriver_tests::*;
 
 #[throws(AE)]
 fn main(){
-  let mut su = setup(module_path!()).always_context("setup")?;
+  let (mut su, inst) = setup(module_path!()).always_context("setup")?;
   let [alice, bob] : [Window; 2] =
-    su.setup_static_users()?.try_into().unwrap();
+    su.setup_static_users(&inst)?.try_into().unwrap();
   debug!("ok {:?} {:?}", alice, bob);
 
 //  alice.synch()?;