@@ -51,13 +51,14 @@ use anyhow::{Context, Result};
5151use clap:: Parser ;
5252use std:: net:: SocketAddr ;
5353use std:: sync:: Arc ;
54- use std:: time:: { Duration , Instant } ;
54+ use std:: time:: Instant ;
5555use tracing:: { error, info} ;
5656
5757use torrust_tracker_deploy:: application:: commands:: ConfigureCommand ;
5858use torrust_tracker_deploy:: config:: { Config , InstanceName , SshCredentials } ;
5959use torrust_tracker_deploy:: container:: Services ;
6060use torrust_tracker_deploy:: e2e:: containers:: actions:: { SshKeySetupAction , SshWaitAction } ;
61+ use torrust_tracker_deploy:: e2e:: containers:: timeout:: ContainerTimeouts ;
6162use torrust_tracker_deploy:: e2e:: containers:: {
6263 RunningProvisionedContainer , StoppedProvisionedContainer ,
6364} ;
@@ -120,7 +121,11 @@ pub async fn main() -> Result<()> {
120121
121122 let test_start = Instant :: now ( ) ;
122123
123- let test_result = run_configuration_tests ( ) . await ;
124+ // Instance name for the test environment - consistent with provision tests
125+ let instance_name =
126+ InstanceName :: new ( "torrust-tracker-vm" . to_string ( ) ) . expect ( "Valid hardcoded instance name" ) ;
127+
128+ let test_result = run_configuration_tests ( cli. templates_dir , instance_name) . await ;
124129
125130 let test_duration = test_start. elapsed ( ) ;
126131
@@ -154,17 +159,14 @@ pub async fn main() -> Result<()> {
154159}
155160
156161/// Setup test environment with preflight cleanup
157- fn setup_test_environment ( ) -> Result < TestEnvironment > {
162+ fn setup_test_environment (
163+ templates_dir : String ,
164+ instance_name : InstanceName ,
165+ ) -> Result < TestEnvironment > {
158166 info ! ( "Running preflight cleanup for Docker-based E2E tests" ) ;
159- let instance_name = InstanceName :: new ( "torrust-tracker-vm" . to_string ( ) )
160- . context ( "Failed to create instance name" ) ?;
161- let test_env = TestEnvironment :: with_ssh_user_and_init (
162- false ,
163- "./data/templates" ,
164- "torrust" ,
165- instance_name,
166- )
167- . context ( "Failed to create test environment" ) ?;
167+ let test_env =
168+ TestEnvironment :: with_ssh_user_and_init ( false , templates_dir, "torrust" , instance_name)
169+ . context ( "Failed to create test environment" ) ?;
168170
169171 preflight_cleanup:: cleanup_lingering_resources_docker ( & test_env)
170172 . context ( "Failed to complete preflight cleanup" ) ?;
@@ -190,7 +192,8 @@ async fn configure_ssh_connectivity(
190192 test_env : & TestEnvironment ,
191193) -> Result < ( ) > {
192194 let socket_addr = container. ssh_details ( ) ;
193- let ssh_wait_action = SshWaitAction :: new ( Duration :: from_secs ( 30 ) , 10 ) ;
195+ let timeouts = ContainerTimeouts :: default ( ) ;
196+ let ssh_wait_action = SshWaitAction :: new ( timeouts. ssh_ready , 10 ) ;
194197 ssh_wait_action
195198 . execute ( socket_addr)
196199 . context ( "SSH server failed to start" ) ?;
@@ -214,11 +217,11 @@ async fn configure_ssh_connectivity(
214217}
215218
216219/// Run the complete configuration tests
217- async fn run_configuration_tests ( ) -> Result < ( ) > {
220+ async fn run_configuration_tests ( templates_dir : String , instance_name : InstanceName ) -> Result < ( ) > {
218221 info ! ( "Starting configuration tests with Docker container" ) ;
219222
220223 // Step 0: Setup test environment with preflight cleanup
221- let test_env = setup_test_environment ( ) ?;
224+ let test_env = setup_test_environment ( templates_dir , instance_name ) ?;
222225
223226 // Step 1: Setup Docker container - start with stopped state
224227 let running_container = setup_docker_container ( ) . await ?;
@@ -228,15 +231,15 @@ async fn run_configuration_tests() -> Result<()> {
228231
229232 // Step 2.5: Run provision simulation to render Ansible templates
230233 info ! ( "Running provision simulation to prepare container configuration" ) ;
231- run_provision_simulation ( & running_container) . await ?;
234+ run_provision_simulation ( & running_container, & test_env ) . await ?;
232235
233236 // Step 3: Run configuration tasks (Ansible playbooks)
234237 info ! ( "Running Ansible configuration tasks" ) ;
235- run_ansible_configuration ( & running_container) ?;
238+ run_ansible_configuration ( & running_container, & test_env ) ?;
236239
237240 // Step 4: Validate deployment
238241 info ! ( "Validating service deployment" ) ;
239- run_deployment_validation ( & running_container) . await ?;
242+ run_deployment_validation ( & running_container, & test_env ) . await ?;
240243
241244 // Step 5: Cleanup - transition back to stopped state
242245 cleanup_container ( running_container) ;
@@ -255,7 +258,8 @@ fn cleanup_container(running_container: RunningProvisionedContainer) {
255258
256259/// Run provision simulation to prepare templates for container configuration
257260async fn run_provision_simulation (
258- running_container : & torrust_tracker_deploy:: e2e:: containers:: RunningProvisionedContainer ,
261+ running_container : & RunningProvisionedContainer ,
262+ test_env : & TestEnvironment ,
259263) -> Result < ( ) > {
260264 let socket_addr = running_container. ssh_details ( ) ;
261265
@@ -265,8 +269,13 @@ async fn run_provision_simulation(
265269 ) ;
266270
267271 // Create SSH credentials and configuration for the container
268- let ssh_credentials = create_container_ssh_credentials ( ) ?;
269- let config = create_container_config ( ) ?;
272+ let ssh_credentials =
273+ create_container_ssh_credentials ( & test_env. config . ssh_credentials . ssh_username ) ?;
274+ let config = create_container_config (
275+ & test_env. config . ssh_credentials . ssh_username ,
276+ test_env. config . instance_name . clone ( ) ,
277+ test_env. config . templates_dir . clone ( ) ,
278+ ) ?;
270279 let services = Services :: new ( & config) ;
271280
272281 // Run the Docker infrastructure provision simulation
@@ -288,7 +297,8 @@ async fn run_provision_simulation(
288297
289298/// Run Ansible configuration tasks on the container
290299fn run_ansible_configuration (
291- running_container : & torrust_tracker_deploy:: e2e:: containers:: RunningProvisionedContainer ,
300+ running_container : & RunningProvisionedContainer ,
301+ test_env : & TestEnvironment ,
292302) -> Result < ( ) > {
293303 let socket_addr = running_container. ssh_details ( ) ;
294304
@@ -308,7 +318,12 @@ fn run_ansible_configuration(
308318 //
309319 // For now, we'll catch the expected connection error and log it:
310320
311- let config = create_container_config ( ) . context ( "Failed to create container configuration" ) ?;
321+ let config = create_container_config (
322+ & test_env. config . ssh_credentials . ssh_username ,
323+ test_env. config . instance_name . clone ( ) ,
324+ test_env. config . templates_dir . clone ( ) ,
325+ )
326+ . context ( "Failed to create container configuration" ) ?;
312327
313328 let services = Services :: new ( & config) ;
314329 let configure_command = ConfigureCommand :: new ( Arc :: clone ( & services. ansible_client ) ) ;
@@ -343,7 +358,8 @@ fn run_ansible_configuration(
343358
344359/// Run deployment validation tests on the container
345360async fn run_deployment_validation (
346- running_container : & torrust_tracker_deploy:: e2e:: containers:: RunningProvisionedContainer ,
361+ running_container : & RunningProvisionedContainer ,
362+ test_env : & TestEnvironment ,
347363) -> Result < ( ) > {
348364 let socket_addr = running_container. ssh_details ( ) ;
349365
@@ -354,7 +370,8 @@ async fn run_deployment_validation(
354370
355371 // Now we can use the proper SSH infrastructure with custom port support
356372 let ssh_credentials =
357- create_container_ssh_credentials ( ) . context ( "Failed to create container SSH credentials" ) ?;
373+ create_container_ssh_credentials ( & test_env. config . ssh_credentials . ssh_username )
374+ . context ( "Failed to create container SSH credentials" ) ?;
358375
359376 // Create SSH connection with the container's dynamic port
360377 validate_container_deployment_with_port ( & ssh_credentials, socket_addr)
@@ -371,23 +388,33 @@ async fn run_deployment_validation(
371388 Ok ( ( ) )
372389}
373390
374- /// Create a minimal configuration for container-based testing
375- fn create_container_config ( ) -> Result < Config > {
376- // For container testing, we use fixed test SSH keys from fixtures/
391+ /// Create centralized SSH credentials for test purposes
392+ ///
393+ /// Uses fixed test SSH keys from fixtures/ directory with provided username.
394+ /// This factory eliminates code duplication across multiple functions that need
395+ /// the same test SSH credentials.
396+ fn create_test_ssh_credentials ( ssh_username : & str ) -> Result < SshCredentials > {
377397 let project_root = std:: env:: current_dir ( ) . context ( "Failed to get current directory" ) ?;
378- let ssh_credentials = SshCredentials :: new (
398+ Ok ( SshCredentials :: new (
379399 project_root. join ( "fixtures/testing_rsa" ) ,
380400 project_root. join ( "fixtures/testing_rsa.pub" ) ,
381- "torrust" . to_string ( ) ,
382- ) ;
401+ ssh_username. to_string ( ) ,
402+ ) )
403+ }
383404
384- let instance_name = InstanceName :: new ( "torrust-tracker-container" . to_string ( ) )
385- . context ( "Failed to create instance name" ) ?;
405+ /// Create a minimal configuration for container-based testing
406+ fn create_container_config (
407+ ssh_username : & str ,
408+ instance_name : InstanceName ,
409+ templates_dir : String ,
410+ ) -> Result < Config > {
411+ // For container testing, we use fixed test SSH keys from fixtures/
412+ let ssh_credentials = create_test_ssh_credentials ( ssh_username)
413+ . context ( "Failed to create test SSH credentials" ) ?;
386414
387415 let project_root = std:: env:: current_dir ( ) . context ( "Failed to determine current directory" ) ?;
388416
389417 let build_dir = project_root. join ( "build" ) ;
390- let templates_dir = "data/templates" . to_string ( ) ;
391418
392419 Ok ( Config :: new (
393420 false , // Don't keep environment - cleanup after tests
@@ -400,16 +427,9 @@ fn create_container_config() -> Result<Config> {
400427}
401428
402429/// Create SSH credentials for connecting to the container
403- fn create_container_ssh_credentials ( ) -> Result < SshCredentials > {
404- // Use the same test SSH keys as the configuration
405- let project_root = std:: env:: current_dir ( ) . context ( "Failed to get current directory" ) ?;
406- let ssh_credentials = SshCredentials :: new (
407- project_root. join ( "fixtures/testing_rsa" ) ,
408- project_root. join ( "fixtures/testing_rsa.pub" ) ,
409- "torrust" . to_string ( ) ,
410- ) ;
411-
412- Ok ( ssh_credentials)
430+ fn create_container_ssh_credentials ( ssh_username : & str ) -> Result < SshCredentials > {
431+ // Use the centralized test SSH credentials factory
432+ create_test_ssh_credentials ( ssh_username)
413433}
414434
415435/// Validate container deployment using SSH infrastructure with custom port
0 commit comments