Skip to main content

torrust_tracker_deployer_lib/testing/e2e/containers/
executor.rs

1//! Container Command Executor Trait
2//!
3//! This module defines the trait that allows decoupled container actions
4//! to execute commands inside running containers.
5
6use testcontainers::core::ExecCommand;
7use testcontainers::TestcontainersError;
8
9/// Trait for containers that can execute commands inside themselves
10///
11/// This trait provides a standardized interface for executing commands within
12/// running containers, enabling decoupled container actions that don't need
13/// to know about the specific container implementation details.
14///
15/// ## Usage
16///
17/// Container actions can use this trait to execute commands without being
18/// tightly coupled to the container implementation:
19///
20/// ```rust,no_run
21/// use torrust_tracker_deployer_lib::testing::e2e::containers::ContainerExecutor;
22/// use testcontainers::core::ExecCommand;
23///
24/// async fn setup_something<T: ContainerExecutor>(container: &T) -> Result<(), Box<dyn std::error::Error>> {
25///     let result = container.exec(ExecCommand::new(["echo", "hello"])).await?;
26///     Ok(())
27/// }
28/// ```
29#[allow(async_fn_in_trait)]
30pub trait ContainerExecutor {
31    /// Execute a command inside the container
32    ///
33    /// # Arguments
34    ///
35    /// * `command` - The command to execute inside the container
36    ///
37    /// # Returns
38    ///
39    /// * `Ok(())` - If the command was executed successfully
40    /// * `Err(TestcontainersError)` - If the command execution failed
41    ///
42    /// # Errors
43    ///
44    /// Returns an error if the command execution fails due to container issues,
45    /// network problems, or other testcontainers-related errors.
46    ///
47    /// # Note
48    ///
49    /// The command execution may succeed even if the command itself fails
50    /// (returns non-zero exit code). The caller should check the exit code
51    /// in the returned result if needed.
52    async fn exec(&self, command: ExecCommand) -> std::result::Result<(), TestcontainersError>;
53}
54
55#[cfg(test)]
56mod tests {
57    // Note: ContainerExecutor trait is no longer object-safe due to impl Future return type
58    // This is expected since async traits can't be used as trait objects without boxing futures
59
60    #[test]
61    fn it_should_define_executor_trait_with_exec_method() {
62        // Test that trait definition compiles correctly
63        // The actual implementation will be tested with concrete types
64    }
65}