From 387a58ec97d4ee8f0919540a50f63a66b0c68839 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Mon, 13 May 2024 12:22:17 -0400 Subject: [PATCH] Test missing name and command. --- src/lib.rs | 6 +++++ src/workflow.rs | 68 ++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 19f698d..b57ffcf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -126,6 +126,12 @@ pub enum Error { #[error("Cannot compare {0} and {1} while checking directory '{2}'.")] CannotCompareInclude(Value, Value, PathBuf), + #[error("Action at index {0} is missing name.")] + ActionMissingName(usize), + + #[error("Action '{0}' is missing command.")] + ActionMissingCommand(String), + // submission errors #[error("Error encountered while executing action '{0}': {1}.")] ExecuteAction(String, String), diff --git a/src/workflow.rs b/src/workflow.rs index fe8ac67..9747fdb 100644 --- a/src/workflow.rs +++ b/src/workflow.rs @@ -115,6 +115,9 @@ pub struct Action { /// The group of jobs to submit. #[serde(default)] pub group: Group, + + // Name of the group to copy defaults from. + pub from: Option, } /// Default tables @@ -547,13 +550,20 @@ impl Workflow { fn validate_and_set_defaults(mut self) -> Result { let mut action_names = HashSet::with_capacity(self.action.len()); - for action in &mut self.action { + for (action_idx, action) in self.action.iter_mut().enumerate() { //TODO: implement from, validate no recursive from's action.resolve(&self.default.action); action_names.insert(action.name().to_string()); trace!("Validating action '{}'.", action.name()); + if action.name == None { + return Err(Error::ActionMissingName(action_idx)); + } + if action.command == None { + return Err(Error::ActionMissingCommand(action.name().into())); + } + // Warn for apparently invalid sort_by. for pointer in &action.group.sort_by { if !pointer.is_empty() && !pointer.starts_with('/') { @@ -812,9 +822,34 @@ command = "c" assert!(!action.group.reverse_sort); } -// TODO: test action with no name -// TODO: test action with no command + #[test] + #[parallel] + fn action_no_name() { + let temp = TempDir::new().unwrap(); + let workflow = r#" +[[action]] +command = "c" +"#; + let result = Workflow::open_str(temp.path(), workflow); + assert!(result.is_err()); + assert!(result.unwrap_err().to_string().contains("missing name")); + } + + #[test] + #[parallel] + fn action_no_command() { + let temp = TempDir::new().unwrap(); + let workflow = r#" +[[action]] +name = "a" +"#; + let result = Workflow::open_str(temp.path(), workflow); + assert!(result.is_err()); + + assert!(result.unwrap_err().to_string().contains("missing command")); + } + #[test] #[parallel] fn group_defaults() { @@ -1296,6 +1331,33 @@ command = "c" assert_eq!(submit_options.partition, Some("i".to_string())); } + #[test] + #[parallel] + fn empty_action_default() { + let temp = TempDir::new().unwrap(); + let workflow = r#" +[default.action] +"#; + + let workflow = Workflow::open_str(temp.path(), workflow).unwrap(); + + assert_eq!(workflow.action.len(), 0); + + let action = workflow.default.action; + assert_eq!(action.name, None); + assert_eq!(action.command, None); + assert_eq!(action.launchers, None); + assert_eq!(action.previous_actions, None); + assert_eq!(action.products, None); + assert_eq!(action.resources.processes, None); + assert_eq!(action.resources.threads_per_process, None); + assert_eq!(action.resources.gpus_per_process, None); + assert_eq!(action.resources.walltime, None); + assert!(action.submit_options.is_empty()); + // TODO: Group + assert_eq!(action.from, None); + } + // TODO: Test action default all keys // TODO: Test action from all keys // TODO: Test action override from