use crate::{
client::Client,
docker::{DockerInspectContainer, DockerUnpauseContainer},
};
use super::GetDeploymentError;
#[derive(Debug, thiserror::Error)]
pub enum UnpauseDeploymentError {
#[error("Failed to unpause container: {0}")]
ContainerUnpause(String),
#[error("Failed to get deployment: {0}")]
GetDeployment(#[from] GetDeploymentError),
}
impl<D: DockerUnpauseContainer + DockerInspectContainer> Client<D> {
pub async fn unpause_deployment(&self, name: &str) -> Result<(), UnpauseDeploymentError> {
let deployment = self.get_deployment(name).await?;
let container_id = deployment.container_id.as_str();
self.docker
.unpause_container(container_id)
.await
.map_err(|e| UnpauseDeploymentError::ContainerUnpause(e.to_string()))?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::docker::DockerError;
use bollard::{models::ContainerInspectResponse, query_parameters::InspectContainerOptions};
use mockall::mock;
mock! {
Docker {}
impl DockerUnpauseContainer for Docker {
async fn unpause_container(&self, container_id: &str) -> Result<(), DockerError>;
}
impl DockerInspectContainer for Docker {
async fn inspect_container(
&self,
container_id: &str,
options: Option<InspectContainerOptions>,
) -> Result<ContainerInspectResponse, DockerError>;
}
}
fn create_test_container_inspect_response() -> ContainerInspectResponse {
use bollard::models::{ContainerConfig, ContainerState, ContainerStateStatusEnum};
use std::collections::HashMap;
let mut labels = HashMap::new();
labels.insert("mongodb-atlas-local".to_string(), "container".to_string());
labels.insert("version".to_string(), "8.0.0".to_string());
labels.insert("mongodb-type".to_string(), "community".to_string());
let env_vars = vec!["TOOL=ATLASCLI".to_string()];
ContainerInspectResponse {
id: Some("test_container_id".to_string()),
name: Some("/test-deployment".to_string()),
config: Some(ContainerConfig {
labels: Some(labels),
env: Some(env_vars),
..Default::default()
}),
state: Some(ContainerState {
status: Some(ContainerStateStatusEnum::PAUSED),
..Default::default()
}),
..Default::default()
}
}
#[tokio::test]
async fn test_unpause_deployment() {
let mut mock_docker = MockDocker::new();
mock_docker
.expect_inspect_container()
.with(
mockall::predicate::eq("test-deployment"),
mockall::predicate::eq(None::<InspectContainerOptions>),
)
.times(1)
.returning(move |_, _| Ok(create_test_container_inspect_response()));
mock_docker
.expect_unpause_container()
.with(mockall::predicate::eq("test_container_id"))
.times(1)
.returning(|_| Ok(()));
let client = Client::new(mock_docker);
let result = client.unpause_deployment("test-deployment").await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_unpause_deployment_get_deployment_error() {
let mut mock_docker = MockDocker::new();
mock_docker
.expect_inspect_container()
.times(1)
.returning(|_, _| Err(DockerError::NotFound));
let client = Client::new(mock_docker);
let result = client.unpause_deployment("nonexistent-deployment").await;
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
UnpauseDeploymentError::GetDeployment(_)
));
}
#[tokio::test]
async fn test_unpause_deployment_unpause_container_error() {
let mut mock_docker = MockDocker::new();
mock_docker
.expect_inspect_container()
.times(1)
.returning(move |_, _| Ok(create_test_container_inspect_response()));
mock_docker
.expect_unpause_container()
.times(1)
.returning(|_| Err(DockerError::ServerError));
let client = Client::new(mock_docker);
let result = client.unpause_deployment("test-deployment").await;
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
UnpauseDeploymentError::ContainerUnpause(_)
));
}
}