Compare commits

..

No commits in common. "52cb63951116b97cd7a6a4371c59316463f05b0c" and "053910c03f749f8d7c7ecf08d7a45a6ebfab8803" have entirely different histories.

2 changed files with 22 additions and 89 deletions

View File

@ -1,12 +1,10 @@
use std::io::Read; use std::io::Read;
use std::path::Path;
use std::path::PathBuf;
use std::str::FromStr; use std::str::FromStr;
use std::time::Duration; use std::time::Duration;
pub struct Conf { pub struct Conf {
pub job_dir: PathBuf, pub job_dir: String,
pub output_dir: PathBuf, pub output_dir: String,
pub check_interval: Duration, pub check_interval: Duration,
pub driver_url: String, pub driver_url: String,
} }
@ -14,15 +12,16 @@ pub struct Conf {
impl Conf { impl Conf {
pub fn get_default_conf() -> Conf { pub fn get_default_conf() -> Conf {
return Conf { return Conf {
job_dir: PathBuf::from_str("jobs.d").unwrap(), job_dir: String::from_str("jobs.d").unwrap(),
output_dir: PathBuf::from_str("results.d").unwrap(), output_dir: String::from_str("results.d").unwrap(),
check_interval: Duration::new(15*60, 0), check_interval: Duration::new(15*60, 0),
driver_url: String::from_str("http://localhost:4444").unwrap(), driver_url: String::from_str("http://localhost:4444").unwrap(),
}; };
} }
pub fn update_from_file(&mut self, path: &Path) { pub fn update_from_file(&mut self, f: &str) {
let mut file = match std::fs::File::open(path) { let path = std::path::Path::new(f);
let mut file = match std::fs::File::open(&path) {
Err(why) => { Err(why) => {
println!("Could not open file '{}': {}", path.display(), why); return; println!("Could not open file '{}': {}", path.display(), why); return;
}, },
@ -54,14 +53,12 @@ impl Conf {
match key { match key {
"job_dir" => { "job_dir" => {
println!("{} changed from '{}' to '{}' by line in '{}'", println!("{} changed from '{}' to '{}' by line in '{}'", key, self.job_dir, value, path.display());
key, self.job_dir.display(), value, path.display()); self.job_dir = String::from_str(value).unwrap();
self.job_dir = PathBuf::from_str(value).unwrap();
}, },
"output_dir" => { "output_dir" => {
println!("{} changed from '{}' to '{}' by line in '{}'", println!("{} changed from '{}' to '{}' by line in '{}'", key, self.output_dir, value, path.display());
key, self.output_dir.display(), value, path.display()); self.output_dir = String::from_str(value).unwrap();
self.output_dir = PathBuf::from_str(value).unwrap();
}, },
"check_interval" => { "check_interval" => {
let converted_value = match value.parse::<u64>() { let converted_value = match value.parse::<u64>() {
@ -89,19 +86,20 @@ mod tests {
use std::io::Write; use std::io::Write;
use std::str::FromStr; use std::str::FromStr;
use tempfile::NamedTempFile; use tempfile::NamedTempFile;
use std::time::Duration;
use super::*; use super::*;
fn write_conf_to_temp_file(content: &str) -> NamedTempFile { fn write_conf_to_temp_file(content: &str) -> NamedTempFile {
let mut f = NamedTempFile::new().unwrap(); let mut f = NamedTempFile::new().unwrap();
f.write_all(content.as_bytes()).expect("Failed to write configuration to file"); f.write_all(content.as_bytes());
return f; return f;
} }
#[test] #[test]
fn test_not_existing() { fn test_not_existing() {
let mut conf = Conf::get_default_conf(); let mut conf = Conf::get_default_conf();
conf.update_from_file(Path::new("/not/a/real/file")); conf.update_from_file("/not/a/real/file");
} }
#[test] #[test]
@ -113,9 +111,10 @@ output_dir=/var/lib/output
check_interval=3600 check_interval=3600
driver_url = https://example.test:6666 driver_url = https://example.test:6666
"#); "#);
conf.update_from_file(tf.path()); let f = tf.path().to_str().unwrap();
assert!(Path::new("/val=ue").eq(&conf.job_dir)); conf.update_from_file(f);
assert!(Path::new("/var/lib/output").eq(&conf.output_dir)); assert!(String::from_str("/val=ue").unwrap().eq(&conf.job_dir));
assert!(String::from_str("/var/lib/output").unwrap().eq(&conf.output_dir));
assert!(String::from_str("https://example.test:6666").unwrap().eq(&conf.driver_url)); assert!(String::from_str("https://example.test:6666").unwrap().eq(&conf.driver_url));
assert_eq!(3600, conf.check_interval.as_secs()); assert_eq!(3600, conf.check_interval.as_secs());
} }
@ -126,7 +125,8 @@ driver_url = https://example.test:6666
let tf = write_conf_to_temp_file(r#" let tf = write_conf_to_temp_file(r#"
check_interval=d3600 check_interval=d3600
"#); "#);
conf.update_from_file(tf.path()); let f = tf.path().to_str().unwrap();
conf.update_from_file(f);
assert_eq!(15*60, conf.check_interval.as_secs()); assert_eq!(15*60, conf.check_interval.as_secs());
} }

View File

@ -1,6 +1,5 @@
use std::cmp::Ordering; use std::cmp::Ordering;
use std::env; use std::env;
use std::path::Path;
use std::thread; use std::thread;
use std::time::Duration; use std::time::Duration;
use std::time::Instant; use std::time::Instant;
@ -44,48 +43,20 @@ impl ThreadJob<'_> {
} }
} }
fn verify_directory(dir: &Path) -> bool {
let md = match std::fs::metadata(&dir) {
Err(why) => {
println!("Cannot stat directory '{}': {}", dir.display(), why);
return false;
},
Ok(val) => val,
};
if !md.is_dir() {
println!("Output directory '{}' is not a directory", dir.display());
return false;
}
if md.permissions().readonly() {
println!("Output directory '{}' is read-only", dir.display());
return false;
}
return true;
}
fn main() { fn main() {
let mut conf = Conf::get_default_conf(); let mut conf = Conf::get_default_conf();
conf.update_from_file(Path::new("/etc/haunter/haunter.conf")); conf.update_from_file("/etc/haunter/haunter.conf");
let mut args = env::args(); let mut args = env::args();
while let Some(arg) = args.next() { while let Some(arg) = args.next() {
if arg.eq("-f") { if arg.eq("-f") {
match args.next() { match args.next() {
Some(file) => conf.update_from_file(Path::new(&file)), Some(file) => conf.update_from_file(file.as_str()),
_ => {println!("Missing argument after '-f'"); std::process::exit(1);}, _ => {println!("Missing argument after '-f'"); std::process::exit(1);},
}; };
} }
} }
if !verify_directory(&conf.output_dir) {
println!("Output directory unusable, aborting");
std::process::exit(1);
}
if !verify_directory(&conf.job_dir) {
println!("Output job unusable, aborting");
std::process::exit(1);
}
let mut jobs = Vec::new(); let mut jobs = Vec::new();
let some_job = Job { let some_job = Job {
url: "https://www.rust-lang.org", url: "https://www.rust-lang.org",
@ -185,41 +156,3 @@ fn get_source(driver: &str, url: &str) -> Result<String, &'static str> {
driver.quit().expect("failed to close session"); driver.quit().expect("failed to close session");
return Ok(source); return Ok(source);
} }
#[cfg(test)]
mod tests {
use super::*;
use tempfile;
#[test]
fn verify_directory_exists_but_is_file() {
let tf = tempfile::NamedTempFile::new().unwrap();
assert!(!verify_directory(tf.path()));
}
#[test]
fn verify_directory_does_not_exist() {
assert!(!verify_directory(Path::new("/fake/path/that/does/not/exist")));
}
#[test]
fn verify_directory_exists() {
let tf = tempfile::tempdir().unwrap();
assert!(verify_directory(tf.path()));
}
#[test]
fn verify_directory_exists_but_is_not_writable() {
let tf = tempfile::tempdir().unwrap();
let md = std::fs::metadata(&tf.path()).unwrap();
let mut perms = md.permissions();
perms.set_readonly(true);
std::fs::set_permissions(&tf.path(), perms).expect("Failed to set temp dir read-only");
let result = verify_directory(tf.path());
perms = md.permissions();
perms.set_readonly(false);
std::fs::set_permissions(&tf.path(), perms).expect("Failed to set temp dir writable");
assert!(!result);
}
}