Skip to content

Commit

Permalink
feat: add working_dir to ContainerRequest,ImageExt (#724)
Browse files Browse the repository at this point in the history
Implements #720 by adding support for setting the working directory on
`ImageExt` and `ContainerRequest`. Also adds a test for this feature.
This is equivalent to the `-w, --workdir` flag of `docker run`.

The abbreviation `working_dir` (as opposed to e.g. `working_directory`)
was chosen to use the same name as the `bollard` crate.
  • Loading branch information
nicmr committed Aug 25, 2024
1 parent 3dd9284 commit 5dff97f
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 0 deletions.
7 changes: 7 additions & 0 deletions testcontainers/src/core/containers/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub struct ContainerRequest<I: Image> {
pub(crate) cgroupns_mode: Option<CgroupnsMode>,
pub(crate) userns_mode: Option<String>,
pub(crate) startup_timeout: Option<Duration>,
pub(crate) working_dir: Option<String>,
pub(crate) log_consumers: Vec<Box<dyn LogConsumer + 'static>>,
}

Expand Down Expand Up @@ -156,6 +157,10 @@ impl<I: Image> ContainerRequest<I> {
pub fn startup_timeout(&self) -> Option<Duration> {
self.startup_timeout
}

pub fn working_dir(&self) -> Option<&str> {
self.working_dir.as_deref()
}
}

impl<I: Image> From<I> for ContainerRequest<I> {
Expand All @@ -177,6 +182,7 @@ impl<I: Image> From<I> for ContainerRequest<I> {
cgroupns_mode: None,
userns_mode: None,
startup_timeout: None,
working_dir: None,
log_consumers: vec![],
}
}
Expand Down Expand Up @@ -218,6 +224,7 @@ impl<I: Image + Debug> Debug for ContainerRequest<I> {
.field("cgroupns_mode", &self.cgroupns_mode)
.field("userns_mode", &self.userns_mode)
.field("startup_timeout", &self.startup_timeout)
.field("working_dir", &self.working_dir)
.finish()
}
}
11 changes: 11 additions & 0 deletions testcontainers/src/core/image/image_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ pub trait ImageExt<I: Image> {
/// Sets the startup timeout for the container. The default is 60 seconds.
fn with_startup_timeout(self, timeout: Duration) -> ContainerRequest<I>;

/// Sets the working directory. The default is defined by the underlying image, which in turn may default to `/`.
fn with_working_dir(self, working_dir: impl Into<String>) -> ContainerRequest<I>;

/// Adds the log consumer to the container.
///
/// Allows to follow the container logs for the whole lifecycle of the container, starting from the creation.
Expand Down Expand Up @@ -235,6 +238,14 @@ impl<RI: Into<ContainerRequest<I>>, I: Image> ImageExt<I> for RI {
}
}

fn with_working_dir(self, working_dir: impl Into<String>) -> ContainerRequest<I> {
let container_req = self.into();
ContainerRequest {
working_dir: Some(working_dir.into()),
..container_req
}
}

fn with_log_consumer(self, log_consumer: impl LogConsumer + 'static) -> ContainerRequest<I> {
let mut container_req = self.into();
container_req.log_consumers.push(Box::new(log_consumer));
Expand Down
22 changes: 22 additions & 0 deletions testcontainers/src/runners/async_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ where
userns_mode: container_req.userns_mode().map(|v| v.to_string()),
..Default::default()
}),
working_dir: container_req.working_dir().map(|dir| dir.to_string()),
..Default::default()
};

Expand Down Expand Up @@ -647,4 +648,25 @@ mod tests {
assert_eq!("host", userns_mode, "userns mode must be `host`");
Ok(())
}

#[tokio::test]
async fn async_run_command_should_have_working_dir() -> anyhow::Result<()> {
let image = GenericImage::new("hello-world", "latest");
let expected_working_dir = "/foo";
let container = image.with_working_dir(expected_working_dir).start().await?;

let client = Client::lazy_client().await?;
let container_details = client.inspect(container.id()).await?;

let working_dir = container_details
.config
.expect("ContainerConfig")
.working_dir
.expect("WorkingDir");
assert_eq!(
expected_working_dir, &working_dir,
"working dir must be `foo`"
);
Ok(())
}
}

0 comments on commit 5dff97f

Please sign in to comment.