testcontainers_modules/valkey/
mod.rs

1use testcontainers::{
2    core::{ContainerPort, WaitFor},
3    Image,
4};
5
6const NAME: &str = "valkey/valkey";
7const TAG: &str = "8.0.1-alpine";
8
9/// Default port (6379) on which Valkey is exposed
10pub 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)]
44pub 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
51impl 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)]
66mod 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}