Skip to content

Add unit tests for parse_duration_string() #17

@cbaugus

Description

@cbaugus

Summary

The parse_duration_string() function parses duration strings like "10m", "5h", "3d" but has no test coverage. This function is used for critical configuration values (test duration, ramp duration) and errors here could cause tests to run for incorrect periods.

Current Implementation

fn parse_duration_string(s: &str) -> Result<Duration, String> {
    let s = s.trim();
    if s.is_empty() {
        return Err("Empty duration string".to_string());
    }
    let (num_str, suffix) = s.split_at(s.len() - 1);
    let num: u64 = num_str.parse().map_err(|e| format!("Invalid number: {}", e))?;
    match suffix {
        "s" => Ok(Duration::from_secs(num)),
        "m" => Ok(Duration::from_secs(num * 60)),
        "h" => Ok(Duration::from_secs(num * 60 * 60)),
        "d" => Ok(Duration::from_secs(num * 60 * 60 * 24)),
        _ => Err(format!("Unknown duration suffix: {}", suffix)),
    }
}

Test Cases Required

Valid Inputs

  • "10s" → 10 seconds
  • "5m" → 300 seconds
  • "2h" → 7200 seconds
  • "1d" → 86400 seconds
  • "0s" → 0 seconds (edge case)
  • "1s" → 1 second (minimum)
  • " 10m " → 600 seconds (whitespace trimming)
  • Large values: "365d" → 31536000 seconds

Invalid Inputs

  • "" → Error: empty string
  • "10" → Error: no suffix
  • "m" → Error: no number
  • "10x" → Error: unknown suffix
  • "-5m" → Error: negative number
  • "5.5h" → Error: fractional number
  • "abc" → Error: not a number

Edge Cases

  • "s" → Error (single char, no number)
  • "10M" → Error (case sensitivity - uppercase M)
  • "10 m" → Error (space between number and suffix)

Acceptance Criteria

  • All valid duration formats tested (s, m, h, d)
  • All error cases return appropriate error messages
  • Whitespace handling verified
  • Edge cases covered
  • Tests are clear and document expected behavior

Example Test Structure

#[cfg(test)]
mod duration_tests {
    use super::*;

    #[test]
    fn test_seconds() {
        assert_eq!(parse_duration_string("10s").unwrap(), Duration::from_secs(10));
    }

    #[test]
    fn test_minutes() {
        assert_eq!(parse_duration_string("5m").unwrap(), Duration::from_secs(300));
    }

    #[test]
    fn test_hours() {
        assert_eq!(parse_duration_string("2h").unwrap(), Duration::from_secs(7200));
    }

    #[test]
    fn test_days() {
        assert_eq!(parse_duration_string("1d").unwrap(), Duration::from_secs(86400));
    }

    #[test]
    fn test_whitespace_trimmed() {
        assert_eq!(parse_duration_string("  10m  ").unwrap(), Duration::from_secs(600));
    }

    #[test]
    fn test_empty_string_error() {
        assert!(parse_duration_string("").is_err());
    }

    #[test]
    fn test_unknown_suffix_error() {
        let result = parse_duration_string("10x");
        assert!(result.is_err());
        assert!(result.unwrap_err().contains("Unknown duration suffix"));
    }

    #[test]
    fn test_invalid_number_error() {
        assert!(parse_duration_string("abcs").is_err());
    }
}

Priority

Medium - Incorrect duration parsing could cause tests to run for wrong periods, but the function is simple and errors would likely be caught during manual testing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions