Skip to content

Commit

Permalink
Implement integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ndelvalle committed Jun 17, 2024
1 parent 82918f3 commit a3a92ea
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 4 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@ name: CI
jobs:
check:
name: Check

runs-on: ubuntu-latest

services:
redis:
image: redis:latest
ports:
- 6379:6379

steps:
- name: Checkout sources
uses: actions/checkout@v2
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ strum = "0.26.2"
strum_macros = "0.26.2"

[dev-dependencies]
redis = "0.25.4"
tokio = { version = "1.35.0", features = ["full", "test-util"] }
4 changes: 2 additions & 2 deletions src/commands/get.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ impl Executable for Get {

match value {
Some(value) => Ok(Frame::Bulk(value.clone())),
None => Ok(Frame::Null),
None => Ok(Frame::NullBulkString),
}
}
}
Expand Down Expand Up @@ -83,6 +83,6 @@ mod tests {

let res = cmd.exec(store.clone()).unwrap();

assert_eq!(res, Frame::Null);
assert_eq!(res, Frame::NullBulkString);
}
}
23 changes: 22 additions & 1 deletion src/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,13 @@ pub enum Frame {
Error(String),
Integer(i64),
Bulk(Bytes),
Null,
Array(Vec<Frame>),
// Whereas RESP3 has a dedicated data type for null values, RESP2 has no such type. Instead,
// due to historical reasons, the representation of null values in RESP2 is via predetermined
// forms of the bulk strings and arrays types.
Null,
NullBulkString,
NullArray,
}

// Protocol specification: https://redis.io/docs/reference/protocol-spec/
Expand Down Expand Up @@ -173,6 +178,20 @@ impl Frame {
bytes.extend_from_slice(CRLF);
bytes
}
Frame::NullBulkString => {
let mut bytes = Vec::with_capacity(4);
bytes.push(u8::from(DataType::BulkString));
bytes.extend_from_slice("-1".as_bytes());
bytes.extend_from_slice(CRLF);
bytes
}
Frame::NullArray => {
let mut bytes = Vec::with_capacity(4);
bytes.push(u8::from(DataType::Array));
bytes.extend_from_slice("-1".as_bytes());
bytes.extend_from_slice(CRLF);
bytes
}
Frame::Array(arr) => {
let length_str = arr.len().to_string();
let mut bytes = Vec::with_capacity(1 + length_str.len() + CRLF.len());
Expand Down Expand Up @@ -204,6 +223,8 @@ impl fmt::Display for Frame {
Frame::Integer(i) => write!(f, ":{}", i),
Frame::Bulk(bytes) => write!(f, "${}", String::from_utf8_lossy(bytes)),
Frame::Null => write!(f, "$-1"),
Frame::NullBulkString => write!(f, "$-1"),
Frame::NullArray => write!(f, "*-1"),
Frame::Array(arr) => {
write!(f, "*{}\r\n", arr.len())?;
for frame in arr {
Expand Down
2 changes: 1 addition & 1 deletion src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::connection::Connection;
use crate::store::Store;
use crate::Error;

const PORT: u16 = 6379;
const PORT: u16 = 6378;

pub async fn run() -> Result<(), Error> {
let subscriber = tracing_subscriber::FmtSubscriber::new();
Expand Down
47 changes: 47 additions & 0 deletions tests/integration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use redis::Connection;
use redis::RedisError;
use redis::Value;
use rustdis::server::run;
use tokio::time::{sleep, Duration};

async fn connect() -> Result<(Connection, Connection), RedisError> {
tokio::spawn(async { run().await });
// Give the server some time to start.
sleep(Duration::from_millis(100)).await;

let our_client = redis::Client::open("redis://127.0.0.1:6378/")?;
let our_connection = our_client.get_connection()?;

let thir_client = redis::Client::open("redis://127.0.0.1:6379/")?;
let their_connection = thir_client.get_connection()?;

Ok((our_connection, their_connection))
}

#[tokio::test]
async fn test_set_and_get() {
let (mut our_connection, mut their_connection) = connect().await.unwrap();

let pipeline = redis::pipe()
.cmd("SET")
.arg("key_1")
.arg(1)
.cmd("SET")
.arg("key_2")
.arg("Argentina")
.cmd("GET")
.arg("key_1")
.cmd("GET")
.arg("key_2")
.cmd("GET")
.arg("nonexistentkey")
.clone();

let our_response: (Value, Value, Value, Value, Value) =
pipeline.clone().query(&mut our_connection).unwrap();

let their_response: (Value, Value, Value, Value, Value) =
pipeline.clone().query(&mut their_connection).unwrap();

assert_eq!(our_response, their_response)
}

0 comments on commit a3a92ea

Please sign in to comment.