Skip to content

Commit b5c8b61

Browse files
ivanvsDDtKey
andauthored
feat: add Valkey module (#252)
Co-authored-by: Artem Medvedev <i@ddtkey.com>
1 parent 4e58c1f commit b5c8b61

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ solr = []
5252
surrealdb = []
5353
trufflesuite_ganachecli = []
5454
victoria_metrics = []
55+
valkey = []
5556
zookeeper = []
5657
cockroach_db = []
5758
kwok = []

src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ pub mod surrealdb;
148148
#[cfg_attr(docsrs, doc(cfg(feature = "trufflesuite_ganachecli")))]
149149
/// **Trufflesuite Ganache CLI** (etherium simulator) testcontainer
150150
pub mod trufflesuite_ganachecli;
151+
#[cfg(feature = "valkey")]
152+
#[cfg_attr(docsrs, doc(cfg(feature = "valkey")))]
153+
/// **Valkey** (in memory nosql database) testcontainer
154+
pub mod valkey;
151155
#[cfg(feature = "victoria_metrics")]
152156
#[cfg_attr(docsrs, doc(cfg(feature = "victoria_metrics")))]
153157
/// **VictoriaMetrics** (monitoring and time series metrics database) testcontainer

src/valkey/mod.rs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
use testcontainers::{
2+
core::{ContainerPort, WaitFor},
3+
Image,
4+
};
5+
6+
const NAME: &str = "valkey/valkey";
7+
const TAG: &str = "8.0.1-alpine";
8+
9+
/// Default port (6379) on which Valkey is exposed
10+
pub const VALKEY_PORT: ContainerPort = ContainerPort::Tcp(6379);
11+
12+
/// Module to work with [`Valkey`] inside of tests.
13+
/// Valkey is a high-performance data structure server that primarily serves key/value workloads.
14+
///
15+
/// Starts an instance of Valkey based on the official [`Valkey docker image`].
16+
///
17+
/// By default, Valkey is exposed on Port 6379 ([`VALKEY_PORT`]), just like Redis, and has no access control.
18+
/// Currently, for communication with Valkey we can still use redis library.
19+
///
20+
/// # Example
21+
/// ```
22+
/// use redis::Commands;
23+
/// use testcontainers_modules::{
24+
/// testcontainers::runners::SyncRunner,
25+
/// valkey::{Valkey, VALKEY_PORT},
26+
/// };
27+
///
28+
/// let valkey_instance = Valkey::default().start().unwrap();
29+
/// let host_ip = valkey_instance.get_host().unwrap();
30+
/// let host_port = valkey_instance.get_host_port_ipv4(VALKEY_PORT).unwrap();
31+
///
32+
/// let url = format!("redis://{host_ip}:{host_port}");
33+
/// let client = redis::Client::open(url.as_ref()).unwrap();
34+
/// let mut con = client.get_connection().unwrap();
35+
///
36+
/// con.set::<_, _, ()>("my_key", 42).unwrap();
37+
/// let result: i64 = con.get("my_key").unwrap();
38+
/// ```
39+
///
40+
/// [`Valkey`]: https://valkey.io/
41+
/// [`Valeky docker image`]: https://hub.docker.com/r/valkey/valkey
42+
/// [`VALKEY_PORT`]: super::VALKEY_PORT
43+
#[derive(Debug, Default, Clone)]
44+
pub struct Valkey {
45+
/// (remove if there is another variable)
46+
/// Field is included to prevent this struct to be a unit struct.
47+
/// This allows extending functionality (and thus further variables) without breaking changes
48+
_priv: (),
49+
}
50+
51+
impl Image for Valkey {
52+
fn name(&self) -> &str {
53+
NAME
54+
}
55+
56+
fn tag(&self) -> &str {
57+
TAG
58+
}
59+
60+
fn ready_conditions(&self) -> Vec<WaitFor> {
61+
vec![WaitFor::message_on_stdout("Ready to accept connections")]
62+
}
63+
}
64+
65+
#[cfg(test)]
66+
mod tests {
67+
use redis::Commands;
68+
69+
use crate::{testcontainers::runners::SyncRunner, valkey::Valkey};
70+
71+
#[test]
72+
fn valkey_fetch_an_integer() -> Result<(), Box<dyn std::error::Error + 'static>> {
73+
let _ = pretty_env_logger::try_init();
74+
let node = Valkey::default().start()?;
75+
let host_ip = node.get_host()?;
76+
let host_port = node.get_host_port_ipv4(6379)?;
77+
let url = format!("redis://{host_ip}:{host_port}");
78+
79+
let client = redis::Client::open(url.as_ref()).unwrap();
80+
let mut con = client.get_connection().unwrap();
81+
82+
con.set::<_, _, ()>("my_key", 42).unwrap();
83+
let result: i64 = con.get("my_key").unwrap();
84+
assert_eq!(42, result);
85+
Ok(())
86+
}
87+
}

0 commit comments

Comments
 (0)