diff --git a/src/cluster.rs b/src/cluster.rs index e47a071..396f481 100644 --- a/src/cluster.rs +++ b/src/cluster.rs @@ -446,7 +446,7 @@ mod tests { let partition = Partition::default(); let resources = Resources { - processes: Processes::PerDirectory(1), + processes: Some(Processes::PerDirectory(1)), threads_per_process: Some(2), gpus_per_process: Some(3), ..Resources::default() @@ -461,7 +461,7 @@ mod tests { setup(); let resources = Resources { - processes: Processes::PerDirectory(1), + processes: Some(Processes::PerDirectory(1)), threads_per_process: Some(2), gpus_per_process: Some(3), ..Resources::default() @@ -564,12 +564,12 @@ mod tests { }; let cpu_resources = Resources { - processes: Processes::PerDirectory(1), + processes: Some(Processes::PerDirectory(1)), ..Resources::default() }; let gpu_resources = Resources { - processes: Processes::PerDirectory(1), + processes: Some(Processes::PerDirectory(1)), gpus_per_process: Some(1), ..Resources::default() }; diff --git a/src/expr.rs b/src/expr.rs index f12c3b8..0b76aed 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -67,6 +67,9 @@ pub(crate) fn evaluate_json_comparison( (_, None) => None, (_, _) => Some(false), } + +// TODO: Greater than or equal to +// TODO: Less than or equal to } #[cfg(test)] diff --git a/src/launcher.rs b/src/launcher.rs index 4cd87b1..41bf747 100644 --- a/src/launcher.rs +++ b/src/launcher.rs @@ -268,14 +268,14 @@ mod tests { assert_eq!(mpi.prefix(&one_proc, 1), "mpirun -n 1 "); let procs_per_directory = Resources { - processes: Processes::PerDirectory(2), + processes: Some(Processes::PerDirectory(2)), ..Resources::default() }; assert_eq!(mpi.prefix(&procs_per_directory, 11), "mpirun -n 22 "); assert_eq!(mpi.prefix(&procs_per_directory, 1), "mpirun -n 2 "); let all = Resources { - processes: Processes::PerDirectory(6), + processes: Some(Processes::PerDirectory(6)), threads_per_process: Some(3), gpus_per_process: Some(8), ..Resources::default() @@ -297,14 +297,14 @@ mod tests { assert_eq!(mpi.prefix(&one_proc, 1), "srun --ntasks=1 "); let procs_per_directory = Resources { - processes: Processes::PerDirectory(2), + processes: Some(Processes::PerDirectory(2)), ..Resources::default() }; assert_eq!(mpi.prefix(&procs_per_directory, 11), "srun --ntasks=22 "); assert_eq!(mpi.prefix(&procs_per_directory, 1), "srun --ntasks=2 "); let all = Resources { - processes: Processes::PerDirectory(6), + processes: Some(Processes::PerDirectory(6)), threads_per_process: Some(3), gpus_per_process: Some(8), ..Resources::default() diff --git a/src/scheduler/bash.rs b/src/scheduler/bash.rs index b150748..545d16c 100644 --- a/src/scheduler/bash.rs +++ b/src/scheduler/bash.rs @@ -318,18 +318,18 @@ mod tests { fn setup() -> (Action, Vec, HashMap) { let resources = Resources { - processes: Processes::PerDirectory(2), + processes: Some(Processes::PerDirectory(2)), threads_per_process: Some(4), gpus_per_process: Some(1), - walltime: Walltime::PerSubmission( - Duration::new(true, 0, 240, 0).expect("Valid duration."), + walltime: Some(Walltime::PerSubmission( + Duration::new(true, 0, 240, 0).expect("Valid duration.")), ), }; let action = Action { name: Some("action".to_string()), command: Some("command {directory}".to_string()), - launchers: vec!["mpi".into()], + launchers: Some(vec!["mpi".into()]), resources, ..Action::default() }; @@ -429,8 +429,8 @@ mod tests { #[parallel] fn execution_openmp() { let (mut action, directories, launchers) = setup(); - action.resources.processes = Processes::PerSubmission(1); - action.launchers = vec!["openmp".into()]; + action.resources.processes = Some(Processes::PerSubmission(1)); + action.launchers = Some(vec!["openmp".into()]); action.command = Some("command {directories}".to_string()); let script = BashScriptBuilder::new("cluster", &action, &directories, &launchers) @@ -445,7 +445,7 @@ mod tests { #[parallel] fn execution_mpi() { let (mut action, directories, launchers) = setup(); - action.launchers = vec!["mpi".into()]; + action.launchers = Some(vec!["mpi".into()]); action.command = Some("command {directories}".to_string()); let script = BashScriptBuilder::new("cluster", &action, &directories, &launchers) @@ -504,9 +504,9 @@ mod tests { #[parallel] fn more_variables() { let (mut action, directories, launchers) = setup(); - action.resources.processes = Processes::PerSubmission(10); + action.resources.processes = Some(Processes::PerSubmission(10)); action.resources.walltime = - Walltime::PerDirectory(Duration::new(true, 0, 60, 0).expect("Valid duration.")); + Some(Walltime::PerDirectory(Duration::new(true, 0, 60, 0).expect("Valid duration."))); action.resources.threads_per_process = None; action.resources.gpus_per_process = None; @@ -547,7 +547,7 @@ mod tests { #[parallel] fn launcher_required() { let (mut action, directories, launchers) = setup(); - action.launchers = vec![]; + action.launchers = Some(vec![]); action.command = Some("command {directories}".to_string()); let result = BashScriptBuilder::new("cluster", &action, &directories, &launchers).build(); @@ -559,8 +559,8 @@ mod tests { #[parallel] fn too_many_launchers() { let (mut action, directories, launchers) = setup(); - action.resources.processes = Processes::PerSubmission(1); - action.launchers = vec!["mpi".into(), "mpi".into()]; + action.resources.processes = Some(Processes::PerSubmission(1)); + action.launchers = Some(vec!["mpi".into(), "mpi".into()]); action.command = Some("command {directories}".to_string()); let result = BashScriptBuilder::new("cluster", &action, &directories, &launchers).build(); diff --git a/src/scheduler/slurm.rs b/src/scheduler/slurm.rs index be18b94..231d714 100644 --- a/src/scheduler/slurm.rs +++ b/src/scheduler/slurm.rs @@ -288,7 +288,7 @@ mod tests { let action = Action { name: Some("action".to_string()), command: Some("command {directory}".to_string()), - launchers: vec!["mpi".into()], + launchers: Some(vec!["mpi".into()]), ..Action::default() }; @@ -328,7 +328,7 @@ mod tests { fn ntasks() { let (mut action, directories, slurm) = setup(); - action.resources.processes = Processes::PerDirectory(3); + action.resources.processes = Some(Processes::PerDirectory(3)); let script = slurm .make_script(&action, &directories) @@ -483,7 +483,7 @@ mod tests { let slurm = Slurm::new(cluster, launchers.by_cluster("cluster")); - action.resources.processes = Processes::PerSubmission(81); + action.resources.processes = Some(Processes::PerSubmission(81)); let script = slurm .make_script(&action, &directories) @@ -511,7 +511,7 @@ mod tests { let slurm = Slurm::new(cluster, launchers.by_cluster("cluster")); - action.resources.processes = Processes::PerSubmission(81); + action.resources.processes = Some(Processes::PerSubmission(81)); action.resources.gpus_per_process = Some(1); let script = slurm diff --git a/src/workflow.rs b/src/workflow.rs index f15bafe..fe8ac67 100644 --- a/src/workflow.rs +++ b/src/workflow.rs @@ -170,6 +170,7 @@ pub enum Comparison { EqualTo, GreaterThan, } +// TODO: Possible to use <, >, <=, >=, ==? /// Group definition. #[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq)] @@ -697,7 +698,7 @@ mod tests { assert_eq!(workflow.root, temp.path().canonicalize().unwrap()); assert_eq!(workflow.workspace.path, PathBuf::from("workspace")); assert!(workflow.workspace.value_file.is_none()); - assert!(workflow.submit_options.is_empty()); + assert_eq!(workflow.default.action, Action::default()); assert!(workflow.action.is_empty()); } @@ -720,7 +721,7 @@ value_file = "s" #[parallel] fn submit_options_defaults() { let temp = TempDir::new().unwrap(); - let workflow = "[submit_options.a]"; + let workflow = "[default.action.submit_options.a]"; let workflow = Workflow::open_str(temp.path(), workflow).unwrap(); assert_eq!( @@ -728,10 +729,10 @@ value_file = "s" temp.path().canonicalize().unwrap() ); - assert_eq!(workflow.submit_options.len(), 1); - assert!(workflow.submit_options.contains_key("a")); + assert_eq!(workflow.default.action.submit_options.len(), 1); + assert!(workflow.default.action.submit_options.contains_key("a")); - let submit_options = workflow.submit_options.get("a").unwrap(); + let submit_options = workflow.default.action.submit_options.get("a").unwrap(); assert_eq!(submit_options.account, None); assert_eq!(submit_options.setup, None); assert!(submit_options.custom.is_empty()); @@ -743,7 +744,7 @@ value_file = "s" fn submit_options_nondefault() { let temp = TempDir::new().unwrap(); let workflow = r#" -[submit_options.a] +[default.action.submit_options.a] account = "my_account" setup = "module load openmpi" custom = ["--option1", "--option2"] @@ -756,10 +757,10 @@ partition = "gpu" temp.path().canonicalize().unwrap() ); - assert_eq!(workflow.submit_options.len(), 1); - assert!(workflow.submit_options.contains_key("a")); + assert_eq!(workflow.default.action.submit_options.len(), 1); + assert!(workflow.default.action.submit_options.contains_key("a")); - let submit_options = workflow.submit_options.get("a").unwrap(); + let submit_options = workflow.default.action.submit_options.get("a").unwrap(); assert_eq!(submit_options.account, Some(String::from("my_account"))); assert_eq!( submit_options.setup, @@ -783,17 +784,22 @@ command = "c" assert_eq!(workflow.action.len(), 1); let action = workflow.action.first().unwrap(); - assert_eq!(action.name, "b"); - assert_eq!(action.command, "c"); - assert!(action.previous_actions.is_empty()); - assert!(action.products.is_empty()); - assert!(action.launchers.is_empty()); - - assert_eq!(action.resources.processes, Processes::PerSubmission(1)); + assert_eq!(action.name(), "b"); + assert_eq!(action.command(), "c"); + assert!(action.previous_actions.is_none()); + assert!(action.products.is_none()); + assert!(action.launchers.is_none()); + + assert_eq!(action.resources.processes, None); + assert_eq!(action.resources.processes(), Processes::PerSubmission(1)); assert_eq!(action.resources.threads_per_process, None); assert_eq!(action.resources.gpus_per_process, None); assert_eq!( action.resources.walltime, + None, + ); + assert_eq!( + action.resources.walltime(), Walltime::PerDirectory(Duration::new(true, 0, 3600, 0).unwrap()) ); @@ -806,6 +812,9 @@ command = "c" assert!(!action.group.reverse_sort); } +// TODO: test action with no name +// TODO: test action with no command + #[test] #[parallel] fn group_defaults() { @@ -821,10 +830,6 @@ command = "c" assert_eq!(workflow.action.len(), 1); let action = workflow.action.first().unwrap(); - assert_eq!( - action.resources.walltime, - Walltime::PerDirectory(Duration::new(true, 0, 3600, 0).unwrap()) - ); assert!(action.submit_options.is_empty()); assert!(action.group.include.is_empty()); @@ -849,15 +854,10 @@ name = "b" command = "d" "#; let result = Workflow::open_str(temp.path(), workflow); - assert!( - result.is_err(), - "Expected duplicate action error, but got {result:?}" - ); + assert!(result.is_ok()); - assert!(result - .unwrap_err() - .to_string() - .starts_with("Found duplicate action")); + // TODO: Test that duplicates with different products fail + // TODO: Test that duplicates with different previous actions fail } #[test] @@ -876,7 +876,7 @@ launchers = ["openmp", "mpi"] assert_eq!(workflow.action.len(), 1); let action = workflow.action.first().unwrap(); - assert_eq!(action.launchers, vec!["openmp", "mpi"]); + assert_eq!(action.launchers(), vec!["openmp".to_string(), "mpi".to_string()]); } #[test] @@ -899,13 +899,13 @@ previous_actions = ["b"] assert_eq!(workflow.action.len(), 2); let action = workflow.action.get(1).unwrap(); - assert_eq!(action.previous_actions, vec!["b"]); + assert_eq!(action.previous_actions(), vec!["b".to_string()]); let action_a = workflow.action_by_name("b"); - assert_eq!(action_a.unwrap().command, "c"); + assert_eq!(action_a.unwrap().command(), "c"); let action_d = workflow.action_by_name("d"); - assert_eq!(action_d.unwrap().command, "e"); + assert_eq!(action_d.unwrap().command(), "e"); assert!(workflow.action_by_name("f").is_none()); } @@ -952,11 +952,11 @@ walltime.per_submission = "4d, 05:32:11" assert_eq!(workflow.action.len(), 1); let action = workflow.action.first().unwrap(); - assert_eq!(action.resources.processes, Processes::PerSubmission(12)); + assert_eq!(action.resources.processes(), Processes::PerSubmission(12)); assert_eq!(action.resources.threads_per_process, Some(8)); assert_eq!(action.resources.gpus_per_process, Some(1)); assert_eq!( - action.resources.walltime, + action.resources.walltime(), Walltime::PerSubmission( Duration::new(true, 4, 5 * 3600 + 32 * 60 + 11, 0) .expect("this should be a valid Duration"), @@ -982,10 +982,10 @@ walltime.per_directory = "00:01" assert_eq!(workflow.action.len(), 1); let action = workflow.action.first().unwrap(); - assert_eq!(action.resources.processes, Processes::PerDirectory(1)); + assert_eq!(action.resources.processes(), Processes::PerDirectory(1)); assert_eq!( - action.resources.walltime, + action.resources.walltime(), Walltime::PerDirectory( Duration::new(true, 0, 60, 0).expect("this should be a valid Duration") ) @@ -1057,7 +1057,7 @@ products = ["d", "e"] assert_eq!(workflow.action.len(), 1); let action = workflow.action.first().unwrap(); - assert_eq!(action.products, vec!["d".to_string(), "e".to_string()]); + assert_eq!(action.products(), vec!["d".to_string(), "e".to_string()]); } #[test] @@ -1200,7 +1200,7 @@ partition = "i" fn action_submit_options_global() { let temp = TempDir::new().unwrap(); let workflow = r#" -[submit_options.d] +[default.action.submit_options.d] account = "e" setup = "f" custom = ["g", "h"] @@ -1231,7 +1231,7 @@ command = "c" fn action_submit_options_no_override() { let temp = TempDir::new().unwrap(); let workflow = r#" -[submit_options.d] +[default.action.submit_options.d] account = "e" setup = "f" custom = ["g", "h"] @@ -1268,7 +1268,7 @@ partition = "n" fn action_submit_options_override() { let temp = TempDir::new().unwrap(); let workflow = r#" -[submit_options.d] +[default.action.submit_options.d] account = "e" setup = "f" custom = ["g", "h"] @@ -1296,11 +1296,17 @@ command = "c" assert_eq!(submit_options.partition, Some("i".to_string())); } +// TODO: Test action default all keys +// TODO: Test action from all keys +// TODO: Test action override from +// TODO: Test action override default +// TODO: Test action override mixed + #[test] #[parallel] fn total_processes() { let r = Resources { - processes: Processes::PerSubmission(10), + processes: Some(Processes::PerSubmission(10)), ..Resources::default() }; @@ -1309,7 +1315,7 @@ command = "c" assert_eq!(r.total_processes(1000), 10); let r = Resources { - processes: Processes::PerDirectory(10), + processes: Some(Processes::PerDirectory(10)), ..Resources::default() }; @@ -1322,7 +1328,7 @@ command = "c" #[parallel] fn total_cpus() { let r = Resources { - processes: Processes::PerSubmission(10), + processes: Some(Processes::PerSubmission(10)), threads_per_process: Some(2), ..Resources::default() }; @@ -1332,7 +1338,7 @@ command = "c" assert_eq!(r.total_cpus(1000), 20); let r = Resources { - processes: Processes::PerDirectory(10), + processes: Some(Processes::PerDirectory(10)), threads_per_process: None, ..Resources::default() }; @@ -1346,7 +1352,7 @@ command = "c" #[parallel] fn total_gpus() { let r = Resources { - processes: Processes::PerSubmission(10), + processes: Some(Processes::PerSubmission(10)), gpus_per_process: Some(2), ..Resources::default() }; @@ -1356,7 +1362,7 @@ command = "c" assert_eq!(r.total_gpus(1000), 20); let r = Resources { - processes: Processes::PerDirectory(10), + processes: Some(Processes::PerDirectory(10)), gpus_per_process: None, ..Resources::default() }; @@ -1370,7 +1376,7 @@ command = "c" #[parallel] fn total_walltime() { let r = Resources { - walltime: Walltime::PerDirectory(Duration::new(true, 1, 3600, 0).unwrap()), + walltime: Some(Walltime::PerDirectory(Duration::new(true, 1, 3600, 0).unwrap())), ..Resources::default() }; @@ -1388,7 +1394,7 @@ command = "c" ); let r = Resources { - walltime: Walltime::PerSubmission(Duration::new(true, 1, 3600, 0).unwrap()), + walltime: Some(Walltime::PerSubmission(Duration::new(true, 1, 3600, 0).unwrap())), ..Resources::default() }; @@ -1410,8 +1416,8 @@ command = "c" #[parallel] fn resource_cost() { let r = Resources { - processes: Processes::PerSubmission(10), - walltime: Walltime::PerDirectory(Duration::new(true, 0, 3600, 0).unwrap()), + processes: Some(Processes::PerSubmission(10)), + walltime: Some(Walltime::PerDirectory(Duration::new(true, 0, 3600, 0).unwrap())), ..Resources::default() }; @@ -1420,8 +1426,8 @@ command = "c" assert_eq!(r.cost(4), ResourceCost::with_values(40.0, 0.0)); let r = Resources { - processes: Processes::PerSubmission(10), - walltime: Walltime::PerDirectory(Duration::new(true, 0, 3600, 0).unwrap()), + processes: Some(Processes::PerSubmission(10)), + walltime: Some(Walltime::PerDirectory(Duration::new(true, 0, 3600, 0).unwrap())), threads_per_process: Some(4), ..Resources::default() }; @@ -1431,8 +1437,8 @@ command = "c" assert_eq!(r.cost(4), ResourceCost::with_values(160.0, 0.0)); let r = Resources { - processes: Processes::PerSubmission(10), - walltime: Walltime::PerDirectory(Duration::new(true, 0, 3600, 0).unwrap()), + processes: Some(Processes::PerSubmission(10)), + walltime: Some(Walltime::PerDirectory(Duration::new(true, 0, 3600, 0).unwrap())), threads_per_process: Some(4), gpus_per_process: Some(2), };