Skip to content

Commit

Permalink
Add additional cluster-routing tests
Browse files Browse the repository at this point in the history
Factor out slot calculation into separate function
to facilitate easier testing
  • Loading branch information
jaymell committed Feb 21, 2023
1 parent 4963c3d commit 866eeea
Showing 1 changed file with 99 additions and 2 deletions.
101 changes: 99 additions & 2 deletions redis/src/cluster_routing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ use crate::types::Value;

pub(crate) const SLOT_SIZE: u16 = 16384;

fn slot(key: &[u8]) -> u16 {
crc16::State::<crc16::XMODEM>::calculate(key) % SLOT_SIZE
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub(crate) enum RoutingInfo {
AllNodes,
Expand Down Expand Up @@ -58,7 +62,7 @@ impl RoutingInfo {
None => key,
};

let slot = crc16::State::<crc16::XMODEM>::calculate(key) % SLOT_SIZE;
let slot = slot(key);
if is_readonly_cmd(cmd) {
RoutingInfo::ReplicaSlot(slot)
} else {
Expand Down Expand Up @@ -174,7 +178,7 @@ fn get_hashtag(key: &[u8]) -> Option<&[u8]> {

#[cfg(test)]
mod tests {
use super::{get_hashtag, RoutingInfo};
use super::{get_hashtag, slot, RoutingInfo};
use crate::{cmd, parser::parse_redis_value};

#[test]
Expand Down Expand Up @@ -257,5 +261,98 @@ mod tests {
RoutingInfo::for_routable(&cmd).unwrap(),
);
}

// Assert expected RoutingInfo explicitly:

for cmd in vec![cmd("FLUSHALL"), cmd("FLUSHDB"), cmd("SCRIPT")] {
assert_eq!(
RoutingInfo::for_routable(&cmd),
Some(RoutingInfo::AllMasters)
);
}

for cmd in vec![
cmd("ECHO"),
cmd("CONFIG"),
cmd("CLIENT"),
cmd("SLOWLOG"),
cmd("DBSIZE"),
cmd("LASTSAVE"),
cmd("PING"),
cmd("INFO"),
cmd("BGREWRITEAOF"),
cmd("BGSAVE"),
cmd("CLIENT LIST"),
cmd("SAVE"),
cmd("TIME"),
cmd("KEYS"),
] {
assert_eq!(RoutingInfo::for_routable(&cmd), Some(RoutingInfo::AllNodes));
}

for cmd in vec![
cmd("SCAN"),
cmd("CLIENT SETNAME"),
cmd("SHUTDOWN"),
cmd("SLAVEOF"),
cmd("REPLICAOF"),
cmd("SCRIPT KILL"),
cmd("MOVE"),
cmd("BITOP"),
] {
assert_eq!(RoutingInfo::for_routable(&cmd), None,);
}

for cmd in vec![
cmd("EVAL").arg(r#"redis.call("PING");"#).arg(0),
cmd("EVALSHA").arg(r#"redis.call("PING");"#).arg(0),
] {
assert_eq!(RoutingInfo::for_routable(cmd), Some(RoutingInfo::Random));
}

for (cmd, expected) in vec![
(
cmd("EVAL")
.arg(r#"redis.call("GET, KEYS[1]");"#)
.arg(1)
.arg("foo"),
Some(RoutingInfo::MasterSlot(slot(b"foo"))),
),
(
cmd("XGROUP")
.arg("CREATE")
.arg("mystream")
.arg("workers")
.arg("$")
.arg("MKSTREAM"),
Some(RoutingInfo::MasterSlot(slot(b"mystream"))),
),
(
cmd("XINFO").arg("GROUPS").arg("foo"),
Some(RoutingInfo::ReplicaSlot(slot(b"foo"))),
),
(
cmd("XREADGROUP")
.arg("GROUP")
.arg("wkrs")
.arg("consmrs")
.arg("STREAMS")
.arg("mystream"),
Some(RoutingInfo::MasterSlot(slot(b"mystream"))),
),
(
cmd("XREAD")
.arg("COUNT")
.arg("2")
.arg("STREAMS")
.arg("mystream")
.arg("writers")
.arg("0-0")
.arg("0-0"),
Some(RoutingInfo::ReplicaSlot(slot(b"mystream"))),
),
] {
assert_eq!(RoutingInfo::for_routable(cmd), expected,);
}
}
}

0 comments on commit 866eeea

Please sign in to comment.