135 lines
4.6 KiB
Rust
135 lines
4.6 KiB
Rust
use std::io::Read;
|
|
use std::path::Path;
|
|
use std::path::PathBuf;
|
|
use std::str::FromStr;
|
|
use std::time::Duration;
|
|
|
|
pub struct Conf {
|
|
pub job_dir: PathBuf,
|
|
pub output_dir: PathBuf,
|
|
pub check_interval: Duration,
|
|
pub driver_url: String,
|
|
}
|
|
|
|
impl Conf {
|
|
pub fn get_default_conf() -> Conf {
|
|
return Conf {
|
|
job_dir: PathBuf::from_str("jobs.d").unwrap(),
|
|
output_dir: PathBuf::from_str("results.d").unwrap(),
|
|
check_interval: Duration::new(15*60, 0),
|
|
driver_url: String::from_str("http://localhost:4444").unwrap(),
|
|
};
|
|
}
|
|
|
|
pub fn update_from_file(&mut self, path: &Path) {
|
|
let mut file = match std::fs::File::open(path) {
|
|
Err(why) => {
|
|
println!("Could not open file '{}': {}", path.display(), why); return;
|
|
},
|
|
Ok(file) => file,
|
|
};
|
|
let mut content = String::new();
|
|
match file.read_to_string(&mut content) {
|
|
Err(why) => println!("Could not read from file '{}': {}", path.display(), why),
|
|
Ok(_) => (),
|
|
}
|
|
|
|
let lines = content.lines();
|
|
for line in lines {
|
|
if line.starts_with('#') {
|
|
continue;
|
|
}
|
|
let result = line.split_once('=');
|
|
if result.is_none() {
|
|
println!("Skipping configuration line '{}', no key-value delimiter (=) found", line);
|
|
continue;
|
|
}
|
|
|
|
let key = result.unwrap().0.trim();
|
|
let value = result.unwrap().1.trim();
|
|
if key.eq("") || value.eq("") {
|
|
println!("Skipping configuration line '{}', no key or value side is empty", line);
|
|
continue;
|
|
}
|
|
|
|
match key {
|
|
"job_dir" => {
|
|
println!("{} changed from '{}' to '{}' by line in '{}'",
|
|
key, self.job_dir.display(), value, path.display());
|
|
self.job_dir = PathBuf::from_str(value).unwrap();
|
|
},
|
|
"output_dir" => {
|
|
println!("{} changed from '{}' to '{}' by line in '{}'",
|
|
key, self.output_dir.display(), value, path.display());
|
|
self.output_dir = PathBuf::from_str(value).unwrap();
|
|
},
|
|
"check_interval" => {
|
|
let converted_value = match value.parse::<u64>() {
|
|
Err(why) => { println!("Failed to convert '{}' to u64: {}", value, why); continue;},
|
|
Ok(v) => v,
|
|
};
|
|
println!("{} changed from '{}' to '{}' by line in '{}'", key, self.check_interval.as_secs(), value, path.display());
|
|
self.check_interval = Duration::new(converted_value, 0);
|
|
},
|
|
"driver_url" => {
|
|
println!("{} changed from '{}' to '{}' by line in '{}'", key, self.driver_url, value, path.display());
|
|
self.driver_url = String::from_str(value).unwrap();
|
|
}
|
|
_ => {
|
|
println!("Unknown key '{}' in file '{}'", key, path.display());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
|
|
use std::io::Write;
|
|
use std::str::FromStr;
|
|
use tempfile::NamedTempFile;
|
|
|
|
use super::*;
|
|
|
|
fn write_conf_to_temp_file(content: &str) -> NamedTempFile {
|
|
let mut f = NamedTempFile::new().unwrap();
|
|
f.write_all(content.as_bytes()).expect("Failed to write configuration to file");
|
|
return f;
|
|
}
|
|
|
|
#[test]
|
|
fn test_not_existing() {
|
|
let mut conf = Conf::get_default_conf();
|
|
conf.update_from_file(Path::new("/not/a/real/file"));
|
|
}
|
|
|
|
#[test]
|
|
fn test_set_all_values() {
|
|
let mut conf = Conf::get_default_conf();
|
|
let tf = write_conf_to_temp_file(r#"
|
|
job_dir = /val=ue
|
|
# this line is ignored, and the white space on the next line is intentional
|
|
output_dir=/var/lib/output
|
|
check_interval=3600
|
|
driver_url = https://example.test:6666
|
|
"#);
|
|
conf.update_from_file(tf.path());
|
|
assert!(Path::new("/val=ue").eq(&conf.job_dir));
|
|
assert!(Path::new("/var/lib/output").eq(&conf.output_dir));
|
|
assert!(String::from_str("https://example.test:6666").unwrap().eq(&conf.driver_url));
|
|
assert_eq!(3600, conf.check_interval.as_secs());
|
|
}
|
|
|
|
#[test]
|
|
fn test_non_numeric_check_interval_fails() {
|
|
let mut conf = Conf::get_default_conf();
|
|
let tf = write_conf_to_temp_file(r#"
|
|
check_interval=d3600
|
|
"#);
|
|
conf.update_from_file(tf.path());
|
|
assert_eq!(15*60, conf.check_interval.as_secs());
|
|
|
|
}
|
|
}
|