Struct swanling::SwanlingAttack[][src]

pub struct SwanlingAttack { /* fields omitted */ }
Expand description

Global internal state for the load test.

Implementations

Swanling’s internal global state.

Load configuration and initialize a SwanlingAttack.

Example

use swanling::prelude::*;

let mut swanling_attack = SwanlingAttack::initialize();

Initialize a SwanlingAttack with an already loaded configuration.

This is generally used by Worker instances and tests.

Example

use swanling::{SwanlingAttack, SwanlingConfiguration};
use gumdrop::Options;

let configuration = SwanlingConfiguration::parse_args_default_or_exit();
let mut swanling_attack = SwanlingAttack::initialize_with_config(configuration);

Define the order SwanlingTaskSets are allocated to new SwanlingUsers as they are launched.

By default, SwanlingTaskSets are allocated to new SwanlingUsers in a round robin style. For example, if TaskSet A has a weight of 5, TaskSet 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, SwanlingTaskSets are allocated to launching SwanlingUsers 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 SwanlingUsers running each SwanlingTaskSet each time.

Example

use swanling::prelude::*;

fn main() -> Result<(), SwanlingError> {
    SwanlingAttack::initialize()?
        .set_scheduler(SwanlingScheduler::Random)
        .register_taskset(taskset!("A Tasks")
            .set_weight(5)?
            .register_task(task!(a_task_1))
        )
        .register_taskset(taskset!("B Tasks")
            .set_weight(3)?
            .register_task(task!(b_task_1))
        );

    Ok(())
}

async fn a_task_1(user: &SwanlingUser) -> SwanlingTaskResult {
    let _swanling = user.get("/foo").await?;

    Ok(())
}

async fn b_task_1(user: &SwanlingUser) -> SwanlingTaskResult {
    let _swanling = user.get("/bar").await?;

    Ok(())
}

A load test must contain one or more SwanlingTaskSets be registered into Swanling’s global state with this method for it to run.

Example

use swanling::prelude::*;

fn main() -> Result<(), SwanlingError> {
    SwanlingAttack::initialize()?
        .register_taskset(taskset!("ExampleTasks")
            .register_task(task!(example_task))
        )
        .register_taskset(taskset!("OtherTasks")
            .register_task(task!(other_task))
        );

    Ok(())
}

async fn example_task(user: &SwanlingUser) -> SwanlingTaskResult {
    let _swanling = user.get("/foo").await?;

    Ok(())
}

async fn other_task(user: &SwanlingUser) -> SwanlingTaskResult {
    let _swanling = user.get("/bar").await?;

    Ok(())
}

Optionally define a task to run before users are started and all task sets start running. This is would generally be used to set up anything required for the load test.

The SwanlingUser used to run the test_start tasks is not preserved and does not otherwise affect the subsequent SwanlingUsers that run the rest of the load test. For example, if the SwanlingUser logs in during test_start, subsequent SwanlingUser do not retain this session and are therefor not already logged in.

When running in a distributed Regatta, this task is only run one time by the Manager.

Example

use swanling::prelude::*;

fn main() -> Result<(), SwanlingError> {
    SwanlingAttack::initialize()?
        .test_start(task!(setup));

    Ok(())
}

async fn setup(user: &SwanlingUser) -> SwanlingTaskResult {
    // do stuff to set up load test ...

    Ok(())
}

Optionally define a task to run after all users have finished running all defined task sets. This would generally be used to clean up anything that was specifically set up for the load test.

When running in a distributed Regatta, this task is only run one time by the Manager.

Example

use swanling::prelude::*;

fn main() -> Result<(), SwanlingError> {
    SwanlingAttack::initialize()?
        .test_stop(task!(teardown));

    Ok(())
}

async fn teardown(user: &SwanlingUser) -> SwanlingTaskResult {
    // do stuff to tear down the load test ...

    Ok(())
}

Execute the SwanlingAttack load test.

Example

use swanling::prelude::*;

fn main() -> Result<(), SwanlingError> {
    let _swanling_metrics = SwanlingAttack::initialize()?
        .register_taskset(taskset!("ExampleTasks")
            .register_task(task!(example_task).set_weight(2)?)
            .register_task(task!(another_example_task).set_weight(3)?)
            // Swanling 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(SwanlingDefault::RunTime, 1)?
        .execute()?;

    Ok(())
}

async fn example_task(user: &SwanlingUser) -> SwanlingTaskResult {
    let _swanling = user.get("/foo").await?;

    Ok(())
}

async fn another_example_task(user: &SwanlingUser) -> SwanlingTaskResult {
    let _swanling = user.get("/bar").await?;

    Ok(())
}

Trait Implementations

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Performs the conversion.

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

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

Performs the conversion.

Should always be Self

The resulting type after obtaining ownership.

Creates owned data from borrowed data, usually by cloning. Read more

🔬 This is a nightly-only experimental API. (toowned_clone_into)

recently added

Uses borrowed data to replace owned data, usually by cloning. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.