torrust_tracker_deployer_lib/domain/environment/state/
released.rs1use serde::{Deserialize, Serialize};
11
12use crate::domain::environment::runtime_outputs::ServiceEndpoints;
13use crate::domain::environment::state::{AnyEnvironmentState, Running, StateTypeError};
14use crate::domain::environment::Environment;
15
16#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
23pub struct Released;
24
25impl Environment<Released> {
27 #[must_use]
36 pub fn start_running_with_endpoints(
37 mut self,
38 service_endpoints: ServiceEndpoints,
39 ) -> Environment<Running> {
40 self.context
41 .runtime_outputs
42 .record_services_started(service_endpoints);
43 self.with_state(Running)
44 }
45
46 #[must_use]
51 pub fn start_running(self) -> Environment<Running> {
52 self.with_state(Running)
53 }
54}
55
56impl Environment<Released> {
58 #[must_use]
60 pub fn into_any(self) -> AnyEnvironmentState {
61 AnyEnvironmentState::Released(self)
62 }
63}
64
65impl AnyEnvironmentState {
67 pub fn try_into_released(self) -> Result<Environment<Released>, StateTypeError> {
73 match self {
74 Self::Released(env) => Ok(env),
75 other => Err(StateTypeError::UnexpectedState {
76 expected: "released",
77 actual: other.state_name().to_string(),
78 }),
79 }
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86
87 #[test]
88 fn it_should_create_released_state() {
89 let state = Released;
90 assert_eq!(state, Released);
91 }
92
93 mod conversion_tests {
94 use super::*;
95 use crate::adapters::ssh::SshCredentials;
96 use crate::domain::environment::name::EnvironmentName;
97 use crate::domain::environment::runtime_outputs::ProvisionMethod;
98 use crate::domain::provider::{LxdConfig, ProviderConfig};
99 use crate::domain::ProfileName;
100 use crate::shared::Username;
101 use std::net::{IpAddr, Ipv4Addr};
102 use std::path::PathBuf;
103
104 fn default_lxd_provider_config(env_name: &EnvironmentName) -> ProviderConfig {
105 ProviderConfig::Lxd(LxdConfig {
106 profile_name: ProfileName::new(format!("lxd-{}", env_name.as_str())).unwrap(),
107 })
108 }
109
110 fn create_test_ssh_credentials() -> SshCredentials {
111 let username = Username::new("test-user".to_string()).unwrap();
112 SshCredentials::new(
113 PathBuf::from("/tmp/test_key"),
114 PathBuf::from("/tmp/test_key.pub"),
115 username,
116 )
117 }
118
119 fn create_test_environment_released() -> Environment<Released> {
120 let name = EnvironmentName::new("test-env".to_string()).unwrap();
121 let ssh_creds = create_test_ssh_credentials();
122 Environment::new(
123 name.clone(),
124 default_lxd_provider_config(&name),
125 ssh_creds,
126 22,
127 chrono::Utc::now(),
128 )
129 .start_provisioning()
130 .provisioned(
131 IpAddr::V4(Ipv4Addr::new(192, 168, 1, 100)),
132 ProvisionMethod::Provisioned,
133 )
134 .start_configuring()
135 .configured()
136 .start_releasing()
137 .released()
138 }
139
140 #[test]
141 fn it_should_convert_released_environment_into_any() {
142 let env = create_test_environment_released();
143 let any_env = env.into_any();
144 assert!(matches!(any_env, AnyEnvironmentState::Released(_)));
145 }
146
147 #[test]
148 fn it_should_convert_any_to_released_successfully() {
149 let env = create_test_environment_released();
150 let any_env = env.into_any();
151 let result = any_env.try_into_released();
152 assert!(result.is_ok());
153 }
154 }
155
156 mod transition_tests {
157 use super::*;
158 use crate::adapters::ssh::SshCredentials;
159 use crate::domain::environment::name::EnvironmentName;
160 use crate::domain::environment::runtime_outputs::ProvisionMethod;
161 use crate::domain::environment::state::Running;
162 use crate::domain::provider::{LxdConfig, ProviderConfig};
163 use crate::domain::ProfileName;
164 use crate::shared::Username;
165 use std::net::{IpAddr, Ipv4Addr};
166 use std::path::PathBuf;
167
168 fn default_lxd_provider_config(env_name: &EnvironmentName) -> ProviderConfig {
169 ProviderConfig::Lxd(LxdConfig {
170 profile_name: ProfileName::new(format!("lxd-{}", env_name.as_str())).unwrap(),
171 })
172 }
173
174 fn create_test_environment() -> Environment<Released> {
175 let env_name = EnvironmentName::new("test-state".to_string()).unwrap();
176 let ssh_username = Username::new("torrust".to_string()).unwrap();
177 let ssh_credentials = SshCredentials::new(
178 PathBuf::from("test_key"),
179 PathBuf::from("test_key.pub"),
180 ssh_username,
181 );
182 Environment::new(
183 env_name.clone(),
184 default_lxd_provider_config(&env_name),
185 ssh_credentials,
186 22,
187 chrono::Utc::now(),
188 )
189 .start_provisioning()
190 .provisioned(
191 IpAddr::V4(Ipv4Addr::new(192, 168, 1, 100)),
192 ProvisionMethod::Provisioned,
193 )
194 .start_configuring()
195 .configured()
196 .start_releasing()
197 .released()
198 }
199
200 #[test]
201 fn it_should_transition_from_released_to_running() {
202 let env = create_test_environment();
203 let env = env.start_running();
204
205 assert_eq!(*env.state(), Running);
206 assert_eq!(env.name().as_str(), "test-state");
207 }
208 }
209}