use std::collections::HashMap;
use std::io::Error;
use std::path::PathBuf;
use std::time::Instant;
pub trait JobInfo: Send {
fn path(&self) -> PathBuf;
fn jobid(&self) -> String;
fn moment(&self) -> Instant;
fn cluster(&self) -> String;
fn hostname(&self) -> String;
fn read_job_info(&mut self) -> Result<(), Error>;
fn files(&self) -> Vec<(String, Vec<u8>)>;
fn script(&self) -> String;
fn extra_info(&self) -> Option<HashMap<String, String>>;
}
#[cfg(test)]
mod tests {
use std::collections::HashMap;
use std::thread::sleep;
use std::time::{Duration, Instant};
use super::*;
#[derive(Debug)]
struct DummyJobInfo {
job_id: String,
moment: Instant,
cluster: String,
hostname: String,
script: String,
extra_info: Option<HashMap<String, String>>,
files: Vec<(String, Vec<u8>)>,
}
impl DummyJobInfo {
fn new(
job_id: &str,
cluster: &str,
hostname: &str,
script: &str,
extra_info: Option<HashMap<String, String>>,
) -> Self {
DummyJobInfo {
job_id: job_id.to_string(),
moment: Instant::now(),
cluster: cluster.to_string(),
hostname: hostname.to_string(),
script: script.to_string(),
extra_info,
files: Vec::new(),
}
}
fn add_file(&mut self, filename: &str, contents: Vec<u8>) {
self.files.push((filename.to_string(), contents));
}
}
impl JobInfo for DummyJobInfo {
fn path(&self) -> PathBuf {
PathBuf::from("/tmp/test")
}
fn jobid(&self) -> String {
self.job_id.clone()
}
fn moment(&self) -> Instant {
self.moment
}
fn cluster(&self) -> String {
self.cluster.clone()
}
fn hostname(&self) -> String {
self.hostname.clone()
}
fn read_job_info(&mut self) -> Result<(), Error> {
sleep(Duration::from_millis(50));
self.add_file("file1.txt", b"file1 contents".to_vec());
self.add_file("file2.txt", b"file2 contents".to_vec());
Ok(())
}
fn files(&self) -> Vec<(String, Vec<u8>)> {
self.files.clone()
}
fn script(&self) -> String {
self.script.clone()
}
fn extra_info(&self) -> Option<HashMap<String, String>> {
self.extra_info.clone()
}
}
#[test]
fn test_jobid() {
let job_info = DummyJobInfo::new("job123", "cluster1", "master", "script1", None);
assert_eq!(job_info.jobid(), "job123");
}
#[test]
fn test_moment() {
let job_info = DummyJobInfo::new("job123", "cluster1", "master", "script1", None);
assert!(job_info.moment() <= Instant::now());
}
#[test]
fn test_cluster() {
let job_info = DummyJobInfo::new("job123", "cluster1", "master", "script1", None);
assert_eq!(job_info.cluster(), "cluster1");
}
#[test]
fn test_hostname() {
let job_info = DummyJobInfo::new("job123", "cluster1", "master", "script1", None);
assert_eq!(job_info.hostname(), "master");
}
#[test]
fn test_read_job_info() {
let mut job_info = DummyJobInfo::new("job123", "cluster1", "master", "script1", None);
assert!(job_info.files().is_empty());
job_info.read_job_info().unwrap();
assert_eq!(job_info.files().len(), 2);
}
#[test]
fn test_script() {
let job_info = DummyJobInfo::new("job123", "cluster1", "master", "script1", None);
assert_eq!(job_info.script(), "script1");
}
#[test]
fn test_extra_info() {
let extra_info = {
let mut map = HashMap::new();
map.insert("key1".to_string(), "value1".to_string());
map.insert("key2".to_string(), "value2".to_string());
map
};
let job_info = DummyJobInfo::new(
"job123",
"cluster1",
"master",
"script1",
Some(extra_info.clone()),
);
assert_eq!(job_info.extra_info(), Some(extra_info));
}
}