1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
//! Represents a created container, in transit to become a OperationalContainer.
use crate::{
composition::{LogOptions, StaticManagementPolicy},
container::OperationalContainer,
docker::{ContainerState, Docker},
waitfor::WaitFor,
DockerTestError, StartPolicy,
};
/// Represent a docker container object in a pending phase between
/// it being created on the daemon, but may not be running.
///
/// This object is an implementation detail of `dockertest-rs` and is only
/// publicly exposed due to the public `WaitFor` trait which is responsible
/// of performing the into conversion from `PendingContainer` to `OperationalContainer`.
// NOTE: No methods on this structure, nor fields, shall be publicly exposed.
#[derive(Clone)]
pub struct PendingContainer {
/// The docker client
pub(crate) client: Docker,
/// Name of the container, defaults to the repository name of the image.
pub(crate) name: String,
/// Id of the running container.
pub(crate) id: String,
/// Handle used to interact with the container from the user
pub(crate) handle: String,
/// The StartPolicy of this Container, is provided from its Composition.
pub(crate) start_policy: StartPolicy,
/// Trait implementing how to wait for the container to startup.
pub(crate) wait: Option<Box<dyn WaitFor>>,
/// Wheter this is a static container
pub(crate) is_static: bool,
/// The StaticManagementPolicy of this container if any exists
pub(crate) static_management_policy: Option<StaticManagementPolicy>,
/// Container log options, they are provided by `Composition`.
pub(crate) log_options: Option<LogOptions>,
/// The containers' expected state after executing its `WaitFor` implementation.
pub(crate) expected_state: ContainerState,
}
impl PendingContainer {
/// Creates a new Container object with the given values.
// FIXME(veeg): reword the PendingContainer API to be more ergonomic
#[allow(clippy::too_many_arguments)]
pub(crate) fn new<T: ToString, R: ToString, H: ToString>(
name: T,
id: R,
handle: H,
start_policy: StartPolicy,
wait: Box<dyn WaitFor>,
client: Docker,
static_management_policy: Option<StaticManagementPolicy>,
log_options: Option<LogOptions>,
) -> PendingContainer {
PendingContainer {
client,
name: name.to_string(),
id: id.to_string(),
handle: handle.to_string(),
start_policy,
is_static: static_management_policy.is_some(),
static_management_policy,
log_options,
expected_state: wait.expected_state(),
wait: Some(wait),
}
}
/// Run the start command and initiate the WaitFor condition.
/// Once the PendingContainer is successfully started and the WaitFor condition
/// has been achived, the OperationalContainer is returned.
pub(crate) async fn start(self) -> Result<OperationalContainer, DockerTestError> {
// TODO: dont clone
let client = self.client.clone();
client.start_container(self).await
}
// Internal start method should only be invoked from the static mod.
// TODO: isolate to static mod only
pub(crate) async fn start_inner(self) -> Result<OperationalContainer, DockerTestError> {
// TODO: dont clone
let client = self.client.clone();
client.start_container_inner(self).await
}
}
#[cfg(test)]
mod tests {
use crate::container::PendingContainer;
use crate::docker::Docker;
use crate::waitfor::NoWait;
use crate::StartPolicy;
/// Tests `PendingContainer::new` with associated struct member field values.
#[tokio::test]
async fn test_new_pending_container() {
let client = Docker::new().unwrap();
let id = "this_is_an_id".to_string();
let name = "this_is_a_container_name".to_string();
let handle_key = "this_is_a_handle_key";
let container = PendingContainer::new(
&name,
&id,
handle_key,
StartPolicy::Relaxed,
Box::new(NoWait {}),
client,
None,
None,
);
assert_eq!(id, container.id, "wrong id set in container creation");
assert_eq!(name, container.name, "wrong name set in container creation");
assert_eq!(
name, container.name,
"container name getter returns wrong value"
);
assert_eq!(
handle_key, container.handle,
"wrong handle_key set in container creation"
);
}
}