Skip to content

Add unit tests for LoadModel calculations #16

@cbaugus

Description

@cbaugus

Summary

The LoadModel enum and its calculate_current_rps() method contain critical business logic for determining request rates, but have zero test coverage. This is a significant gap as incorrect calculations could lead to unexpected load patterns during testing.

Current State

LoadModel has four variants with complex calculation logic:

  • Concurrent - No RPS limit (returns None)
  • Rps { target_rps } - Constant rate
  • RampRps { min_rps, max_rps, ramp_duration } - Linear ramp with 3 phases
  • DailyTraffic { ... } - 6-phase daily pattern simulation

Test coverage: 0%

Test Cases Required

Concurrent Model

#[test]
fn test_concurrent_returns_none() {
    let model = LoadModel::Concurrent;
    assert_eq!(model.calculate_current_rps(Duration::from_secs(0), Duration::from_secs(100)), None);
}

Rps Model

  • Returns constant target_rps regardless of elapsed time
  • Works with fractional RPS values (e.g., 0.5)
  • Works with high RPS values (e.g., 10000.0)

RampRps Model

  • Returns min_rps at elapsed time 0
  • Returns value between min and max during ramp-up phase
  • Returns max_rps at end of ramp-up
  • Returns max_rps during sustain phase (middle third)
  • Returns value between max and min during ramp-down phase
  • Returns min_rps at end of test
  • Linear interpolation is mathematically correct
  • Edge case: min_rps == max_rps
  • Edge case: very short ramp_duration

DailyTraffic Model

  • Phase 1 (morning_ramp): Linear increase from night_rps to peak_rps
  • Phase 2 (peak_sustain): Constant peak_rps
  • Phase 3 (midday_decline): Linear decrease from peak_rps to midday_rps
  • Phase 4 (midday_sustain): Constant midday_rps
  • Phase 5 (evening_decline): Linear decrease from midday_rps to night_rps
  • Phase 6 (night_sustain): Constant night_rps
  • Cycle wrapping works correctly (day 2, day 3, etc.)
  • Phase boundaries are calculated correctly
  • Edge case: elapsed time exactly at phase boundary

Acceptance Criteria

  • All LoadModel variants have test coverage
  • All phase transitions tested for RampRps and DailyTraffic
  • Edge cases covered (boundary values, zero duration, equal min/max)
  • Linear interpolation verified with mathematical precision (within f64 epsilon)
  • Tests document expected behavior clearly
  • cargo test passes with all new tests

Example Test Structure

#[cfg(test)]
mod tests {
    use super::*;
    use std::time::Duration;

    mod concurrent {
        use super::*;
        // tests...
    }

    mod rps {
        use super::*;
        // tests...
    }

    mod ramp_rps {
        use super::*;
        
        #[test]
        fn test_returns_min_at_start() {
            let model = LoadModel::RampRps {
                min_rps: 10.0,
                max_rps: 100.0,
                ramp_duration: Duration::from_secs(60),
            };
            let total = Duration::from_secs(180);
            let rps = model.calculate_current_rps(Duration::ZERO, total).unwrap();
            assert!((rps - 10.0).abs() < 0.001);
        }
        
        #[test]
        fn test_midpoint_of_ramp_up() {
            let model = LoadModel::RampRps {
                min_rps: 0.0,
                max_rps: 100.0,
                ramp_duration: Duration::from_secs(60),
            };
            let total = Duration::from_secs(180);
            let rps = model.calculate_current_rps(Duration::from_secs(30), total).unwrap();
            assert!((rps - 50.0).abs() < 0.001);
        }
    }

    mod daily_traffic {
        use super::*;
        // tests...
    }
}

Priority

High - This is core business logic that affects the accuracy of load tests. Bugs here could cause tests to generate incorrect load patterns.

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