Skip to content

Commit

Permalink
handle canceling load test
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremyandrews committed Apr 27, 2022
1 parent 949a8ae commit d67094b
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 12 deletions.
53 changes: 48 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,8 @@ struct GooseAttackRunState {
/// Thread-safe boolean flag indicating if the [`GooseAttack`](./struct.GooseAttack.html)
/// has been canceled.
canceled: Arc<AtomicBool>,
/// Whether or not the load test is currently canceling.
canceling: bool,
/// Optional socket used to coordinate a distributed Gaggle.
socket: Option<Socket>,
}
Expand Down Expand Up @@ -1299,6 +1301,7 @@ impl GooseAttack {
all_users_spawned: false,
shutdown_after_stop: !self.configuration.no_autostart,
canceled: Arc::new(AtomicBool::new(false)),
canceling: false,
socket,
};

Expand Down Expand Up @@ -1529,6 +1532,46 @@ impl GooseAttack {
Ok(())
}

// Quickly abort and shut down an active [`GooseAttack`](./struct.GooseAttack.html).
async fn cancel_attack(
&mut self,
goose_attack_run_state: &mut GooseAttackRunState,
) -> Result<(), GooseError> {
// Determine how long has elapsed since this step started.
let elapsed = if let Some(step_started) = self.step_started {
step_started.elapsed().as_millis() as usize
} else if let Some(started) = self.started {
started.elapsed().as_millis() as usize
} else {
unreachable!("the load test had to have started");
};

// Reset the test_plan to stop all users quickly.
self.test_plan.steps = vec![
// Record how many active users there are currently.
(goose_attack_run_state.active_users, elapsed),
// Record how long the attack ran in this step.
(0, 0),
];
// Reset the current step to what was happening when canceled.
self.test_plan.current = 0;

// Moving to the last phase, reset adjust_user_in_ms.
goose_attack_run_state.adjust_user_in_ms = 0;

// Advance to the final decrease phase.
self.advance_test_plan(goose_attack_run_state);

// Load test isn't just decreasing, it's canceling.
self.metrics
.history
.last_mut()
.expect("tried to cancel load test with no history")
.action = TestPlanStepAction::Canceling;

Ok(())
}

// Decrease the number of active [`GooseUser`](./goose/struct.GooseUser.html) threads in the
// active [`GooseAttack`](./struct.GooseAttack.html).
async fn decrease_attack(
Expand Down Expand Up @@ -1864,6 +1907,7 @@ impl GooseAttack {

// Gracefully exit loop if ctrl-c is caught.
if self.attack_phase != AttackPhase::Shutdown
&& !goose_attack_run_state.canceling
&& goose_attack_run_state.canceled.load(Ordering::SeqCst)
{
// Shutdown after stopping as the load test was canceled.
Expand All @@ -1875,11 +1919,10 @@ impl GooseAttack {
}

// Cleanly stop the load test.
self.set_attack_phase(&mut goose_attack_run_state, AttackPhase::Decrease);
self.metrics.history.push(TestPlanHistory::step(
TestPlanStepAction::Decreasing,
goose_attack_run_state.active_users,
));
self.cancel_attack(&mut goose_attack_run_state).await?;

// Load test is actively canceling.
goose_attack_run_state.canceling = true;
}
}

Expand Down
9 changes: 4 additions & 5 deletions src/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2122,7 +2122,7 @@ impl GooseMetrics {
)?;
}
// For decreasing show the new number of users from the current number of users.
TestPlanStepAction::Decreasing => {
TestPlanStepAction::Decreasing | TestPlanStepAction::Canceling => {
writeln!(
fmt,
" {:<12} {} - {} ({:02}:{:02}:{:02}, {} <- {})",
Expand Down Expand Up @@ -2410,12 +2410,11 @@ impl GooseAttack {
goose_attack_run_state.active_users
);
}
// Restart the timer now that all threads are launched.
self.started = Some(std::time::Instant::now());
} else {
println!("{} users hatched.", goose_attack_run_state.active_users);
}

// Restart the timer now that all threads are launched.
self.started = Some(std::time::Instant::now());
}

Ok(())
Expand Down Expand Up @@ -2672,7 +2671,7 @@ impl GooseAttack {
));
}
// For decreasing show the new number of users from the current number of users.
TestPlanStepAction::Decreasing => {
TestPlanStepAction::Decreasing | TestPlanStepAction::Canceling => {
steps_overview.push_str(&format!(
"<tr><td>{:?}</td><td>{}</td><td>{}</td><td>{:02}:{:02}:{:02}</td><td>{} &larr; {}</td></tr>",
step[0].action,
Expand Down
4 changes: 3 additions & 1 deletion src/test_plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,10 @@ pub enum TestPlanStepAction {
Increasing,
/// A test plan step that is maintaining the number of GooseUser threads.
Maintaining,
/// A test plan step that is increasing the number of GooseUser threads.
/// A test plan step that is decreasing the number of GooseUser threads.
Decreasing,
/// A test plan step that is canceling all GooseUser threads.
Canceling,
/// The final step indicating that the load test is finished.
Finished,
}
Expand Down
2 changes: 1 addition & 1 deletion tests/defaults.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const EXPECT_WORKERS: usize = 2;
// Increase, Increase, Decrease, Increase, Maintain, Decrease, Decrease
const TEST_PLAN: &str = "4,1;8,1;4,2;10,2;10,1;4,1;0,1";
const TEST_PLAN_MAX_USERS: usize = 10;
const TEST_PLAN_RUN_TIME: usize = 8;
const TEST_PLAN_RUN_TIME: usize = 9;
const TEST_PLAN_STEPS: usize = 7;

// There are multiple test variations in this file.
Expand Down

0 comments on commit d67094b

Please sign in to comment.