ソースを参照

Add server tests.

Jing Yang 5 年 前
コミット
a6e8a88c3b
3 ファイル変更135 行追加0 行削除
  1. 35 0
      src/junk_server.rs
  2. 3 0
      src/lib.rs
  3. 97 0
      src/server.rs

+ 35 - 0
src/junk_server.rs

@@ -0,0 +1,35 @@
+use crate::{server::RpcHandler, ReplyMessage, RequestMessage, Server};
+use std::sync::Arc;
+use bytes::BytesMut;
+
+pub struct EchoRpcHandler {}
+
+impl RpcHandler for EchoRpcHandler {
+    fn call(&self, request: RequestMessage) -> ReplyMessage {
+        let mut reply = BytesMut::from(request.as_ref());
+        reply.reverse();
+        reply.freeze()
+    }
+}
+
+pub struct AbortingRpcHandler {}
+
+impl RpcHandler for AbortingRpcHandler {
+    fn call(&self, _data: RequestMessage) -> ReplyMessage {
+        panic!("Aborting rpc...")
+    }
+}
+
+pub fn make_server() -> Arc<Server> {
+    let mut server = Server::make_server("test-server".to_string());
+    server
+        .register_rpc_handler("echo".to_string(), Box::new(EchoRpcHandler {}))
+        .expect("Registering the first RPC handler should not fail.");
+    server
+        .register_rpc_handler(
+            "aborting".to_string(),
+            Box::new(AbortingRpcHandler {}),
+        )
+        .expect("Registering the second RPC handler should not fail.");
+    Arc::new(server)
+}

+ 3 - 0
src/lib.rs

@@ -28,3 +28,6 @@ type ReplyMessage = bytes::Bytes;
 
 type ServerIdentifier = String;
 type ClientIdentifier = String;
+
+#[cfg(test)]
+mod junk_server;

+ 97 - 0
src/server.rs

@@ -108,3 +108,100 @@ impl Server {
         }
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::junk_server::{EchoRpcHandler, make_server};
+
+    #[test]
+    fn test_register_rpc_handler() -> Result<()> {
+        let server = make_server();
+
+        assert_eq!(2, server.state.lock().unwrap().rpc_handlers.len());
+        Ok(())
+    }
+
+    #[test]
+    fn test_register_rpc_handler_failure() -> Result<()> {
+        let mut server = make_server();
+        let server = std::sync::Arc::get_mut(&mut server).unwrap();
+
+        let result = server.register_rpc_handler(
+            "echo".to_string(),
+            Box::new(EchoRpcHandler {}),
+        );
+
+        assert!(result.is_err());
+        assert_eq!(2, server.state.lock().unwrap().rpc_handlers.len());
+        Ok(())
+    }
+
+    #[test]
+    fn test_serve_rpc() -> Result<()> {
+        let server = make_server();
+
+        let reply = server.dispatch(
+            "echo".to_string(),
+            RequestMessage::from_static(&[0x08, 0x07]),
+        );
+        let result = futures::executor::block_on(reply)?;
+
+        assert_eq!(ReplyMessage::from_static(&[0x07, 0x08]), result);
+        Ok(())
+    }
+
+    #[test]
+    fn test_rpc_not_found() -> Result<()> {
+        let server = make_server();
+
+        let reply = server.dispatch("acorn".to_string(), RequestMessage::new());
+        match futures::executor::block_on(reply) {
+            Ok(_) => panic!("acorn service is not registered."),
+            Err(e) => assert_eq!(e.kind(), std::io::ErrorKind::InvalidInput),
+        }
+        Ok(())
+    }
+
+    #[test]
+    fn test_rpc_error() -> Result<()> {
+        let server = make_server();
+
+        let reply = futures::executor::block_on(
+            server.dispatch("aborting".to_string(), RequestMessage::new()),
+        );
+
+        assert_eq!(
+            reply
+                .err()
+                .expect("Aborting RPC should return error.")
+                .kind(),
+            std::io::ErrorKind::ConnectionReset,
+        );
+
+        Ok(())
+    }
+
+    #[test]
+    fn test_server_survives_3_rpc_errors() -> Result<()> {
+        let server = make_server();
+
+        // TODO(ditsing): server hangs after the 4th RPC error.
+        for _ in 0..3 {
+            let server_clone = server.clone();
+            let _ = futures::executor::block_on(
+                server_clone.dispatch("aborting".to_string(), RequestMessage::new()),
+            );
+        }
+
+        let reply = server.dispatch(
+            "echo".to_string(),
+            RequestMessage::from_static(&[0x08, 0x07]),
+        );
+        let result = futures::executor::block_on(reply)?;
+
+        assert_eq!(ReplyMessage::from_static(&[0x07, 0x08]), result);
+
+        Ok(())
+    }
+}