-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathdestroy_command.rs
More file actions
227 lines (193 loc) · 8.68 KB
/
destroy_command.rs
File metadata and controls
227 lines (193 loc) · 8.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
//! End-to-End Black Box Tests for Destroy Command
//!
//! This test suite provides true black-box testing of the destroy command
//! by running the production application as an external process. These tests
//! verify that the destroy command correctly handles the working directory
//! parameter, ensuring environments can be destroyed from custom locations.
//!
//! ## Test Approach
//!
//! - **Black Box**: Runs production binary as external process
//! - **Isolation**: Uses temporary directories for complete test isolation
//! - **Coverage**: Tests complete workflow from environment creation to destruction
//! - **Verification**: Validates environment is properly removed
//!
//! ## Test Scenarios
//!
//! 1. Default working directory: Destroy environment from current directory
//! 2. Custom working directory: Destroy environment from temporary directory
//! 3. Full lifecycle: Create → Destroy with custom working directory
use super::super::support::{EnvironmentStateAssertions, ProcessRunner, TempWorkspace};
use anyhow::Result;
use torrust_dependency_installer::{verify_dependencies, Dependency};
use torrust_tracker_deployer_lib::testing::e2e::tasks::black_box::create_test_environment_config;
/// Verify that all required dependencies are installed for destroy command E2E tests.
///
/// **Current State**: No system dependencies required.
///
/// These black-box tests run the production binary as an external process and verify
/// the destroy command workflow. Currently, they only test the command interface and
/// environment state transitions, without requiring infrastructure tools.
///
/// # Future Dependencies
///
/// If these tests evolve to verify actual infrastructure destruction or cleanup,
/// add required dependencies here:
/// ```ignore
/// let required_deps = &[Dependency::OpenTofu, Dependency::Ansible, Dependency::Lxd];
/// ```
///
/// # Errors
///
/// Returns an error if any required dependencies are missing or cannot be detected.
fn verify_required_dependencies() -> Result<()> {
// Currently no system dependencies required - empty array
let required_deps: &[Dependency] = &[];
verify_dependencies(required_deps)?;
Ok(())
}
#[test]
fn it_should_destroy_environment_with_default_working_directory() {
// Verify dependencies before running tests
verify_required_dependencies().expect("Dependency verification failed");
// Arrange: Create temporary workspace
let temp_workspace = TempWorkspace::new().expect("Failed to create temp workspace");
// Create environment configuration file
let config = create_test_environment_config("test-destroy-default");
temp_workspace
.write_config_file("environment.json", &config)
.expect("Failed to write config file");
// Create environment in default location
let create_result = ProcessRunner::new()
.working_dir(temp_workspace.path())
.run_create_command("./environment.json")
.expect("Failed to run create command");
assert!(
create_result.success(),
"Create command failed: {}",
create_result.stderr()
);
// Verify environment was created
let env_assertions = EnvironmentStateAssertions::new(temp_workspace.path());
env_assertions.assert_environment_exists("test-destroy-default");
// Act: Destroy environment using destroy command
let destroy_result = ProcessRunner::new()
.working_dir(temp_workspace.path())
.run_destroy_command("test-destroy-default")
.expect("Failed to run destroy command");
// Assert: Verify command succeeded
assert!(
destroy_result.success(),
"Destroy command failed with exit code: {:?}\nstderr: {}",
destroy_result.exit_code(),
destroy_result.stderr()
);
// Assert: Verify environment was transitioned to Destroyed state
let env_assertions = EnvironmentStateAssertions::new(temp_workspace.path());
env_assertions.assert_environment_exists("test-destroy-default");
env_assertions.assert_environment_state_is("test-destroy-default", "Destroyed");
}
#[test]
fn it_should_destroy_environment_with_custom_working_directory() {
// Verify dependencies before running tests
verify_required_dependencies().expect("Dependency verification failed");
// Arrange: Create temporary workspace
let temp_workspace = TempWorkspace::new().expect("Failed to create temp workspace");
// Create environment configuration file
let config = create_test_environment_config("test-destroy-custom");
temp_workspace
.write_config_file("environment.json", &config)
.expect("Failed to write config file");
// Create environment in custom location
let create_result = ProcessRunner::new()
.working_dir(temp_workspace.path())
.run_create_command("./environment.json")
.expect("Failed to run create command");
assert!(
create_result.success(),
"Create command failed: {}",
create_result.stderr()
);
// Verify environment was created in custom location
let env_assertions = EnvironmentStateAssertions::new(temp_workspace.path());
env_assertions.assert_environment_exists("test-destroy-custom");
// Act: Destroy environment using same working directory
let destroy_result = ProcessRunner::new()
.working_dir(temp_workspace.path())
.run_destroy_command("test-destroy-custom")
.expect("Failed to run destroy command");
// Assert: Verify command succeeded
assert!(
destroy_result.success(),
"Destroy command failed with exit code: {:?}\nstderr: {}",
destroy_result.exit_code(),
destroy_result.stderr()
);
// Assert: Verify environment was transitioned to Destroyed state in custom location
let env_assertions = EnvironmentStateAssertions::new(temp_workspace.path());
env_assertions.assert_environment_exists("test-destroy-custom");
env_assertions.assert_environment_state_is("test-destroy-custom", "Destroyed");
}
#[test]
fn it_should_fail_when_environment_not_found_in_working_directory() {
// Verify dependencies before running tests
verify_required_dependencies().expect("Dependency verification failed");
// Arrange: Create temporary workspace
let temp_workspace = TempWorkspace::new().expect("Failed to create temp workspace");
// Act: Try to destroy non-existent environment
let destroy_result = ProcessRunner::new()
.working_dir(temp_workspace.path())
.run_destroy_command("nonexistent-environment")
.expect("Failed to run destroy command");
// Assert: Command should fail
assert!(
!destroy_result.success(),
"Command should have failed when environment doesn't exist"
);
// Verify error message mentions environment not found
let stderr = destroy_result.stderr();
assert!(
stderr.contains("not found") || stderr.contains("does not exist"),
"Error message should mention environment not found, got: {stderr}"
);
}
#[test]
fn it_should_complete_full_lifecycle_with_custom_working_directory() {
verify_required_dependencies().expect("Dependency verification failed");
// Arrange: Create temporary workspace
let temp_workspace = TempWorkspace::new().expect("Failed to create temp workspace");
// Create environment configuration file
let config = create_test_environment_config("test-lifecycle");
temp_workspace
.write_config_file("environment.json", &config)
.expect("Failed to write config file");
// Act: Create environment in custom location
let create_result = ProcessRunner::new()
.working_dir(temp_workspace.path())
.run_create_command("./environment.json")
.expect("Failed to run create command");
assert!(
create_result.success(),
"Create command failed: {}",
create_result.stderr()
);
// Verify environment exists
let env_assertions = EnvironmentStateAssertions::new(temp_workspace.path());
env_assertions.assert_environment_exists("test-lifecycle");
env_assertions.assert_environment_state_is("test-lifecycle", "Created");
// Act: Destroy environment
let destroy_result = ProcessRunner::new()
.working_dir(temp_workspace.path())
.run_destroy_command("test-lifecycle")
.expect("Failed to run destroy command");
// Assert: Both commands succeed
assert!(
destroy_result.success(),
"Destroy command failed: {}",
destroy_result.stderr()
);
// Assert: Environment is transitioned to Destroyed state
let env_assertions = EnvironmentStateAssertions::new(temp_workspace.path());
env_assertions.assert_environment_exists("test-lifecycle");
env_assertions.assert_environment_state_is("test-lifecycle", "Destroyed");
}