Skip to content

Commit

Permalink
Prefer bind mount semantics
Browse files Browse the repository at this point in the history
  • Loading branch information
runesoerensen committed Oct 22, 2024
1 parent 81868f0 commit 6f4aea4
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 25 deletions.
17 changes: 8 additions & 9 deletions libcnb-test/src/container_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +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>,
pub(crate) bind_mounts: HashMap<PathBuf, PathBuf>,
}

impl ContainerConfig {
Expand Down Expand Up @@ -171,35 +171,34 @@ 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.
/// Mount a `source` file or directory on the host machine into the container `target`. 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)
/// See: [Docker Engine: Bind Mounts](https://docs.docker.com/engine/storage/bind-mounts/)
///
/// # 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")),
/// ContainerConfig::new().bind_mount("/shared/cache", "/workspace/cache"),
/// |container| {
/// // ...
/// },
/// );
/// },
/// );
/// ```
pub fn volume(
pub fn bind_mount(
&mut self,
source: impl Into<PathBuf>,
destination: impl Into<PathBuf>,
target: impl Into<PathBuf>,
) -> &mut Self {
self.volumes.insert(source.into(), destination.into());
self.bind_mounts.insert(source.into(), target.into());
self
}

Expand Down
28 changes: 14 additions & 14 deletions libcnb-test/src/docker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub(crate) struct DockerRunCommand {
image_name: String,
platform: Option<String>,
remove: bool,
volumes: BTreeMap<PathBuf, PathBuf>,
bind_mounts: BTreeMap<PathBuf, PathBuf>,
}

impl DockerRunCommand {
Expand All @@ -29,7 +29,7 @@ impl DockerRunCommand {
image_name: image_name.into(),
platform: None,
remove: false,
volumes: BTreeMap::new(),
bind_mounts: BTreeMap::new(),
}
}

Expand Down Expand Up @@ -71,8 +71,8 @@ impl DockerRunCommand {
self
}

pub(crate) fn volume<P: Into<PathBuf>>(&mut self, source: P, destination: P) -> &mut Self {
self.volumes.insert(source.into(), destination.into());
pub(crate) fn bind_mount<P: Into<PathBuf>>(&mut self, source: P, target: P) -> &mut Self {
self.bind_mounts.insert(source.into(), target.into());
self
}
}
Expand Down Expand Up @@ -106,13 +106,13 @@ impl From<DockerRunCommand> for Command {
command.args(["--publish", &format!("127.0.0.1::{port}")]);
}

for (source, destination) in &docker_run_command.volumes {
for (source, target) in &docker_run_command.bind_mounts {
command.args([
"--volume",
"--mount",
&format!(
"{}:{}",
"type=bind,source={},target={}",
source.to_string_lossy(),
destination.to_string_lossy()
target.to_string_lossy()
),
]);
}
Expand Down Expand Up @@ -334,8 +334,8 @@ mod tests {
docker_run_command.expose_port(55555);
docker_run_command.platform("linux/amd64");
docker_run_command.remove(true);
docker_run_command.volume(PathBuf::from("./test-cache"), PathBuf::from("/cache"));
docker_run_command.volume("foo", "/bar");
docker_run_command.bind_mount(PathBuf::from("./test-cache"), PathBuf::from("/cache"));
docker_run_command.bind_mount("foo", "/bar");

let command: Command = docker_run_command.clone().into();
assert_eq!(
Expand All @@ -358,10 +358,10 @@ mod tests {
"127.0.0.1::12345",
"--publish",
"127.0.0.1::55555",
"--volume",
"./test-cache:/cache",
"--volume",
"foo:/bar",
"--mount",
"type=bind,source=./test-cache,target=/cache",
"--mount",
"type=bind,source=foo,target=/bar",
"my-image",
"echo",
"hello",
Expand Down
4 changes: 2 additions & 2 deletions libcnb-test/src/test_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ impl<'a> TestContext<'a> {
docker_run_command.expose_port(*port);
});

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

// We create the ContainerContext early to ensure the cleanup in ContainerContext::drop
Expand Down

0 comments on commit 6f4aea4

Please sign in to comment.