|
| 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