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
use crate::core::{Container, Docker}; /// Represents a docker image. /// /// Implementations are required to implement Default. The default instance of an [`Image`] /// should have a meaningful configuration! It should be possible to [`run`][docker_run] the default /// instance of an Image and get back a working container! /// /// [`Image`]: trait.Image.html /// [docker_run]: trait.Docker.html#tymethod.run pub trait Image where Self: Sized + Default, Self::Args: Default + IntoIterator<Item = String>, Self::EnvVars: Default + IntoIterator<Item = (String, String)>, Self::Volumes: Default + IntoIterator<Item = (String, String)>, Self::EntryPoint: ToString, { /// A type representing the arguments for an Image. /// /// There are a couple of things regarding the arguments of images: /// /// 1. Similar to the Default implementation of an Image, the Default instance /// of its arguments should be meaningful! /// 2. Implementations should be conservative about which arguments they expose. Many times, /// users will either go with the default arguments or just override one or two. When defining /// the arguments of your image, consider that the whole purpose is to facilitate integration /// testing. Only expose those that actually make sense for this case. type Args; /// A type representing the environment variables for an Image. /// /// There are a couple of things regarding the arguments of images: /// /// 1. Similar to the Default implementation of an Image, the Default instance /// of its environment variables should be meaningful! /// 2. Implementations should be conservative about which environment variables they expose. Many times, /// users will either go with the default ones or just override one or two. When defining /// the environment variables of your image, consider that the whole purpose is to facilitate integration /// testing. Only expose those that actually make sense for this case. type EnvVars; /// A type representing the volumes for an Image. /// /// There are a couple of things regarding the arguments of images: /// /// 1. Similar to the Default implementation of an Image, the Default instance /// of its volumes should be meaningful! /// 2. Implementations should be conservative about which volumes they expose. Many times, /// users will either go with the default ones or just override one or two. When defining /// the volumes of your image, consider that the whole purpose is to facilitate integration /// testing. Only expose those that actually make sense for this case. type Volumes; /// A type representing the entrypoint for an Image. type EntryPoint: ?Sized; /// The descriptor of the docker image. /// /// This should return a full-qualified descriptor. /// Implementations are encouraged to include a tag that will not change (i.e. NOT latest) /// in order to prevent test code from randomly breaking because the underlying docker /// suddenly changed. fn descriptor(&self) -> String; /// Blocks the current thread until the started container is ready. /// /// This method is the **🍞 and butter** of the whole testcontainers library. Containers are /// rarely instantly available as soon as they are started. Most of them take some time to boot /// up. /// /// Implementations MUST block the current thread until the passed-in container is ready to be /// interacted with. The container instance provides access to logs of the container. /// /// Most implementations will very likely want to make use of this to wait for a particular /// message to be emitted. fn wait_until_ready<D: Docker>(&self, container: &Container<'_, D, Self>); /// Returns the arguments this instance was created with. fn args(&self) -> Self::Args; /// Returns the environment variables this instance was created with. fn env_vars(&self) -> Self::EnvVars; /// Returns the volumes this instance was created with. fn volumes(&self) -> Self::Volumes; /// Returs the ports mapping requested for the image. /// If not explicit port mappings is defined, all image ports will be automatically /// exposed and mapped on random host ports. fn ports(&self) -> Option<Vec<Port>>; /// Re-configures the current instance of this image with the given arguments. fn with_args(self, arguments: Self::Args) -> Self; /// Re-configures the current instance of this image with the given entrypoint. fn with_entrypoint(self, _entryppoint: &Self::EntryPoint) -> Self { self } /// Returns the entrypoint this instance was created with. fn entrypoint(&self) -> Option<String> { None } } /// Represents a port mapping between a local port and the internal port of a container. #[derive(Clone, Debug, PartialEq)] pub struct Port { pub local: u16, pub internal: u16, } impl Into<Port> for (u16, u16) { fn into(self) -> Port { Port { local: self.0, internal: self.1, } } }