-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes #26340: Write a new test framework for the Rudder methods
- Loading branch information
Fdall
committed
Feb 12, 2025
1 parent
467186f
commit a801eed
Showing
25 changed files
with
952 additions
and
16 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
[package] | ||
name = "lib" | ||
version = "0.1.0" | ||
edition = "2021" | ||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
serde = { version = "1", features = ["derive"] } | ||
rudderc = { path = "../rudderc" } | ||
rudder_commons = { path = "../rudder-commons" } | ||
tempfile = "3.14.0" | ||
anyhow = "1.0.93" | ||
serde_json = "1.0.133" | ||
dyn-clone = "1.0.18" | ||
log = "0.4.22" | ||
itertools = "0.14.0" | ||
test-log = "*" | ||
serde_yaml = "0.9.34+deprecated" | ||
env_logger = "0.11.6" | ||
regex = "1.11.1" | ||
|
||
[dev-dependencies] | ||
test-log = "*" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
use crate::integration::{end_test, get_lib_path, init_test}; | ||
use crate::testlib::method_test_suite::MethodTestSuite; | ||
use crate::testlib::method_to_test::{MethodStatus, MethodToTest}; | ||
|
||
#[test] | ||
fn it_is_not_applicable_in_audit_mode() { | ||
let workdir = init_test(); | ||
let file_path = workdir.path().join("target.txt"); | ||
|
||
let tested_method = MethodToTest::command_execution(format!( | ||
"/bin/touch {}", | ||
file_path.clone().to_str().unwrap() | ||
)) | ||
.audit(); | ||
let r = MethodTestSuite::new() | ||
.when(tested_method.clone()) | ||
.execute(get_lib_path(), workdir.path().to_path_buf()); | ||
r.assert_legacy_result_conditions(tested_method.clone(), vec![MethodStatus::NA]); | ||
r.assert_log_v4_result_conditions(tested_method.clone(), MethodStatus::NA); | ||
assert!( | ||
!file_path.exists(), | ||
"The file '{}' should not have been created by the method execution", | ||
file_path.display() | ||
); | ||
end_test(workdir); | ||
} | ||
#[test] | ||
fn it_repairs_in_enforced_mode_if_the_command_succeeds() { | ||
let workdir = init_test(); | ||
let file_path = workdir.path().join("target.txt"); | ||
|
||
let tested_method = MethodToTest::command_execution(format!( | ||
"/bin/touch {}", | ||
file_path.clone().to_str().unwrap() | ||
)) | ||
.enforce(); | ||
let r = MethodTestSuite::new() | ||
.when(tested_method.clone()) | ||
.execute(get_lib_path(), workdir.path().to_path_buf()); | ||
r.assert_legacy_result_conditions(tested_method.clone(), vec![MethodStatus::Repaired]); | ||
r.assert_log_v4_result_conditions(tested_method.clone(), MethodStatus::Repaired); | ||
assert!( | ||
file_path.exists(), | ||
"The file '{}' should have been created by the method execution", | ||
file_path.display() | ||
); | ||
end_test(workdir); | ||
} | ||
#[test] | ||
fn it_errors_in_enforced_mode_if_the_command_fails() { | ||
let workdir = init_test(); | ||
let file_path = workdir.path().join("nonexistingfolder/target.txt"); | ||
|
||
let tested_method = MethodToTest::command_execution(format!( | ||
"/bin/touch {}", | ||
file_path.clone().to_str().unwrap() | ||
)) | ||
.enforce(); | ||
let r = MethodTestSuite::new() | ||
.when(tested_method.clone()) | ||
.execute(get_lib_path(), workdir.path().to_path_buf()); | ||
r.assert_legacy_result_conditions(tested_method.clone(), vec![MethodStatus::Error]); | ||
r.assert_log_v4_result_conditions(tested_method.clone(), MethodStatus::Error); | ||
assert!( | ||
!file_path.exists(), | ||
"The file '{}' should not have been created by the method execution", | ||
file_path.display() | ||
); | ||
end_test(workdir); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
use crate::integration::{end_test, get_lib_path, init_test}; | ||
use crate::testlib::given::Given; | ||
use crate::testlib::method_test_suite::MethodTestSuite; | ||
use crate::testlib::method_to_test::{MethodStatus, MethodToTest}; | ||
|
||
#[test] | ||
fn it_repairs_in_enforce_when_the_target_file_exists() { | ||
let workdir = init_test(); | ||
let file = workdir.path().join("file_to_remove"); | ||
let file_path = file.clone().to_string_lossy().into_owned(); | ||
|
||
let tested_method = MethodToTest::file_absent(file_path.clone()).enforce(); | ||
let r = MethodTestSuite::new() | ||
.given(Given::file_present(file_path.clone())) | ||
.when(tested_method.clone()) | ||
.execute(get_lib_path(), workdir.path().to_path_buf()); | ||
r.assert_legacy_result_conditions(tested_method, vec![MethodStatus::Repaired]); | ||
assert!( | ||
!file.exists(), | ||
"The file '{}' should have been removed by the method execution", | ||
file.display() | ||
); | ||
end_test(workdir); | ||
} | ||
|
||
#[test] | ||
fn it_errors_in_audit_when_the_target_file_exists() { | ||
let workdir = init_test(); | ||
let file = workdir.path().join("file_to_remove"); | ||
let file_path = file.clone().to_string_lossy().into_owned(); | ||
|
||
let tested_method = MethodToTest::file_absent(file_path.clone()).audit(); | ||
let r = MethodTestSuite::new() | ||
.given(Given::file_present(file_path.clone())) | ||
.when(tested_method.clone()) | ||
.execute(get_lib_path(), workdir.path().to_path_buf()); | ||
r.assert_legacy_result_conditions(tested_method, vec![MethodStatus::Error]); | ||
assert!( | ||
file.exists(), | ||
"The file '{}' should NOT have been removed by the method execution", | ||
file.display() | ||
); | ||
end_test(workdir); | ||
} | ||
|
||
#[test] | ||
fn it_errors_in_enforce_when_the_target_exists_and_is_a_directory() { | ||
let workdir = init_test(); | ||
let dir = workdir.path().join("dir_to_remove"); | ||
let file_path = dir.clone().to_string_lossy().into_owned(); | ||
let tested_method = MethodToTest::file_absent(file_path.clone()).enforce(); | ||
|
||
let r = MethodTestSuite::new() | ||
.given(Given::directory_present(file_path.clone())) | ||
.when(tested_method.clone()) | ||
.execute(get_lib_path(), workdir.path().to_path_buf()); | ||
r.assert_legacy_result_conditions(tested_method, vec![MethodStatus::Error]); | ||
assert!( | ||
dir.exists(), | ||
"The directory '{}' should not have been removed by the method execution", | ||
dir.display() | ||
); | ||
end_test(workdir); | ||
} | ||
|
||
#[ignore] | ||
#[test_log::test] | ||
fn it_should_be_idempotent() { | ||
let workdir = init_test(); | ||
let file = workdir.path().join("file_to_remove"); | ||
let file_path = file.clone().to_string_lossy().into_owned(); | ||
let tested_method = MethodToTest::file_absent(file_path.clone()).enforce(); | ||
|
||
let r = MethodTestSuite::new() | ||
.given(Given::file_present(file_path.clone())) | ||
.when(tested_method.clone()) | ||
.when(tested_method.clone()) | ||
.when(tested_method.clone()) | ||
.execute(get_lib_path(), workdir.path().to_path_buf()); | ||
r.assert_legacy_result_conditions( | ||
tested_method, | ||
vec![ | ||
MethodStatus::Repaired, | ||
MethodStatus::Success, | ||
MethodStatus::Success, | ||
], | ||
); | ||
assert!( | ||
!file.exists(), | ||
"The file '{}' should have been removed by the method execution", | ||
file.display() | ||
); | ||
end_test(workdir); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
use crate::integration::{end_test, get_lib_path, init_test}; | ||
use crate::testlib::given::Given; | ||
use crate::testlib::method_test_suite::MethodTestSuite; | ||
use crate::testlib::method_to_test::{MethodStatus, MethodToTest}; | ||
|
||
#[test] | ||
fn it_succeeds_in_enforce_when_the_target_file_exists() { | ||
let workdir = init_test(); | ||
let file_path = workdir | ||
.path() | ||
.join("flag_file") | ||
.to_string_lossy() | ||
.into_owned(); | ||
let tested_method = MethodToTest::file_check_exists(file_path.clone()).enforce(); | ||
|
||
let r = MethodTestSuite::new() | ||
.given(Given::file_present(file_path.clone())) | ||
.when(tested_method.clone()) | ||
.execute(get_lib_path(), workdir.path().to_path_buf()); | ||
r.assert_legacy_result_conditions(tested_method, vec![MethodStatus::Success]); | ||
end_test(workdir); | ||
} | ||
|
||
#[test] | ||
fn it_fails_in_enforce_when_the_target_file_does_not_exist() { | ||
let workdir = init_test(); | ||
let file_path = workdir | ||
.path() | ||
.join("flag_file") | ||
.to_string_lossy() | ||
.into_owned(); | ||
|
||
let tested_method = MethodToTest::file_check_exists(file_path.clone()).enforce(); | ||
let r = MethodTestSuite::new() | ||
.given(Given::file_absent(file_path.clone())) | ||
.when(tested_method.clone()) | ||
.execute(get_lib_path(), workdir.path().to_path_buf()); | ||
r.assert_legacy_result_conditions(tested_method, vec![MethodStatus::Error]); | ||
end_test(workdir); | ||
} | ||
|
||
#[test] | ||
fn it_succeeds_in_audit_when_the_target_file_exists() { | ||
let workdir = init_test(); | ||
let file_path = workdir | ||
.path() | ||
.join("flag_file") | ||
.to_string_lossy() | ||
.into_owned(); | ||
|
||
let tested_method = MethodToTest::file_check_exists(file_path.clone()).audit(); | ||
let r = MethodTestSuite::new() | ||
.given(Given::file_present(file_path.clone())) | ||
.when(tested_method.clone()) | ||
.execute(get_lib_path(), workdir.path().to_path_buf()); | ||
r.assert_legacy_result_conditions(tested_method, vec![MethodStatus::Success]); | ||
end_test(workdir); | ||
} | ||
#[test] | ||
fn it_succeeds_in_audit_when_the_target_file_does_not_exist() { | ||
let workdir = init_test(); | ||
let file_path = workdir | ||
.path() | ||
.join("flag_file") | ||
.to_string_lossy() | ||
.into_owned(); | ||
|
||
let tested_method = MethodToTest::file_check_exists(file_path.clone()).audit(); | ||
let r = MethodTestSuite::new() | ||
.given(Given::file_absent(file_path.clone())) | ||
.when(tested_method.clone()) | ||
.execute(get_lib_path(), workdir.path().to_path_buf()); | ||
r.assert_legacy_result_conditions(tested_method, vec![MethodStatus::Error]); | ||
end_test(workdir); | ||
} | ||
#[test] | ||
fn it_succeeds_in_enforce_when_the_target_is_a_directory() { | ||
let workdir = init_test(); | ||
let dir_path = workdir | ||
.path() | ||
.join("directory") | ||
.to_string_lossy() | ||
.into_owned(); | ||
|
||
let tested_method = MethodToTest::file_check_exists(dir_path.clone()).audit(); | ||
let r = MethodTestSuite::new() | ||
.given(Given::directory_present(dir_path.clone())) | ||
.when(tested_method.clone()) | ||
.execute(get_lib_path(), workdir.path().to_path_buf()); | ||
r.assert_legacy_result_conditions(tested_method, vec![MethodStatus::Success]); | ||
end_test(workdir); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#[cfg(test)] | ||
pub mod command_execution_test; | ||
#[cfg(test)] | ||
pub mod file_absent_test; | ||
#[cfg(test)] | ||
pub mod file_check_exists_test; | ||
use log::debug; | ||
use rudder_commons::methods::Methods; | ||
use std::mem::ManuallyDrop; | ||
use std::path::PathBuf; | ||
use std::sync::OnceLock; | ||
use tempfile::{tempdir, TempDir}; | ||
|
||
const LIBRARY_PATH: &str = "./tree"; | ||
pub fn get_lib() -> &'static Methods { | ||
static LIB: OnceLock<Methods> = OnceLock::new(); | ||
LIB.get_or_init(|| { | ||
rudderc::frontends::read_methods(&[get_lib_path()]) | ||
.unwrap() | ||
.clone() | ||
}) | ||
} | ||
fn get_lib_path() -> PathBuf { | ||
PathBuf::from(LIBRARY_PATH) | ||
} | ||
|
||
fn init_test() -> ManuallyDrop<TempDir> { | ||
env_logger::init(); | ||
let workdir = tempdir().unwrap(); | ||
debug!("WORKDIR = {:?}", workdir.path()); | ||
ManuallyDrop::new(workdir) | ||
} | ||
|
||
fn end_test(workdir: ManuallyDrop<TempDir>) { | ||
ManuallyDrop::into_inner(workdir); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pub mod integration; | ||
pub mod testlib; |
Oops, something went wrong.