switchgear_testing/credentials/
db.rs

1use crate::credentials::download_credentials;
2use crate::services::IntegrationTestServices;
3use anyhow::Context;
4use std::fs;
5use std::path::PathBuf;
6use tempfile::TempDir;
7
8#[derive(Debug, Clone, PartialEq, Eq, Hash)]
9pub struct TestDatabase {
10    pub address: String,
11    pub ca_cert_path: PathBuf,
12}
13
14#[derive(Debug, Clone, PartialEq, Eq, Hash)]
15pub struct TestDatabases {
16    pub postgres: Option<TestDatabase>,
17    pub mysql: Option<TestDatabase>,
18}
19
20pub struct DbCredentials {
21    inner: Option<DbCredentialsInner>,
22}
23
24struct DbCredentialsInner {
25    credentials_dir: TempDir,
26    postgres: String,
27    mysql: String,
28}
29
30impl DbCredentials {
31    pub fn create() -> anyhow::Result<Self> {
32        let services = IntegrationTestServices::create()?;
33
34        let inner = match (
35            services.credentials(),
36            services.postgres(),
37            services.mysql(),
38        ) {
39            (Some(credentials), Some(postgres), Some(mysql)) => {
40                let credentials_dir = TempDir::new()?;
41                download_credentials(credentials_dir.path(), credentials)?;
42                Some(DbCredentialsInner {
43                    credentials_dir,
44                    postgres: postgres.to_string(),
45                    mysql: mysql.to_string(),
46                })
47            }
48            _ => None,
49        };
50        Ok(Self { inner })
51    }
52
53    pub fn get_databases(&self) -> anyhow::Result<TestDatabases> {
54        let inner = match &self.inner {
55            None => {
56                return Ok(TestDatabases {
57                    postgres: None,
58                    mysql: None,
59                })
60            }
61            Some(inner) => inner,
62        };
63
64        let credentials = inner.credentials_dir.path().join("credentials");
65        let base_path = credentials.as_path();
66
67        let entries = fs::read_dir(base_path)
68            .with_context(|| format!("reading directory {}", base_path.display()))?;
69
70        let mut postgres = None;
71        let mut mysql = None;
72        for entry in entries {
73            let entry = entry
74                .with_context(|| format!("reading directory entry in {}", base_path.display(),))?;
75
76            let path = entry.path();
77
78            if !path.is_dir() {
79                continue;
80            }
81
82            let dir_name = match path.file_name() {
83                Some(name) => match name.to_str() {
84                    Some(s) => s,
85                    None => continue,
86                },
87                None => continue,
88            };
89
90            if dir_name == "postgres" {
91                postgres = Some(TestDatabase {
92                    address: inner.postgres.to_string(),
93                    ca_cert_path: path.join("server.pem"),
94                });
95            }
96
97            if dir_name == "mysql" {
98                mysql = Some(TestDatabase {
99                    address: inner.mysql.to_string(),
100                    ca_cert_path: path.join("server.pem"),
101                });
102            }
103
104            if postgres.is_some() && mysql.is_some() {
105                break;
106            }
107        }
108
109        Ok(TestDatabases { postgres, mysql })
110    }
111}