Struct goose::GooseAttack
source · pub struct GooseAttack { /* private fields */ }
Expand description
Global internal state for the load test.
Implementations§
source§impl GooseAttack
impl GooseAttack
Goose’s internal global state.
sourcepub fn initialize() -> Result<GooseAttack, GooseError>
pub fn initialize() -> Result<GooseAttack, GooseError>
Load configuration and initialize a GooseAttack
.
Example
use goose::prelude::*;
let mut goose_attack = GooseAttack::initialize();
sourcepub fn initialize_with_config(
configuration: GooseConfiguration
) -> Result<GooseAttack, GooseError>
pub fn initialize_with_config( configuration: GooseConfiguration ) -> Result<GooseAttack, GooseError>
Initialize a GooseAttack
with an already loaded
configuration.
This is generally used by Worker instances and tests.
Example
use goose::GooseAttack;
use goose::config::GooseConfiguration;
use gumdrop::Options;
let configuration = GooseConfiguration::parse_args_default_or_exit();
let mut goose_attack = GooseAttack::initialize_with_config(configuration);
sourcepub fn set_scheduler(self, scheduler: GooseScheduler) -> Self
pub fn set_scheduler(self, scheduler: GooseScheduler) -> Self
Define the order Scenario
s are
allocated to new GooseUser
s as they are
launched.
By default, Scenario
s are allocated
to new GooseUser
s in a round robin style.
For example, if Scenario A has a weight of 5, Scenario B has a weight of 3, and
you launch 20 users, they will be launched in the following order:
A, B, A, B, A, B, A, A, A, B, A, B, A, B, A, A, A, B, A, B
Note that the following pattern is repeated: A, B, A, B, A, B, A, A
If reconfigured to schedule serially, then they will instead be allocated in the following order: A, A, A, A, A, B, B, B, A, A, A, A, A, B, B, B, A, A, A, A
In the serial case, the following pattern is repeated: A, A, A, A, A, B, B, B
In the following example, Scenario
s
are allocated to launching GooseUser
s in a
random order. This means running the test multiple times can generate
different amounts of load, as depending on your weighting rules you may
have a different number of GooseUser
s
running each Scenario
each time.
Example
use goose::prelude::*;
#[tokio::main]
async fn main() -> Result<(), GooseError> {
GooseAttack::initialize()?
.set_scheduler(GooseScheduler::Random)
.register_scenario(scenario!("A Scenario")
.set_weight(5)?
.register_transaction(transaction!(a_transaction))
)
.register_scenario(scenario!("B Scenario")
.set_weight(3)?
.register_transaction(transaction!(b_transaction))
);
Ok(())
}
async fn a_transaction(user: &mut GooseUser) -> TransactionResult {
let _goose = user.get("/foo").await?;
Ok(())
}
async fn b_transaction(user: &mut GooseUser) -> TransactionResult {
let _goose = user.get("/bar").await?;
Ok(())
}
sourcepub fn register_scenario(self, scenario: Scenario) -> Self
pub fn register_scenario(self, scenario: Scenario) -> Self
A load test must contain one or more Scenario
s
be registered into Goose’s global state with this method for it to run.
Example
use goose::prelude::*;
#[tokio::main]
async fn main() -> Result<(), GooseError> {
GooseAttack::initialize()?
.register_scenario(scenario!("ExampleScenario")
.register_transaction(transaction!(example_transaction))
)
.register_scenario(scenario!("OtherScenario")
.register_transaction(transaction!(other_transaction))
);
Ok(())
}
async fn example_transaction(user: &mut GooseUser) -> TransactionResult {
let _goose = user.get("/foo").await?;
Ok(())
}
async fn other_transaction(user: &mut GooseUser) -> TransactionResult {
let _goose = user.get("/bar").await?;
Ok(())
}
sourcepub fn test_start(self, transaction: Transaction) -> Self
pub fn test_start(self, transaction: Transaction) -> Self
Optionally define a transaction to run before users are started and all transactions start running. This is would generally be used to set up anything required for the load test.
The GooseUser
used to run the test_start
transactions is not preserved and does not otherwise affect the subsequent
GooseUser
s that run the rest of the load
test. For example, if the GooseUser
logs in during test_start
, subsequent GooseUser
do not retain this session and are therefor not already logged in.
Example
use goose::prelude::*;
#[tokio::main]
async fn main() -> Result<(), GooseError> {
GooseAttack::initialize()?
.test_start(transaction!(setup));
Ok(())
}
async fn setup(user: &mut GooseUser) -> TransactionResult {
// do stuff to set up load test ...
Ok(())
}
sourcepub fn test_stop(self, transaction: Transaction) -> Self
pub fn test_stop(self, transaction: Transaction) -> Self
Optionally define a transaction to run after all users have finished running all defined transactions. This would generally be used to clean up anything that was specifically set up for the load test.
Example
use goose::prelude::*;
#[tokio::main]
async fn main() -> Result<(), GooseError> {
GooseAttack::initialize()?
.test_stop(transaction!(teardown));
Ok(())
}
async fn teardown(user: &mut GooseUser) -> TransactionResult {
// do stuff to tear down the load test ...
Ok(())
}
sourcepub async fn execute(self) -> Result<GooseMetrics, GooseError>
pub async fn execute(self) -> Result<GooseMetrics, GooseError>
Execute the GooseAttack
load test.
Example
use goose::prelude::*;
#[tokio::main]
async fn main() -> Result<(), GooseError> {
let _goose_metrics = GooseAttack::initialize()?
.register_scenario(scenario!("ExampleTransaction")
.register_transaction(transaction!(example_transaction).set_weight(2)?)
.register_transaction(transaction!(another_example_transaction).set_weight(3)?)
// Goose must run against a host, point to localhost so test starts.
.set_host("http://localhost")
)
// Exit after one second so test doesn't run forever.
.set_default(GooseDefault::RunTime, 1)?
.execute()
.await?;
Ok(())
}
async fn example_transaction(user: &mut GooseUser) -> TransactionResult {
let _goose = user.get("/foo").await?;
Ok(())
}
async fn another_example_transaction(user: &mut GooseUser) -> TransactionResult {
let _goose = user.get("/bar").await?;
Ok(())
}
Trait Implementations§
source§impl GooseDefaultType<&str> for GooseAttack
impl GooseDefaultType<&str> for GooseAttack
source§fn set_default(
self,
key: GooseDefault,
value: &str
) -> Result<Box<Self>, GooseError>
fn set_default( self, key: GooseDefault, value: &str ) -> Result<Box<Self>, GooseError>
Sets GooseDefault
to a &str
value.
source§impl GooseDefaultType<GooseCoordinatedOmissionMitigation> for GooseAttack
impl GooseDefaultType<GooseCoordinatedOmissionMitigation> for GooseAttack
source§fn set_default(
self,
key: GooseDefault,
value: GooseCoordinatedOmissionMitigation
) -> Result<Box<Self>, GooseError>
fn set_default( self, key: GooseDefault, value: GooseCoordinatedOmissionMitigation ) -> Result<Box<Self>, GooseError>
Sets GooseDefault
to a GooseCoordinatedOmissionMitigation
value.
source§impl GooseDefaultType<GooseLogFormat> for GooseAttack
impl GooseDefaultType<GooseLogFormat> for GooseAttack
source§fn set_default(
self,
key: GooseDefault,
value: GooseLogFormat
) -> Result<Box<Self>, GooseError>
fn set_default( self, key: GooseDefault, value: GooseLogFormat ) -> Result<Box<Self>, GooseError>
Sets GooseDefault
to a GooseLogFormat
value.
source§impl GooseDefaultType<bool> for GooseAttack
impl GooseDefaultType<bool> for GooseAttack
source§fn set_default(
self,
key: GooseDefault,
value: bool
) -> Result<Box<Self>, GooseError>
fn set_default( self, key: GooseDefault, value: bool ) -> Result<Box<Self>, GooseError>
Sets GooseDefault
to a bool
value.
source§impl GooseDefaultType<usize> for GooseAttack
impl GooseDefaultType<usize> for GooseAttack
source§fn set_default(
self,
key: GooseDefault,
value: usize
) -> Result<Box<Self>, GooseError>
fn set_default( self, key: GooseDefault, value: usize ) -> Result<Box<Self>, GooseError>
Sets GooseDefault
to a usize
value.
Auto Trait Implementations§
impl !RefUnwindSafe for GooseAttack
impl Send for GooseAttack
impl Sync for GooseAttack
impl Unpin for GooseAttack
impl !UnwindSafe for GooseAttack
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere T: Any,
source§fn into_any(self: Box<T, Global>) -> Box<dyn Any, Global>
fn into_any(self: Box<T, Global>) -> Box<dyn Any, Global>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
. Box<dyn Any>
can
then be further downcast
into Box<ConcreteType>
where ConcreteType
implements Trait
.source§fn into_any_rc(self: Rc<T, Global>) -> Rc<dyn Any, Global>
fn into_any_rc(self: Rc<T, Global>) -> Rc<dyn Any, Global>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.