add initial client tests (#25)
This commit is contained in:
@@ -187,6 +187,11 @@ pub struct Subscriber {
|
|||||||
|
|
||||||
impl Subscriber {
|
impl Subscriber {
|
||||||
|
|
||||||
|
/// get the list of subscribed channels
|
||||||
|
pub fn get_subscribed(&self) -> &HashSet<String> {
|
||||||
|
&self.subscribed_channels
|
||||||
|
}
|
||||||
|
|
||||||
/// await for next message published on the subscribed channels
|
/// await for next message published on the subscribed channels
|
||||||
pub async fn next_message(&mut self) -> crate::Result<Message> {
|
pub async fn next_message(&mut self) -> crate::Result<Message> {
|
||||||
match self.receive_message().await {
|
match self.receive_message().await {
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ pub async fn run(listener: TcpListener, shutdown: impl Future) -> crate::Result<
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Extract the `shutdown_complete` receiver and transmitter
|
// Extract the `shutdown_complete` receiver and transmitter
|
||||||
// ` explicitly drop shutdown_transmitter`. This is important, as the
|
// explicitly drop `shutdown_transmitter`. This is important, as the
|
||||||
// `.await` below would otherwise never complete.
|
// `.await` below would otherwise never complete.
|
||||||
let Listener { mut shutdown_complete_rx, shutdown_complete_tx, .. } = server;
|
let Listener { mut shutdown_complete_rx, shutdown_complete_tx, .. } = server;
|
||||||
|
|
||||||
|
|||||||
90
tests/client.rs
Normal file
90
tests/client.rs
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
use std::net::SocketAddr;
|
||||||
|
use tokio::net::TcpListener;
|
||||||
|
use tokio::task::JoinHandle;
|
||||||
|
use mini_redis::{client, server};
|
||||||
|
|
||||||
|
/// A basic "hello world" style test. A server instance is started in a
|
||||||
|
/// background task. A client instance is then established and set and get
|
||||||
|
/// commands are sent to the server. The response is then evaluated
|
||||||
|
#[tokio::test]
|
||||||
|
async fn key_value_get_set() {
|
||||||
|
let (addr, _) = start_server().await;
|
||||||
|
|
||||||
|
let mut client = client::connect(addr).await.unwrap();
|
||||||
|
client.set("hello", "world".into()).await.unwrap();
|
||||||
|
|
||||||
|
let value = client.get("hello").await.unwrap().unwrap();
|
||||||
|
assert_eq!(b"world", &value[..])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// similar to the "hello world" style test, But this time
|
||||||
|
/// a single channel subscription will be tested instead
|
||||||
|
#[tokio::test]
|
||||||
|
async fn receive_message_subscribed_channel() {
|
||||||
|
let (addr, _) = start_server().await;
|
||||||
|
|
||||||
|
let client = client::connect(addr.clone()).await.unwrap();
|
||||||
|
let mut subscriber = client.subscribe(vec!["hello".into()]).await.unwrap();
|
||||||
|
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let mut client = client::connect(addr).await.unwrap();
|
||||||
|
client.publish("hello", "world".into()).await.unwrap()
|
||||||
|
});
|
||||||
|
|
||||||
|
let message = subscriber.next_message().await.unwrap();
|
||||||
|
assert_eq!("hello", &message.channel);
|
||||||
|
assert_eq!(b"world", &message.content[..])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// test that a client gets messages from multiple subscribed channels
|
||||||
|
#[tokio::test]
|
||||||
|
async fn receive_message_multiple_subscribed_channels() {
|
||||||
|
let (addr, _) = start_server().await;
|
||||||
|
|
||||||
|
let client = client::connect(addr.clone()).await.unwrap();
|
||||||
|
let mut subscriber = client.subscribe(vec!["hello".into(), "world".into()]).await.unwrap();
|
||||||
|
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let mut client = client::connect(addr).await.unwrap();
|
||||||
|
client.publish("hello", "world".into()).await.unwrap()
|
||||||
|
});
|
||||||
|
|
||||||
|
let message1 = subscriber.next_message().await.unwrap();
|
||||||
|
assert_eq!("hello", &message1.channel);
|
||||||
|
assert_eq!(b"world", &message1.content[..]);
|
||||||
|
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let mut client = client::connect(addr).await.unwrap();
|
||||||
|
client.publish("world", "howdy?".into()).await.unwrap()
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
let message2 = subscriber.next_message().await.unwrap();
|
||||||
|
assert_eq!("world", &message2.channel);
|
||||||
|
assert_eq!(b"howdy?", &message2.content[..])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// test that a client accurately removes its own subscribed chanel list
|
||||||
|
/// when unbscribing to all subscribed channels by submitting an empty vec
|
||||||
|
#[tokio::test]
|
||||||
|
async fn unsubscribes_from_channels() {
|
||||||
|
let (addr, _) = start_server().await;
|
||||||
|
|
||||||
|
let client = client::connect(addr.clone()).await.unwrap();
|
||||||
|
let mut subscriber = client.subscribe(vec!["hello".into(), "world".into()]).await.unwrap();
|
||||||
|
|
||||||
|
subscriber.unsubscribe(vec![]).await.unwrap();
|
||||||
|
assert_eq!(subscriber.get_subscribed().len(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn start_server() -> (SocketAddr, JoinHandle<mini_redis::Result<()>>) {
|
||||||
|
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||||
|
let addr = listener.local_addr().unwrap();
|
||||||
|
|
||||||
|
let handle = tokio::spawn(async move {
|
||||||
|
server::run(listener, tokio::signal::ctrl_c()).await
|
||||||
|
});
|
||||||
|
|
||||||
|
(addr, handle)
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user