chiark / gitweb /
wdt, at: Use vpid mapping everywhere, rather than hardcoded
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 4 Apr 2021 11:53:08 +0000 (12:53 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 4 Apr 2021 18:16:25 +0000 (19:16 +0100)
Races can affect the vpid layout!  This fixes flakiness in the tests.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/prelude.rs
wdriver/wdriver.rs
wdriver/wdt-hand.rs
wdriver/wdt-simple.rs

index 933de8a171112376a99f391ca30d2634468dffb6..5766b4531267dfc998b7825cb413f5b93859bbe7 100644 (file)
@@ -95,7 +95,7 @@ pub use strum::{IntoEnumIterator, IntoStaticStr};
 pub use thiserror::Error;
 pub use url::Url;
 pub use vecdeque_stableix::Deque as StableIndexVecDeque;
-pub use void::{Void, ResultVoidExt, ResultVoidErrExt};
+pub use void::{unreachable, Void, ResultVoidExt, ResultVoidErrExt};
 
 use nix::time::ClockId;
 pub const CLOCK_REALTIME : ClockId = ClockId::CLOCK_REALTIME ;
index 34c09cf85cd03ed38fbea8e91379e9cf189bad02..0ad43dc22130f852be0b47bff294f63692a63567 100644 (file)
@@ -59,6 +59,12 @@ pub struct Window {
   pub instance: InstanceName,
 }
 
+#[derive(Debug,Clone,Eq,PartialEq,Ord,PartialOrd,Hash)]
+pub struct Vpid(pub String);
+impl Display for Vpid {
+  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(&self.0) }
+}
+
 impl Window {
   pub fn table(&self) -> String { self.instance.to_string() }
 }
@@ -204,11 +210,42 @@ impl Debug for WindowGuard<'_> {
 
 impl<'g> WindowGuard<'g> {
   #[throws(AE)]
-  pub fn find_piece(&'g self, pieceid: &'g str) -> PieceElement<'g> {
-    let id = format!("use{}", pieceid);
-    let elem = self.su.driver.find_element(By::Id(&id))?;
+  pub fn piece_vpid(&'g self, some_pieceid: &'_ str) -> Vpid {
+    if some_pieceid.contains('.') { return Vpid(some_pieceid.to_owned()) }
+    let (l, r) = some_pieceid.split_once('v').unwrap();
+    let s = format!(r#"{{ "idx":{}, "version":{} }}"#, l,r); // cheesy!
+    let kd: slotmap::KeyData = serde_json::from_str(&s).unwrap();
+    let piece: PieceId = kd.into();
+    let resp = self.su.mgmt_conn().cmd(&MC::AlterGame {
+      game: TABLE.parse().unwrap(),
+      how: MgmtGameUpdateMode::Online,
+      insns: vec![ MgmtGameInstruction::PieceIdLookupFwd {
+        piece,
+        player: self.w.player,
+      } ],
+    })?;
+    let vpid = if_chain!{
+      if let MgmtResponse::AlterGame { error: None, responses } = &resp;
+      if let [MgmtGameResponse::VisiblePieceId(vpid)] = responses.as_slice();
+      then { vpid }
+      else { unreachable(Err::<Void,_>(&resp).unwrap()) }
+    };
+    Vpid(vpid.unwrap().to_string())
+  }
+
+  #[throws(AE)]
+  pub fn vpidelem(&'g self, prefix: &'_ str, some_pieceid: &'_ str) -> String {
+    prefix.to_string() + &self.piece_vpid(some_pieceid)?.0
+  }
+
+  #[throws(AE)]
+  pub fn find_piece(&'g self, pieceid: &'_ str) -> PieceElement<'g> {
+    let pieceid = self.piece_vpid(pieceid)?;
+    let elemid = format!("use{}", &pieceid);
+    let elem = self.su.driver.find_element(By::Id(&elemid))?;
     PieceElement {
-      pieceid, elem,
+      elem,
+      pieceid: pieceid.clone(),
       w: self,
     }
   }
@@ -230,7 +267,7 @@ impl<'g> WindowGuard<'g> {
     let held = self.execute_script(&format!(r##"
         let pc = pieces['{}'];
         return pc.held;
-                       "##, &pc))?;
+                       "##, &self.piece_vpid(pc)?))?;
     let held = held.value();
     dbg!(held);
     match held {
@@ -330,7 +367,7 @@ pub type WebCoord = i32;
 pub type WebPos = (WebCoord, WebCoord);
 
 pub struct PieceElement<'g> {
-  pieceid: &'g str,
+  pieceid: Vpid,
   w: &'g WindowGuard<'g>,
   elem: t4::WebElement<'g>,
 }
@@ -613,7 +650,7 @@ impl<'a> t4::action_chain::ActionChain<'a> {
   }
 
   #[throws(AE)]
-  fn move_pc<'g>(self, w: &'g WindowGuard, pc: &str) -> Self {
+  fn move_pc<'g>(self, w: &'g WindowGuard, pc: &'_ str) -> Self {
     (||{
       let p = w.find_piece(pc).context("find")?;
       let pos = p.posw().context("get pos")?;
index f312096501c40e0eb45d971f61519927aa6abe2c..008e5aa61e1d33e06a6a7c092dc71427c042d7bd 100644 (file)
@@ -12,8 +12,8 @@ struct Ctx {
 deref_to_field!{Ctx, Setup, su}
 usual_wanted_tests!{Ctx, su}
 
-const HAND: &str = "6.1";
-const PAWN: &str = "7.1";
+const HAND: &str = "6v1";
+const PAWN: &str = "7v1";
 const ALICE: &str = "1#1";
 
 #[throws(AE)]
@@ -39,7 +39,7 @@ impl Ctx {
       w.synch()?;
 
       let dasharray = player.map(player_dasharray).transpose()?;
-      let euse = w.find_element(By::Id(&format!("piece{}", pc)))?;
+      let euse = w.find_element(By::Id(&w.vpidelem("piece", pc)?))?;
       let epath = euse.find_element(By::Tag("path"))?;
       let attr = epath.get_attribute("stroke-dasharray")?;
 
index 35e37c5acf6a4c8bad2677336d47e20c9c63c627..8c8f487ca30516d2ebbf0e438affc3fc0bce8848 100644 (file)
@@ -21,8 +21,8 @@ impl Ctx {
     let alice_p1g = {
       let mut w = su.w(&self.alice)?;
       w.synch()?;
-      let p1 = w.find_piece("1.1")?;
-      let p2 = w.find_piece("2.1")?;
+      let p1 = w.find_piece("1v1")?;
+      let p2 = w.find_piece("2v1")?;
       let p1g_old = p1.posg()?;
       let (p2x,p2y) = p2.posw()?;
 
@@ -44,19 +44,19 @@ impl Ctx {
     {
       let mut w = su.w(&self.bob)?;
       w.synch()?;
-      let p1 = w.find_piece("1.1")?;
+      let p1 = w.find_piece("1v1")?;
       assert_eq!(p1.posg()?, alice_p1g);
     }
   }
 
   #[throws(AE)]
   fn rotate(&mut self) -> &'static str {
-    let pc = "4.1";
+    let pc = "4v1";
     let su = &mut self.su;
 
     let chk = |w: &WindowGuard<'_>| {
       let transform = format!("rotate(-90)");
-      let pd = w.find_element(By::Id(&format!("piece{}",pc)))?;
+      let pd = w.find_element(By::Id(&w.vpidelem("piece",pc)?))?;
       assert_eq!(pd.get_attribute("transform")?, Some(transform));
       Ok::<_,AE>(())
     };
@@ -160,11 +160,11 @@ impl Ctx {
 
   #[throws(AE)]
   fn conflict(&mut self) {
-    let pc = "1.1";
+    let pc = "1v1";
     let su = &mut self.su;
 
     {
-      let pc = "4.1";
+      let pc = "4v1";
       let w = su.w(&self.alice)?;
       w.action_chain()
         .move_pc(&w, pc)?