Browse Source

Added a message for halting a node.

Matthew Carr 2 years ago
parent
commit
ab4fd2332b
2 changed files with 39 additions and 7 deletions
  1. 1 0
      crates/btnode/src/main.rs
  2. 38 7
      crates/harness/src/lib.rs

+ 1 - 0
crates/btnode/src/main.rs

@@ -376,6 +376,7 @@ fn main() {
                     error!("Failed to flush stdout {:?}", err);
                 }
             }, 
+            Message::Halt => break,
         }
     }
 }

+ 38 - 7
crates/harness/src/lib.rs

@@ -10,7 +10,10 @@ use log::{error};
 
 #[derive(Serialize, Deserialize)]
 pub enum Message {
+    /// An echo request. This should elicit an identical reply.
     Echo(String),
+    /// Orders the node to halt.
+    Halt,
 }
 
 pub struct Node {
@@ -38,14 +41,11 @@ impl Node {
                         Err(_) => break,
                     }
                 },
-                // Break if the child is dead.
+                // Break if the child is has exited.
                 Err(serde_block_tree::Error::Eof) => break,
                 Err(serde_block_tree::Error::Io(io_err)) => {
                     match io_err.kind() {
-                        std::io::ErrorKind::UnexpectedEof => {
-                            error!("The child process closed its stdout stream.");
-                            break;
-                        }
+                        std::io::ErrorKind::UnexpectedEof => break,
                         _ => error!("IO error ocurred: {:?}", io_err),
                     }
                 },
@@ -70,6 +70,30 @@ impl Node {
             }
         }
     }
+
+    pub fn halt(mut self) -> Result<(), NodeHaltError> {
+        self.send(&Message::Halt).unwrap();
+        match self.child.wait() {
+            Ok(status) => {
+                let code = status.code();
+                if code == Some(0) {
+                    Ok(())
+                }
+                else {
+                    Err(NodeHaltError::NonZeroExitCode(code))
+                }
+            },
+            Err(err) => Err(NodeHaltError::Io(err)),
+        }
+    }
+}
+
+#[derive(Debug)]
+pub enum NodeHaltError {
+    /// The node exited with a non-zero or non-existent status code.
+    NonZeroExitCode(Option<i32>),
+    /// An IO error was encountered.
+    Io(std::io::Error),
 }
 
 impl Drop for Node {
@@ -105,9 +129,16 @@ mod test {
             node.send(&Message::Echo(expected.clone())).unwrap();
             let reply = node.receive(Duration::from_millis(100)).unwrap();
             let reply_payload = match reply {
-                Message::Echo(actual) => actual,
+                Message::Echo(actual) => Some(actual),
+                _ => None,
             };
-            assert_eq!(expected, reply_payload.as_str());
+            assert_eq!(Some(expected), reply_payload);
         }
     }
+
+    #[test]
+    fn message_halt() {
+        let node = Node::new().unwrap();
+        node.halt().unwrap();
+    }
 }