torrust_tracker_deployer_lib/testing/integration/ssh_server/
config.rs1use std::path::PathBuf;
4
5use crate::shared::secrets::PlainPassword;
6
7use super::constants::{
8 CONTAINER_STARTUP_WAIT_SECS, DEFAULT_TEST_PASSWORD, DEFAULT_TEST_USERNAME, DOCKERFILE_DIR,
9 MOCK_SSH_PORT, SSH_SERVER_IMAGE_NAME, SSH_SERVER_IMAGE_TAG,
10};
11
12#[derive(Debug, Clone, PartialEq, Eq)]
34pub struct SshServerConfig {
35 pub image_name: String,
37
38 pub image_tag: String,
40
41 pub username: String,
43
44 pub password: PlainPassword,
46
47 pub startup_wait_secs: u64,
49
50 pub dockerfile_dir: PathBuf,
52
53 pub mock_port: u16,
55}
56
57impl SshServerConfig {
58 #[must_use]
71 pub fn builder() -> SshServerConfigBuilder {
72 SshServerConfigBuilder::default()
73 }
74}
75
76impl Default for SshServerConfig {
77 fn default() -> Self {
89 Self {
90 image_name: SSH_SERVER_IMAGE_NAME.to_string(),
91 image_tag: SSH_SERVER_IMAGE_TAG.to_string(),
92 username: DEFAULT_TEST_USERNAME.to_string(),
93 password: DEFAULT_TEST_PASSWORD.to_string(),
94 startup_wait_secs: CONTAINER_STARTUP_WAIT_SECS,
95 dockerfile_dir: PathBuf::from(DOCKERFILE_DIR),
96 mock_port: MOCK_SSH_PORT,
97 }
98 }
99}
100
101#[derive(Debug, Default)]
120pub struct SshServerConfigBuilder {
121 image_name: Option<String>,
122 image_tag: Option<String>,
123 username: Option<String>,
124 password: Option<PlainPassword>,
125 startup_wait_secs: Option<u64>,
126 dockerfile_dir: Option<PathBuf>,
127 mock_port: Option<u16>,
128}
129
130impl SshServerConfigBuilder {
131 #[must_use]
133 pub fn image_name(mut self, name: impl Into<String>) -> Self {
134 self.image_name = Some(name.into());
135 self
136 }
137
138 #[must_use]
140 pub fn image_tag(mut self, tag: impl Into<String>) -> Self {
141 self.image_tag = Some(tag.into());
142 self
143 }
144
145 #[must_use]
147 pub fn username(mut self, username: impl Into<String>) -> Self {
148 self.username = Some(username.into());
149 self
150 }
151
152 #[must_use]
154 pub fn password(mut self, password: impl Into<PlainPassword>) -> Self {
155 self.password = Some(password.into());
156 self
157 }
158
159 #[must_use]
161 pub fn startup_wait_secs(mut self, secs: u64) -> Self {
162 self.startup_wait_secs = Some(secs);
163 self
164 }
165
166 #[must_use]
168 pub fn dockerfile_dir(mut self, dir: impl Into<PathBuf>) -> Self {
169 self.dockerfile_dir = Some(dir.into());
170 self
171 }
172
173 #[must_use]
175 pub fn mock_port(mut self, port: u16) -> Self {
176 self.mock_port = Some(port);
177 self
178 }
179
180 #[must_use]
184 pub fn build(self) -> SshServerConfig {
185 let defaults = SshServerConfig::default();
186 SshServerConfig {
187 image_name: self.image_name.unwrap_or(defaults.image_name),
188 image_tag: self.image_tag.unwrap_or(defaults.image_tag),
189 username: self.username.unwrap_or(defaults.username),
190 password: self.password.unwrap_or(defaults.password),
191 startup_wait_secs: self.startup_wait_secs.unwrap_or(defaults.startup_wait_secs),
192 dockerfile_dir: self.dockerfile_dir.unwrap_or(defaults.dockerfile_dir),
193 mock_port: self.mock_port.unwrap_or(defaults.mock_port),
194 }
195 }
196}
197
198#[cfg(test)]
199mod tests {
200 use super::*;
201
202 #[test]
203 fn it_should_create_config_with_default_values() {
204 let config = SshServerConfig::default();
205
206 assert_eq!(config.image_name, "torrust-ssh-server");
207 assert_eq!(config.image_tag, "latest");
208 assert_eq!(config.username, "testuser");
209 assert_eq!(config.password, "testpass");
210 assert_eq!(config.startup_wait_secs, 10);
211 assert_eq!(config.dockerfile_dir, PathBuf::from("docker/ssh-server"));
212 assert_eq!(config.mock_port, 2222);
213 }
214
215 #[test]
216 fn it_should_build_config_with_custom_values() {
217 let config = SshServerConfig::builder()
218 .image_name("custom-ssh")
219 .image_tag("v2.0")
220 .username("admin")
221 .password("secret")
222 .startup_wait_secs(15)
223 .dockerfile_dir("custom/path")
224 .mock_port(3333)
225 .build();
226
227 assert_eq!(config.image_name, "custom-ssh");
228 assert_eq!(config.image_tag, "v2.0");
229 assert_eq!(config.username, "admin");
230 assert_eq!(config.password, "secret");
231 assert_eq!(config.startup_wait_secs, 15);
232 assert_eq!(config.dockerfile_dir, PathBuf::from("custom/path"));
233 assert_eq!(config.mock_port, 3333);
234 }
235
236 #[test]
237 fn it_should_use_defaults_for_unset_builder_fields() {
238 let config = SshServerConfig::builder().username("customuser").build();
239
240 assert_eq!(config.username, "customuser");
242
243 assert_eq!(config.image_name, "torrust-ssh-server");
245 assert_eq!(config.image_tag, "latest");
246 assert_eq!(config.password, "testpass");
247 assert_eq!(config.startup_wait_secs, 10);
248 assert_eq!(config.mock_port, 2222);
249 }
250
251 #[test]
252 fn it_should_allow_chaining_builder_methods() {
253 let config = SshServerConfig::builder()
254 .image_name("test")
255 .image_tag("v1")
256 .username("user1")
257 .password("pass1")
258 .startup_wait_secs(5)
259 .build();
260
261 assert_eq!(config.image_name, "test");
262 assert_eq!(config.username, "user1");
263 assert_eq!(config.startup_wait_secs, 5);
264 }
265
266 #[test]
267 fn it_should_be_cloneable() {
268 let config1 = SshServerConfig::default();
269 let config2 = config1.clone();
270
271 assert_eq!(config1, config2);
272 }
273
274 #[test]
275 fn it_should_allow_customizing_mock_port() {
276 let config = SshServerConfig::builder().mock_port(5555).build();
277
278 assert_eq!(config.mock_port, 5555);
279
280 assert_eq!(config.username, "testuser");
282 assert_eq!(config.password, "testpass");
283 }
284}