mod common;
use common::*;
use predicates::prelude::*;
use std::sync::atomic::{AtomicU64, Ordering};
static TEST_COUNTER: AtomicU64 = AtomicU64::new(0);
fn setup_test_config() -> (tempfile::TempDir, String) {
let counter = TEST_COUNTER.fetch_add(1, Ordering::SeqCst);
let temp_dir = tempfile::TempDir::new().expect("Failed to create temp dir");
let config_path = temp_dir.path().join(format!("config-{}.toml", counter));
let config_path_str = config_path.to_str().expect("Invalid path").to_string();
(temp_dir, config_path_str)
}
fn crush_cmd_with_config(config_path: &str) -> assert_cmd::Command {
let mut cmd = crush_cmd();
cmd.env("CRUSH_TEST_CONFIG_FILE", config_path);
cmd
}
#[test]
fn test_config_set_and_get() {
let (_temp_dir, config_path) = setup_test_config();
crush_cmd_with_config(&config_path)
.arg("config")
.arg("set")
.arg("compression.level")
.arg("fast")
.assert()
.success();
let assert = crush_cmd_with_config(&config_path)
.arg("config")
.arg("get")
.arg("compression.level")
.assert()
.success();
let stdout = String::from_utf8(assert.get_output().stdout.clone()).unwrap();
assert!(stdout.contains("fast"), "Should show the set value");
}
#[test]
fn test_config_list() {
let (_temp_dir, config_path) = setup_test_config();
let assert = crush_cmd_with_config(&config_path)
.arg("config")
.arg("list")
.assert()
.success();
let stdout = String::from_utf8(assert.get_output().stdout.clone()).unwrap();
assert!(
stdout.contains("[compression]"),
"Should show compression section"
);
assert!(stdout.contains("[output]"), "Should show output section");
assert!(stdout.contains("[logging]"), "Should show logging section");
assert!(
stdout.contains("balanced") || stdout.contains("default-plugin"),
"Should show compression settings"
);
}
#[test]
fn test_config_reset() {
let (_temp_dir, config_path) = setup_test_config();
crush_cmd_with_config(&config_path)
.arg("config")
.arg("set")
.arg("compression.level")
.arg("best")
.assert()
.success();
crush_cmd_with_config(&config_path)
.arg("config")
.arg("reset")
.arg("--yes")
.assert()
.success();
let assert = crush_cmd_with_config(&config_path)
.arg("config")
.arg("get")
.arg("compression.level")
.assert()
.success();
let stdout = String::from_utf8(assert.get_output().stdout.clone()).unwrap();
assert!(
stdout.contains("balanced"),
"Should restore default value 'balanced'"
);
}
#[test]
fn test_config_invalid_key() {
let (_temp_dir, config_path) = setup_test_config();
crush_cmd_with_config(&config_path)
.arg("config")
.arg("get")
.arg("invalid.key.path")
.assert()
.failure()
.stderr(
predicate::str::contains("Invalid config key")
.or(predicate::str::contains("unknown"))
.or(predicate::str::contains("not found")),
);
}
#[test]
fn test_config_invalid_value() {
let (_temp_dir, config_path) = setup_test_config();
crush_cmd_with_config(&config_path)
.arg("config")
.arg("set")
.arg("compression.level")
.arg("invalid_level")
.assert()
.failure()
.stderr(predicate::str::contains("Invalid").or(predicate::str::contains("must be")));
}
#[test]
fn test_config_affects_compression() {
let (_temp_dir, config_path) = setup_test_config();
let dir = test_dir();
let test_data = b"config test data";
let input = create_test_file(dir.path(), "test.txt", test_data);
crush_cmd_with_config(&config_path)
.arg("config")
.arg("set")
.arg("compression.level")
.arg("fast")
.assert()
.success();
crush_cmd_with_config(&config_path)
.arg("compress")
.arg(&input)
.assert()
.success();
let output = dir.path().join("test.txt.crush");
assert_file_exists(&output);
}