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}