Struct GooseAttack

Source
pub struct GooseAttack { /* private fields */ }
Expand description

Global internal state for the load test.

Implementations§

Source§

impl GooseAttack

Goose’s internal global state.

Source

pub fn initialize() -> Result<GooseAttack, GooseError>

Load configuration and initialize a GooseAttack.

§Example
use goose::prelude::*;

let mut goose_attack = GooseAttack::initialize();
Source

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);
Source

pub fn set_scheduler(self, scheduler: GooseScheduler) -> Self

Define the order Scenarios are allocated to new GooseUsers as they are launched.

By default, Scenarios are allocated to new GooseUsers 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, Scenarios are allocated to launching GooseUsers 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 GooseUsers 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(())
}
Source

pub fn register_scenario(self, scenario: Scenario) -> Self

A load test must contain one or more Scenarios 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(())
}
Source

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 GooseUsers 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(())
}
Source

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(())
}
Source

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§

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &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)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSend for T
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_sync(self: Box<T>) -> Box<dyn Any + Sync + Send>

Converts Box<Trait> (where Trait: DowncastSync) to Box<dyn Any + Send + Sync>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Converts Arc<Trait> (where Trait: DowncastSync) to Arc<Any>, which can then be downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> GooseUserData for T
where T: Send + Sync + 'static,