Skip to content

Commit

Permalink
Add integration test support for volume mounts
Browse files Browse the repository at this point in the history
  • Loading branch information
runesoerensen committed Oct 21, 2024
1 parent a3174bc commit 6ef8a2b
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 0 deletions.
33 changes: 33 additions & 0 deletions libcnb-test/src/container_config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::{HashMap, HashSet};
use std::path::{Path, PathBuf};

/// Config used when starting a container.
///
Expand Down Expand Up @@ -31,6 +32,7 @@ pub struct ContainerConfig {
pub(crate) command: Option<Vec<String>>,
pub(crate) env: HashMap<String, String>,
pub(crate) exposed_ports: HashSet<u16>,
pub(crate) volumes: HashMap<PathBuf, PathBuf>,
}

impl ContainerConfig {
Expand Down Expand Up @@ -169,6 +171,37 @@ impl ContainerConfig {
self
}

/// Mounts a named volume `source` into the container `destination`. Useful for integration
/// tests that depend on persistent storage shared between container executions.
///
/// See: [Docker CLI, Mount Volume](https://docs.docker.com/reference/cli/docker/container/run/#volume)
///
/// # Example
/// ```no_run
/// use libcnb_test::{BuildConfig, ContainerConfig, TestRunner};
/// use std::path::PathBuf;
///
/// TestRunner::default().build(
/// BuildConfig::new("heroku/builder:22", "tests/fixtures/app"),
/// |context| {
/// // ...
/// context.start_container(
/// ContainerConfig::new().volume(PathBuf::from("/shared/cache"), PathBuf::from("/workspace/cache")),
/// |container| {
/// // ...
/// },
/// );
/// },
/// );
/// ```
pub fn volume(&mut self, source: impl AsRef<Path>, destination: impl AsRef<Path>) -> &mut Self {
self.volumes.insert(
source.as_ref().to_path_buf(),
destination.as_ref().to_path_buf(),
);
self
}

/// Adds or updates multiple environment variable mappings for the container.
///
/// # Example
Expand Down
26 changes: 26 additions & 0 deletions libcnb-test/src/docker.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::{BTreeMap, BTreeSet};
use std::path::PathBuf;
use std::process::Command;

/// Represents a `docker run` command.
Expand All @@ -9,6 +10,7 @@ pub(crate) struct DockerRunCommand {
detach: bool,
entrypoint: Option<String>,
env: BTreeMap<String, String>,
volumes: BTreeMap<PathBuf, PathBuf>,
exposed_ports: BTreeSet<u16>,
image_name: String,
platform: Option<String>,
Expand All @@ -23,6 +25,7 @@ impl DockerRunCommand {
detach: false,
entrypoint: None,
env: BTreeMap::new(),
volumes: BTreeMap::new(),
exposed_ports: BTreeSet::new(),
image_name: image_name.into(),
platform: None,
Expand Down Expand Up @@ -53,6 +56,15 @@ impl DockerRunCommand {
self
}

pub(crate) fn volume(
&mut self,
source: impl Into<PathBuf>,
destination: impl Into<PathBuf>,
) -> &mut Self {
self.volumes.insert(source.into(), destination.into());
self
}

pub(crate) fn expose_port(&mut self, port: u16) -> &mut Self {
self.exposed_ports.insert(port);
self
Expand Down Expand Up @@ -98,6 +110,17 @@ impl From<DockerRunCommand> for Command {
command.args(["--publish", &format!("127.0.0.1::{port}")]);
}

for (source, destination) in &docker_run_command.volumes {
command.args([
"--volume",
&format!(
"{}:{}",
source.to_string_lossy(),
destination.to_string_lossy()
),
]);
}

command.arg(docker_run_command.image_name);

if let Some(container_command) = docker_run_command.command {
Expand Down Expand Up @@ -311,6 +334,7 @@ mod tests {
docker_run_command.entrypoint("/usr/bin/bash");
docker_run_command.env("BAR", "2");
docker_run_command.env("FOO", "1");
docker_run_command.volume(PathBuf::from("./test-cache"), PathBuf::from("/cache"));
docker_run_command.expose_port(12345);
docker_run_command.expose_port(55555);
docker_run_command.platform("linux/amd64");
Expand All @@ -337,6 +361,8 @@ mod tests {
"127.0.0.1::12345",
"--publish",
"127.0.0.1::55555",
"--volume",
"./test-cache:/cache",
"my-image",
"echo",
"hello",
Expand Down
4 changes: 4 additions & 0 deletions libcnb-test/src/test_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ impl<'a> TestContext<'a> {
docker_run_command.env(key, value);
});

config.volumes.iter().for_each(|(source, destination)| {
docker_run_command.volume(source, destination);
});

config.exposed_ports.iter().for_each(|port| {
docker_run_command.expose_port(*port);
});
Expand Down

0 comments on commit 6ef8a2b

Please sign in to comment.