nethsm_tests/
container.rs

1use nethsm::Url;
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
13/// The NetHSM container image and specific tag
14///
15/// We are currently pinning to "c16fe4ed" due to <https://gitlab.archlinux.org/archlinux/signstar/-/issues/32>
16/// In the future we will probably want to stick to a specific release tag (representing an actual
17/// upstream release) and not "testing"
18const IMAGE_NAME: &str = "docker.io/nitrokey/nethsm:c16fe4ed";
19const DEFAULT_PORT: u16 = 8443;
20const DEFAULT_PATH: &str = "/api/v1";
21
22/// An image of NetHSM used to create a running container.
23#[derive(Debug)]
24pub struct NetHsmImage {
25    /// Image name that is used to start the container.
26    pub image: ImageName,
27
28    /// Exposed port which will be used for communication with the NetHSM.
29    pub port: ExposedPort,
30}
31
32impl NetHsmImage {
33    /// Returns an base URL for the virtualized NetHSM.
34    pub async fn url(&self) -> TestResult<Url> {
35        Ok(Url::new(&format!(
36            "https://localhost:{}{}",
37            self.port.host_port().await?,
38            DEFAULT_PATH
39        ))?)
40    }
41}
42
43impl Default for NetHsmImage {
44    fn default() -> Self {
45        Self {
46            image: ImageName::new(IMAGE_NAME),
47            port: ExposedPort::new(DEFAULT_PORT),
48        }
49    }
50}
51
52impl ToRunnableContainer for NetHsmImage {
53    fn to_runnable(&self, builder: RunnableContainerBuilder) -> RunnableContainer {
54        builder
55            .with_image(self.image.clone())
56            .with_container_name(Some(format!(
57                "nethsm-test-{}",
58                Uuid::new_v7(Timestamp::now(NoContext))
59            )))
60            .with_wait_strategy(WaitStrategy::HttpSuccess {
61                https: true,
62                require_valid_certs: false,
63                path: "/".into(),
64                container_port: 8443.into(),
65            })
66            .with_port_mappings([self.port.clone()])
67            .build()
68    }
69}