fmt (#34)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
use mini_redis::{client, server};
|
||||
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
|
||||
@@ -42,7 +42,10 @@ 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();
|
||||
let mut subscriber = client
|
||||
.subscribe(vec!["hello".into(), "world".into()])
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
tokio::spawn(async move {
|
||||
let mut client = client::connect(addr).await.unwrap();
|
||||
@@ -58,7 +61,6 @@ async fn receive_message_multiple_subscribed_channels() {
|
||||
client.publish("world", "howdy?".into()).await.unwrap()
|
||||
});
|
||||
|
||||
|
||||
let message2 = subscriber.next_message().await.unwrap().unwrap();
|
||||
assert_eq!("world", &message2.channel);
|
||||
assert_eq!(b"howdy?", &message2.content[..])
|
||||
@@ -71,7 +73,10 @@ 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();
|
||||
let mut subscriber = client
|
||||
.subscribe(vec!["hello".into(), "world".into()])
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
subscriber.unsubscribe(&[]).await.unwrap();
|
||||
assert_eq!(subscriber.get_subscribed().len(), 0);
|
||||
@@ -81,10 +86,7 @@ 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
|
||||
});
|
||||
let handle = tokio::spawn(async move { server::run(listener, tokio::signal::ctrl_c()).await });
|
||||
|
||||
(addr, handle)
|
||||
}
|
||||
|
||||
|
||||
187
tests/server.rs
187
tests/server.rs
@@ -1,6 +1,6 @@
|
||||
use mini_redis::server;
|
||||
|
||||
use std::net::{SocketAddr, Shutdown};
|
||||
use std::net::{Shutdown, SocketAddr};
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
use tokio::net::{TcpListener, TcpStream};
|
||||
use tokio::time::{self, Duration};
|
||||
@@ -17,7 +17,10 @@ async fn key_value_get_set() {
|
||||
let mut stream = TcpStream::connect(addr).await.unwrap();
|
||||
|
||||
// Get a key, data is missing
|
||||
stream.write_all(b"*2\r\n$3\r\nGET\r\n$5\r\nhello\r\n").await.unwrap();
|
||||
stream
|
||||
.write_all(b"*2\r\n$3\r\nGET\r\n$5\r\nhello\r\n")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Read nil response
|
||||
let mut response = [0; 5];
|
||||
@@ -25,7 +28,10 @@ async fn key_value_get_set() {
|
||||
assert_eq!(b"$-1\r\n", &response);
|
||||
|
||||
// Set a key
|
||||
stream.write_all(b"*3\r\n$3\r\nSET\r\n$5\r\nhello\r\n$5\r\nworld\r\n").await.unwrap();
|
||||
stream
|
||||
.write_all(b"*3\r\n$3\r\nSET\r\n$5\r\nhello\r\n$5\r\nworld\r\n")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Read OK
|
||||
let mut response = [0; 5];
|
||||
@@ -33,7 +39,10 @@ async fn key_value_get_set() {
|
||||
assert_eq!(b"+OK\r\n", &response);
|
||||
|
||||
// Get the key, data is present
|
||||
stream.write_all(b"*2\r\n$3\r\nGET\r\n$5\r\nhello\r\n").await.unwrap();
|
||||
stream
|
||||
.write_all(b"*2\r\n$3\r\nGET\r\n$5\r\nhello\r\n")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Shutdown the write half
|
||||
stream.shutdown(Shutdown::Write).unwrap();
|
||||
@@ -65,8 +74,13 @@ async fn key_value_timeout() {
|
||||
let mut stream = TcpStream::connect(addr).await.unwrap();
|
||||
|
||||
// Set a key
|
||||
stream.write_all(b"*5\r\n$3\r\nSET\r\n$5\r\nhello\r\n$5\r\nworld\r\n\
|
||||
+EX\r\n:1\r\n").await.unwrap();
|
||||
stream
|
||||
.write_all(
|
||||
b"*5\r\n$3\r\nSET\r\n$5\r\nhello\r\n$5\r\nworld\r\n\
|
||||
+EX\r\n:1\r\n",
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let mut response = [0; 5];
|
||||
|
||||
@@ -76,7 +90,10 @@ async fn key_value_timeout() {
|
||||
assert_eq!(b"+OK\r\n", &response);
|
||||
|
||||
// Get the key, data is present
|
||||
stream.write_all(b"*2\r\n$3\r\nGET\r\n$5\r\nhello\r\n").await.unwrap();
|
||||
stream
|
||||
.write_all(b"*2\r\n$3\r\nGET\r\n$5\r\nhello\r\n")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Read "world" response
|
||||
let mut response = [0; 11];
|
||||
@@ -89,7 +106,10 @@ async fn key_value_timeout() {
|
||||
time::advance(Duration::from_secs(1)).await;
|
||||
|
||||
// Get a key, data is missing
|
||||
stream.write_all(b"*2\r\n$3\r\nGET\r\n$5\r\nhello\r\n").await.unwrap();
|
||||
stream
|
||||
.write_all(b"*2\r\n$3\r\nGET\r\n$5\r\nhello\r\n")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Read nil response
|
||||
let mut response = [0; 5];
|
||||
@@ -107,7 +127,10 @@ async fn pub_sub() {
|
||||
|
||||
// Publish a message, there are no subscribers yet so the server will
|
||||
// return `0`.
|
||||
publisher.write_all(b"*3\r\n$7\r\nPUBLISH\r\n$5\r\nhello\r\n$5\r\nworld\r\n").await.unwrap();
|
||||
publisher
|
||||
.write_all(b"*3\r\n$7\r\nPUBLISH\r\n$5\r\nhello\r\n$5\r\nworld\r\n")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let mut response = [0; 4];
|
||||
publisher.read_exact(&mut response).await.unwrap();
|
||||
@@ -116,15 +139,23 @@ async fn pub_sub() {
|
||||
// Create a subscriber. This subscriber will only subscribe to the `hello`
|
||||
// channel.
|
||||
let mut sub1 = TcpStream::connect(addr).await.unwrap();
|
||||
sub1.write_all(b"*2\r\n$9\r\nSUBSCRIBE\r\n$5\r\nhello\r\n").await.unwrap();
|
||||
sub1.write_all(b"*2\r\n$9\r\nSUBSCRIBE\r\n$5\r\nhello\r\n")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Read the subscribe response
|
||||
let mut response = [0; 34];
|
||||
sub1.read_exact(&mut response).await.unwrap();
|
||||
assert_eq!(&b"*3\r\n$9\r\nsubscribe\r\n$5\r\nhello\r\n:1\r\n"[..], &response[..]);
|
||||
assert_eq!(
|
||||
&b"*3\r\n$9\r\nsubscribe\r\n$5\r\nhello\r\n:1\r\n"[..],
|
||||
&response[..]
|
||||
);
|
||||
|
||||
// Publish a message, there now is a subscriber
|
||||
publisher.write_all(b"*3\r\n$7\r\nPUBLISH\r\n$5\r\nhello\r\n$5\r\nworld\r\n").await.unwrap();
|
||||
publisher
|
||||
.write_all(b"*3\r\n$7\r\nPUBLISH\r\n$5\r\nhello\r\n$5\r\nworld\r\n")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let mut response = [0; 4];
|
||||
publisher.read_exact(&mut response).await.unwrap();
|
||||
@@ -133,31 +164,48 @@ async fn pub_sub() {
|
||||
// The first subscriber received the message
|
||||
let mut response = [0; 39];
|
||||
sub1.read_exact(&mut response).await.unwrap();
|
||||
assert_eq!(&b"*3\r\n$7\r\nmessage\r\n$5\r\nhello\r\n$5\r\nworld\r\n"[..], &response[..]);
|
||||
assert_eq!(
|
||||
&b"*3\r\n$7\r\nmessage\r\n$5\r\nhello\r\n$5\r\nworld\r\n"[..],
|
||||
&response[..]
|
||||
);
|
||||
|
||||
// Create a second subscriber
|
||||
//
|
||||
// This subscriber will be subscribed to both `hello` and `foo`
|
||||
let mut sub2 = TcpStream::connect(addr).await.unwrap();
|
||||
sub2.write_all(b"*3\r\n$9\r\nSUBSCRIBE\r\n$5\r\nhello\r\n$3\r\nfoo\r\n").await.unwrap();
|
||||
sub2.write_all(b"*3\r\n$9\r\nSUBSCRIBE\r\n$5\r\nhello\r\n$3\r\nfoo\r\n")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Read the subscribe response
|
||||
let mut response = [0; 34];
|
||||
sub2.read_exact(&mut response).await.unwrap();
|
||||
assert_eq!(&b"*3\r\n$9\r\nsubscribe\r\n$5\r\nhello\r\n:1\r\n"[..], &response[..]);
|
||||
assert_eq!(
|
||||
&b"*3\r\n$9\r\nsubscribe\r\n$5\r\nhello\r\n:1\r\n"[..],
|
||||
&response[..]
|
||||
);
|
||||
let mut response = [0; 32];
|
||||
sub2.read_exact(&mut response).await.unwrap();
|
||||
assert_eq!(&b"*3\r\n$9\r\nsubscribe\r\n$3\r\nfoo\r\n:2\r\n"[..], &response[..]);
|
||||
assert_eq!(
|
||||
&b"*3\r\n$9\r\nsubscribe\r\n$3\r\nfoo\r\n:2\r\n"[..],
|
||||
&response[..]
|
||||
);
|
||||
|
||||
// Publish another message on `hello`, there are two subscribers
|
||||
publisher.write_all(b"*3\r\n$7\r\nPUBLISH\r\n$5\r\nhello\r\n$5\r\njazzy\r\n").await.unwrap();
|
||||
publisher
|
||||
.write_all(b"*3\r\n$7\r\nPUBLISH\r\n$5\r\nhello\r\n$5\r\njazzy\r\n")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let mut response = [0; 4];
|
||||
publisher.read_exact(&mut response).await.unwrap();
|
||||
assert_eq!(b":2\r\n", &response);
|
||||
|
||||
// Publish a message on `foo`, there is only one subscriber
|
||||
publisher.write_all(b"*3\r\n$7\r\nPUBLISH\r\n$3\r\nfoo\r\n$3\r\nbar\r\n").await.unwrap();
|
||||
publisher
|
||||
.write_all(b"*3\r\n$7\r\nPUBLISH\r\n$3\r\nfoo\r\n$3\r\nbar\r\n")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let mut response = [0; 4];
|
||||
publisher.read_exact(&mut response).await.unwrap();
|
||||
@@ -166,21 +214,32 @@ async fn pub_sub() {
|
||||
// The first subscriber received the message
|
||||
let mut response = [0; 39];
|
||||
sub1.read_exact(&mut response).await.unwrap();
|
||||
assert_eq!(&b"*3\r\n$7\r\nmessage\r\n$5\r\nhello\r\n$5\r\njazzy\r\n"[..], &response[..]);
|
||||
assert_eq!(
|
||||
&b"*3\r\n$7\r\nmessage\r\n$5\r\nhello\r\n$5\r\njazzy\r\n"[..],
|
||||
&response[..]
|
||||
);
|
||||
|
||||
// The second subscriber received the message
|
||||
let mut response = [0; 39];
|
||||
sub2.read_exact(&mut response).await.unwrap();
|
||||
assert_eq!(&b"*3\r\n$7\r\nmessage\r\n$5\r\nhello\r\n$5\r\njazzy\r\n"[..], &response[..]);
|
||||
assert_eq!(
|
||||
&b"*3\r\n$7\r\nmessage\r\n$5\r\nhello\r\n$5\r\njazzy\r\n"[..],
|
||||
&response[..]
|
||||
);
|
||||
|
||||
// The first subscriber **did not** receive the second message
|
||||
let mut response = [0; 1];
|
||||
time::timeout(Duration::from_millis(100), sub1.read(&mut response)).await.unwrap_err();
|
||||
time::timeout(Duration::from_millis(100), sub1.read(&mut response))
|
||||
.await
|
||||
.unwrap_err();
|
||||
|
||||
// The second subscriber **did** receive the message
|
||||
let mut response = [0; 35];
|
||||
sub2.read_exact(&mut response).await.unwrap();
|
||||
assert_eq!(&b"*3\r\n$7\r\nmessage\r\n$3\r\nfoo\r\n$3\r\nbar\r\n"[..], &response[..]);
|
||||
assert_eq!(
|
||||
&b"*3\r\n$7\r\nmessage\r\n$3\r\nfoo\r\n$3\r\nbar\r\n"[..],
|
||||
&response[..]
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -191,34 +250,55 @@ async fn manage_subscription() {
|
||||
|
||||
// Create a subscriber
|
||||
let mut sub = TcpStream::connect(addr).await.unwrap();
|
||||
sub.write_all(b"*2\r\n$9\r\nSUBSCRIBE\r\n$5\r\nhello\r\n").await.unwrap();
|
||||
sub.write_all(b"*2\r\n$9\r\nSUBSCRIBE\r\n$5\r\nhello\r\n")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Read the subscribe response
|
||||
let mut response = [0; 34];
|
||||
sub.read_exact(&mut response).await.unwrap();
|
||||
assert_eq!(&b"*3\r\n$9\r\nsubscribe\r\n$5\r\nhello\r\n:1\r\n"[..], &response[..]);
|
||||
assert_eq!(
|
||||
&b"*3\r\n$9\r\nsubscribe\r\n$5\r\nhello\r\n:1\r\n"[..],
|
||||
&response[..]
|
||||
);
|
||||
|
||||
// Update subscription to add `foo`
|
||||
sub.write_all(b"*2\r\n$9\r\nSUBSCRIBE\r\n$3\r\nfoo\r\n").await.unwrap();
|
||||
sub.write_all(b"*2\r\n$9\r\nSUBSCRIBE\r\n$3\r\nfoo\r\n")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let mut response = [0; 32];
|
||||
sub.read_exact(&mut response).await.unwrap();
|
||||
assert_eq!(&b"*3\r\n$9\r\nsubscribe\r\n$3\r\nfoo\r\n:2\r\n"[..], &response[..]);
|
||||
assert_eq!(
|
||||
&b"*3\r\n$9\r\nsubscribe\r\n$3\r\nfoo\r\n:2\r\n"[..],
|
||||
&response[..]
|
||||
);
|
||||
|
||||
// Update subscription to remove `hello`
|
||||
sub.write_all(b"*2\r\n$11\r\nUNSUBSCRIBE\r\n$5\r\nhello\r\n").await.unwrap();
|
||||
sub.write_all(b"*2\r\n$11\r\nUNSUBSCRIBE\r\n$5\r\nhello\r\n")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let mut response = [0; 37];
|
||||
sub.read_exact(&mut response).await.unwrap();
|
||||
assert_eq!(&b"*3\r\n$11\r\nunsubscribe\r\n$5\r\nhello\r\n:1\r\n"[..], &response[..]);
|
||||
assert_eq!(
|
||||
&b"*3\r\n$11\r\nunsubscribe\r\n$5\r\nhello\r\n:1\r\n"[..],
|
||||
&response[..]
|
||||
);
|
||||
|
||||
// Publish a message to `hello` and then a message to `foo`
|
||||
publisher.write_all(b"*3\r\n$7\r\nPUBLISH\r\n$5\r\nhello\r\n$5\r\nworld\r\n").await.unwrap();
|
||||
publisher
|
||||
.write_all(b"*3\r\n$7\r\nPUBLISH\r\n$5\r\nhello\r\n$5\r\nworld\r\n")
|
||||
.await
|
||||
.unwrap();
|
||||
let mut response = [0; 4];
|
||||
publisher.read_exact(&mut response).await.unwrap();
|
||||
assert_eq!(b":0\r\n", &response);
|
||||
|
||||
publisher.write_all(b"*3\r\n$7\r\nPUBLISH\r\n$3\r\nfoo\r\n$3\r\nbar\r\n").await.unwrap();
|
||||
publisher
|
||||
.write_all(b"*3\r\n$7\r\nPUBLISH\r\n$3\r\nfoo\r\n$3\r\nbar\r\n")
|
||||
.await
|
||||
.unwrap();
|
||||
let mut response = [0; 4];
|
||||
publisher.read_exact(&mut response).await.unwrap();
|
||||
assert_eq!(b":1\r\n", &response);
|
||||
@@ -227,18 +307,28 @@ async fn manage_subscription() {
|
||||
// The second subscriber **did** receive the message
|
||||
let mut response = [0; 35];
|
||||
sub.read_exact(&mut response).await.unwrap();
|
||||
assert_eq!(&b"*3\r\n$7\r\nmessage\r\n$3\r\nfoo\r\n$3\r\nbar\r\n"[..], &response[..]);
|
||||
assert_eq!(
|
||||
&b"*3\r\n$7\r\nmessage\r\n$3\r\nfoo\r\n$3\r\nbar\r\n"[..],
|
||||
&response[..]
|
||||
);
|
||||
|
||||
// No more messages
|
||||
let mut response = [0; 1];
|
||||
time::timeout(Duration::from_millis(100), sub.read(&mut response)).await.unwrap_err();
|
||||
time::timeout(Duration::from_millis(100), sub.read(&mut response))
|
||||
.await
|
||||
.unwrap_err();
|
||||
|
||||
// Unsubscribe from all channels
|
||||
sub.write_all(b"*1\r\n$11\r\nunsubscribe\r\n").await.unwrap();
|
||||
sub.write_all(b"*1\r\n$11\r\nunsubscribe\r\n")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let mut response = [0; 35];
|
||||
sub.read_exact(&mut response).await.unwrap();
|
||||
assert_eq!(&b"*3\r\n$11\r\nunsubscribe\r\n$3\r\nfoo\r\n:0\r\n"[..], &response[..]);
|
||||
assert_eq!(
|
||||
&b"*3\r\n$11\r\nunsubscribe\r\n$3\r\nfoo\r\n:0\r\n"[..],
|
||||
&response[..]
|
||||
);
|
||||
}
|
||||
|
||||
// In this case we test that server Responds with an Error message if a client
|
||||
@@ -251,7 +341,10 @@ async fn send_error_unknown_command() {
|
||||
let mut stream = TcpStream::connect(addr).await.unwrap();
|
||||
|
||||
// Get a key, data is missing
|
||||
stream.write_all(b"*2\r\n$3\r\nFOO\r\n$5\r\nhello\r\n").await.unwrap();
|
||||
stream
|
||||
.write_all(b"*2\r\n$3\r\nFOO\r\n$5\r\nhello\r\n")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let mut response = [0; 28];
|
||||
|
||||
@@ -269,22 +362,34 @@ async fn send_error_get_set_after_subscribe() {
|
||||
let mut stream = TcpStream::connect(addr).await.unwrap();
|
||||
|
||||
// send SUBSCRIBE command
|
||||
stream.write_all(b"*2\r\n$9\r\nsubscribe\r\n$5\r\nhello\r\n").await.unwrap();
|
||||
stream
|
||||
.write_all(b"*2\r\n$9\r\nsubscribe\r\n$5\r\nhello\r\n")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let mut response = [0; 34];
|
||||
|
||||
stream.read_exact(&mut response).await.unwrap();
|
||||
|
||||
assert_eq!(&b"*3\r\n$9\r\nsubscribe\r\n$5\r\nhello\r\n:1\r\n"[..], &response[..]);
|
||||
assert_eq!(
|
||||
&b"*3\r\n$9\r\nsubscribe\r\n$5\r\nhello\r\n:1\r\n"[..],
|
||||
&response[..]
|
||||
);
|
||||
|
||||
stream.write_all(b"*3\r\n$3\r\nSET\r\n$5\r\nhello\r\n$5\r\nworld\r\n").await.unwrap();
|
||||
stream
|
||||
.write_all(b"*3\r\n$3\r\nSET\r\n$5\r\nhello\r\n$5\r\nworld\r\n")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let mut response = [0; 28];
|
||||
|
||||
stream.read_exact(&mut response).await.unwrap();
|
||||
assert_eq!(b"-ERR unknown command \'set\'\r\n", &response);
|
||||
|
||||
stream.write_all(b"*2\r\n$3\r\nGET\r\n$5\r\nhello\r\n").await.unwrap();
|
||||
stream
|
||||
.write_all(b"*2\r\n$3\r\nGET\r\n$5\r\nhello\r\n")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let mut response = [0; 28];
|
||||
|
||||
@@ -296,9 +401,7 @@ async fn start_server() -> SocketAddr {
|
||||
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
let addr = listener.local_addr().unwrap();
|
||||
|
||||
tokio::spawn(async move {
|
||||
server::run(listener, tokio::signal::ctrl_c()).await
|
||||
});
|
||||
tokio::spawn(async move { server::run(listener, tokio::signal::ctrl_c()).await });
|
||||
|
||||
addr
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user