nethsm/test/
container.rs

1use rust_dotenv::dotenv::DotEnv;
2use rustainers::{
3    ExposedPort,
4    ImageName,
5    RunnableContainer,
6    RunnableContainerBuilder,
7    ToRunnableContainer,
8    WaitStrategy,
9};
10use testresult::TestResult;
11use uuid::{NoContext, Uuid, timestamp::Timestamp};
12
13use crate::Url;
14
15/// The NetHSM container image without a specific tag
16const IMAGE_NAME: &str = "docker.io/nitrokey/nethsm";
17const DEFAULT_PORT: u16 = 8443;
18const DEFAULT_PATH: &str = "/api/v1";
19
20/// An image of NetHSM used to create a running container.
21#[derive(Debug)]
22pub struct NetHsmImage {
23    /// Image name that is used to start the container.
24    pub image: ImageName,
25
26    /// Exposed port which will be used for communication with the NetHSM.
27    pub port: ExposedPort,
28}
29
30impl NetHsmImage {
31    /// Returns an base URL for the virtualized NetHSM.
32    pub async fn url(&self) -> TestResult<Url> {
33        Ok(Url::new(&format!(
34            "https://localhost:{}{}",
35            self.port.host_port().await?,
36            DEFAULT_PATH
37        ))?)
38    }
39}
40
41impl Default for NetHsmImage {
42    fn default() -> Self {
43        let mut image = ImageName::new(IMAGE_NAME);
44        image.set_tag(
45            DotEnv::new("")
46                .get_var("NETHSM_IMAGE_TAG".into())
47                .unwrap_or_else(|| "testing".into()),
48        );
49        Self {
50            image,
51            port: ExposedPort::new(DEFAULT_PORT),
52        }
53    }
54}
55
56impl ToRunnableContainer for NetHsmImage {
57    fn to_runnable(&self, builder: RunnableContainerBuilder) -> RunnableContainer {
58        builder
59            .with_image(self.image.clone())
60            .with_container_name(Some(format!(
61                "nethsm-test-{}",
62                Uuid::new_v7(Timestamp::now(NoContext))
63            )))
64            .with_wait_strategy(WaitStrategy::HttpSuccess {
65                https: true,
66                require_valid_certs: false,
67                path: "/".into(),
68                container_port: 8443.into(),
69            })
70            .with_port_mappings([self.port.clone()])
71            .build()
72    }
73}