use std::io::{Read, Write};
use std::net::{SocketAddr, TcpStream};
use foundation_core::valtron::valtron_test;
use foundation_deployment_platform::docker::ContainerGroup;
use foundation_deployment_platform::docker_container;
fn assert_redis_pong(addr: SocketAddr) {
let mut stream = TcpStream::connect(addr)
.expect("container should be accepting connections while the body runs");
stream.write_all(b"PING\r\n").expect("PING should write");
let mut buf = [0u8; 7];
stream.read_exact(&mut buf).expect("PONG should read back");
assert_eq!(&buf, b"+PONG\r\n", "Redis should answer PING with +PONG");
}
#[docker_container(
image = "redis:7-alpine",
as = "cache",
port = 6379,
env = [("REDIS_ARGS", "--appendonly no")],
wait_stdout = "Ready to accept connections",
wait_port = 6379,
wait_timeout = 60,
memory = "256m",
stop_timeout = 5
)]
#[valtron_test]
fn docker_container_macro_serves_traffic_while_body_runs(containers: ContainerGroup) {
let cache = containers
.container("cache")
.expect("the `as = \"cache\"` container should be in the group");
let addr = cache
.address(6379)
.expect("Docker should have assigned a host port for 6379");
assert_ne!(addr.port(), 6379, "the host port should be Docker-assigned, not the container port");
assert_redis_pong(addr);
}
#[docker_container(
{
image = "redis:7-alpine",
as = "first",
port = 6379,
wait_stdout = "Ready to accept connections",
stop_timeout = 5
},
{
image = "redis:7-alpine",
as = "second",
port = 6379,
wait_stdout = "Ready to accept connections",
stop_timeout = 5
}
)]
#[valtron_test]
fn docker_container_macro_starts_multiple_containers(containers: ContainerGroup) {
assert_eq!(containers.len(), 2, "both declared containers should be in the group");
let first = containers.container("first").expect("`first` should be in the group");
let second = containers.container("second").expect("`second` should be in the group");
let first_addr = first.address(6379).expect("first should have a host port");
let second_addr = second.address(6379).expect("second should have a host port");
assert_ne!(
first_addr, second_addr,
"each container should get its own Docker-assigned host port"
);
assert_redis_pong(first_addr);
assert_redis_pong(second_addr);
assert_eq!(
containers.get(0).and_then(|h| h.address(6379)),
Some(first_addr),
"the first block's container starts first"
);
}
#[docker_container(
image = "redis:7-alpine",
as = "cache",
port = 6379,
wait_stdout = "Ready to accept connections",
required = true,
stop_timeout = 5
)]
async fn redis_body_async(containers: ContainerGroup) {
let addr = containers
.container("cache")
.and_then(|h| h.address(6379))
.expect("cache should be addressable");
assert_redis_pong(addr);
}
#[valtron_test]
fn docker_container_macro_supports_async_functions() {
foundation_core::valtron::block_on_future(redis_body_async());
}