Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#222: Allow naming of tasks without naming requests #580

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
100 changes: 71 additions & 29 deletions src/goose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,11 @@ impl Scenario {
/// }
/// ```
pub fn register_transaction(mut self, mut transaction: Transaction) -> Self {
trace!("{} register_transaction: {}", self.name, transaction.name);
trace!(
"{} register_transaction: {}",
self.name,
transaction.name.name_for_transaction()
);
transaction.transactions_index = self.transactions.len();
self.transactions.push(transaction);
self
Expand Down Expand Up @@ -830,7 +834,7 @@ pub struct GooseUser {
/// An optional index into [`Scenario`]`.transaction`, indicating which transaction this is.
pub(crate) transaction_index: Option<String>,
/// Current transaction name, if set.
pub(crate) transaction_name: Option<String>,
pub(crate) transaction_name: Option<TransactionName>,
/// Client used to make requests, managing sessions and cookies.
pub client: Client,
/// The base URL to prepend to all relative paths.
Expand Down Expand Up @@ -1562,15 +1566,15 @@ impl GooseUser {
.map_or_else(|| "", |v| v.as_ref()),
transaction_name: self
.transaction_name
.as_ref()
.map_or_else(|| "", |v| v.as_ref()),
.clone()
.unwrap_or(TransactionName::default_value()),
};

// Record information about the request.
let mut request_metric = GooseRequestMetric::new(
raw_request,
transaction_detail,
request_name,
request_name.as_str(),
self.started.elapsed().as_millis(),
self.weighted_users_index,
);
Expand Down Expand Up @@ -1628,7 +1632,7 @@ impl GooseUser {
warn!("{:?}: {}", &path, e);
request_metric.success = false;
request_metric.set_status_code(None);
request_metric.error = clean_reqwest_error(e, request_name);
request_metric.error = clean_reqwest_error(e, request_name.as_str());
}
};

Expand Down Expand Up @@ -1763,7 +1767,10 @@ impl GooseUser {
&& request_metric.response_time > self.request_cadence.user_cadence
{
let transaction_name = if let Some(transaction_name) = &self.transaction_name {
format!(", transaction name: \"{}\"", transaction_name)
format!(
", transaction name: \"{}\"",
transaction_name.name_for_transaction()
)
} else {
"".to_string()
};
Expand Down Expand Up @@ -1826,18 +1833,19 @@ impl GooseUser {

/// If `request_name` is set, unwrap and use this. Otherwise, if the Transaction has a name
/// set use it. Otherwise use the path.
fn get_request_name<'a>(&'a self, request: &'a GooseRequest) -> &'a str {
fn get_request_name(&self, request: &GooseRequest) -> String {
match request.name {
// If a request.name is set, unwrap and return it.
Some(rn) => rn,
Some(rn) => rn.to_string(),
None => {
// Otherwise determine if the current Transaction is named, and if so return it.
if let Some(transaction_name) = &self.transaction_name {
transaction_name
} else {
// Otherwise return a copy of the the path.
request.path
let request_name = transaction_name.name_for_request();
if !request_name.is_empty() {
return request_name;
}
}
request.path.to_string()
}
}
}
Expand Down Expand Up @@ -2722,14 +2730,38 @@ pub type TransactionFunction = Arc<
+ Sync,
>;

#[derive(Clone, Deserialize, Serialize, Hash, PartialEq, Eq, Debug)]
pub enum TransactionName {
InheritNameByRequests(String),
TransactionOnly(String),
}

impl TransactionName {
pub fn name_for_transaction(&self) -> String {
match self {
TransactionName::InheritNameByRequests(v) => v.to_string(),
TransactionName::TransactionOnly(v) => v.to_string(),
}
}
pub fn name_for_request(&self) -> String {
match self {
TransactionName::InheritNameByRequests(v) => v.to_string(),
TransactionName::TransactionOnly(_) => "".to_string(),
}
}
pub fn default_value() -> Self {
Self::InheritNameByRequests("".to_string())
}
}

/// An individual transaction within a [`Scenario`](./struct.Scenario.html).
#[derive(Clone)]
pub struct Transaction {
/// An index into [`Scenario`](./struct.Scenario.html)`.transaction`, indicating which
/// transaction this is.
pub transactions_index: usize,
/// An optional name for the transaction, used when displaying metrics.
pub name: String,
pub name: TransactionName,
/// An integer value that controls the frequency that this transaction will be run.
pub weight: usize,
/// An integer value that controls when this transaction runs compared to other transactions in the same
Expand All @@ -2747,7 +2779,7 @@ impl Transaction {
trace!("new transaction");
Transaction {
transactions_index: usize::max_value(),
name: "".to_string(),
name: TransactionName::default_value(),
weight: 1,
sequence: 0,
on_start: false,
Expand All @@ -2774,8 +2806,18 @@ impl Transaction {
/// }
/// ```
pub fn set_name(mut self, name: &str) -> Self {
trace!("[{}] set_name: {}", self.transactions_index, self.name);
self.name = name.to_string();
trace!("[{}] set_name: {}", self.transactions_index, name);
self.name = TransactionName::InheritNameByRequests(name.to_string());
self
}

pub fn set_name_transaction_only(mut self, name: &str) -> Self {
trace!(
"[{}] set_name (for transaction only): {}",
self.transactions_index,
name
);
self.name = TransactionName::TransactionOnly(name.to_string());
self
}

Expand Down Expand Up @@ -2804,7 +2846,7 @@ impl Transaction {
pub fn set_on_start(mut self) -> Self {
trace!(
"{} [{}] set_on_start transaction",
self.name,
self.name.name_for_transaction(),
self.transactions_index
);
self.on_start = true;
Expand Down Expand Up @@ -2836,7 +2878,7 @@ impl Transaction {
pub fn set_on_stop(mut self) -> Self {
trace!(
"{} [{}] set_on_stop transaction",
self.name,
self.name.name_for_transaction(),
self.transactions_index
);
self.on_stop = true;
Expand Down Expand Up @@ -2867,7 +2909,7 @@ impl Transaction {
pub fn set_weight(mut self, weight: usize) -> Result<Self, GooseError> {
trace!(
"{} [{}] set_weight: {}",
self.name,
self.name.name_for_transaction(),
self.transactions_index,
weight
);
Expand Down Expand Up @@ -2955,14 +2997,14 @@ impl Transaction {
pub fn set_sequence(mut self, sequence: usize) -> Self {
trace!(
"{} [{}] set_sequence: {}",
self.name,
self.name.name_for_transaction(),
self.transactions_index,
sequence
);
if sequence < 1 {
info!(
"setting sequence to 0 for transaction {} is unnecessary, sequence disabled",
self.name
self.name.name_for_transaction()
);
}
self.sequence = sequence;
Expand Down Expand Up @@ -3114,28 +3156,28 @@ mod tests {
// Initialize scenario.
let mut transaction = transaction!(test_function_a);
assert_eq!(transaction.transactions_index, usize::max_value());
assert_eq!(transaction.name, "".to_string());
assert_eq!(transaction.name.name_for_transaction(), "".to_string());
assert_eq!(transaction.weight, 1);
assert_eq!(transaction.sequence, 0);
assert!(!transaction.on_start);
assert!(!transaction.on_stop);

// Name can be set, without affecting other fields.
transaction = transaction.set_name("foo");
assert_eq!(transaction.name, "foo".to_string());
assert_eq!(transaction.name.name_for_transaction(), "foo".to_string());
assert_eq!(transaction.weight, 1);
assert_eq!(transaction.sequence, 0);
assert!(!transaction.on_start);
assert!(!transaction.on_stop);

// Name can be set multiple times.
transaction = transaction.set_name("bar");
assert_eq!(transaction.name, "bar".to_string());
assert_eq!(transaction.name.name_for_transaction(), "bar".to_string());

// On start flag can be set, without affecting other fields.
transaction = transaction.set_on_start();
assert!(transaction.on_start);
assert_eq!(transaction.name, "bar".to_string());
assert_eq!(transaction.name.name_for_transaction(), "bar".to_string());
assert_eq!(transaction.weight, 1);
assert_eq!(transaction.sequence, 0);
assert!(!transaction.on_stop);
Expand All @@ -3149,7 +3191,7 @@ mod tests {
transaction = transaction.set_on_stop();
assert!(transaction.on_stop);
assert!(transaction.on_start);
assert_eq!(transaction.name, "bar".to_string());
assert_eq!(transaction.name.name_for_transaction(), "bar".to_string());
assert_eq!(transaction.weight, 1);
assert_eq!(transaction.sequence, 0);

Expand All @@ -3162,7 +3204,7 @@ mod tests {
assert_eq!(transaction.weight, 2);
assert!(transaction.on_stop);
assert!(transaction.on_start);
assert_eq!(transaction.name, "bar".to_string());
assert_eq!(transaction.name.name_for_transaction(), "bar".to_string());
assert_eq!(transaction.sequence, 0);

// Weight field can be changed multiple times.
Expand All @@ -3175,7 +3217,7 @@ mod tests {
assert_eq!(transaction.weight, 3);
assert!(transaction.on_stop);
assert!(transaction.on_start);
assert_eq!(transaction.name, "bar".to_string());
assert_eq!(transaction.name.name_for_transaction(), "bar".to_string());

// Sequence field can be changed multiple times.
transaction = transaction.set_sequence(8);
Expand Down
21 changes: 11 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ use tokio::fs::File;

use crate::config::{GooseConfiguration, GooseDefaults};
use crate::controller::{ControllerProtocol, ControllerRequest};
use crate::goose::{GooseUser, GooseUserCommand, Scenario, Transaction};
use crate::goose::{GooseUser, GooseUserCommand, Scenario, Transaction, TransactionName};
use crate::graph::GraphData;
use crate::logger::{GooseLoggerJoinHandle, GooseLoggerTx};
use crate::metrics::{GooseMetric, GooseMetrics};
Expand All @@ -86,7 +86,7 @@ lazy_static! {
}

/// Internal representation of a weighted transaction list.
type WeightedTransactions = Vec<(usize, String)>;
type WeightedTransactions = Vec<(usize, TransactionName)>;

/// Internal representation of unsequenced transactions.
type UnsequencedTransactions = Vec<Transaction>;
Expand Down Expand Up @@ -884,7 +884,8 @@ impl GooseAttack {
for transaction in scenario.transactions {
println!(
" o {} (weight: {})",
transaction.name, transaction.weight
transaction.name.name_for_transaction(),
transaction.weight
);
}
}
Expand Down Expand Up @@ -2007,39 +2008,39 @@ fn allocate_transactions(
for transaction in scheduled_sequenced_on_start_transactions.iter() {
on_start_transactions.extend(vec![(
*transaction,
scenario.transactions[*transaction].name.to_string(),
scenario.transactions[*transaction].name.clone(),
)])
}
for transaction in scheduled_sequenced_transactions.iter() {
transactions.extend(vec![(
*transaction,
scenario.transactions[*transaction].name.to_string(),
scenario.transactions[*transaction].name.clone(),
)])
}
for transaction in scheduled_sequenced_on_stop_transactions.iter() {
on_stop_transactions.extend(vec![(
*transaction,
scenario.transactions[*transaction].name.to_string(),
scenario.transactions[*transaction].name.clone(),
)])
}

// Unsequenced transactions come last.
for transaction in scheduled_unsequenced_on_start_transactions.iter() {
on_start_transactions.extend(vec![(
*transaction,
scenario.transactions[*transaction].name.to_string(),
scenario.transactions[*transaction].name.clone(),
)])
}
for transaction in scheduled_unsequenced_transactions.iter() {
transactions.extend(vec![(
*transaction,
scenario.transactions[*transaction].name.to_string(),
scenario.transactions[*transaction].name.clone(),
)])
}
for transaction in scheduled_unsequenced_on_stop_transactions.iter() {
on_stop_transactions.extend(vec![(
*transaction,
scenario.transactions[*transaction].name.to_string(),
scenario.transactions[*transaction].name.clone(),
)])
}

Expand All @@ -2061,7 +2062,7 @@ fn weight_unsequenced_transactions(
trace!(
"{}: {} has weight of {} (reduced with gcd to {})",
transaction.transactions_index,
transaction.name,
transaction.name.name_for_transaction(),
transaction.weight,
weight
);
Expand Down
2 changes: 1 addition & 1 deletion src/logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ impl GooseLogger<GooseRequestMetric> for GooseConfiguration {
message.scenario_index,
message.scenario_name,
message.transaction_index,
message.transaction_name,
message.transaction_name.name_for_request(),
format!("{:?}", message.raw),
message.name,
message.final_url,
Expand Down