// k6 Tags and Groups
// Enhanced support for tagging and grouping
///| Tag Management
///|
/// Tag set for organizing test metrics
pub struct TagSet {
tags : Map[String, String]
}
///|
/// Create new tag set
pub fn TagSet::new() -> TagSet {
{ tags: Map::new() }
}
///|
/// Add a tag
pub fn TagSet::add(self : TagSet, key : String, value : String) -> TagSet {
let tags = self.tags
tags.set(key, value)
{ tags, }
}
///|
/// Add multiple tags
pub fn TagSet::add_all(self : TagSet, tags : Map[String, String]) -> TagSet {
let current_tags = self.tags
tags.each(fn(k, v) { current_tags.set(k, v) })
{ tags: current_tags }
}
///|
/// Remove a tag
pub fn TagSet::remove(self : TagSet, key : String) -> TagSet {
let tags = self.tags
tags.remove(key)
{ tags, }
}
///|
/// Get tag value
pub fn TagSet::get(self : TagSet, key : String) -> String? {
self.tags.get(key)
}
///|
/// Convert to map
pub fn TagSet::to_map(self : TagSet) -> Map[String, String] {
self.tags
}
///| Common Tag Builders
///|
/// Create environment tag
pub fn tag_environment(env : String) -> (String, String) {
("environment", env)
}
///|
/// Create test type tag
pub fn tag_test_type(test_type : String) -> (String, String) {
("test_type", test_type)
}
///|
/// Create API version tag
pub fn tag_api_version(version : String) -> (String, String) {
("api_version", version)
}
///|
/// Create region tag
pub fn tag_region(region : String) -> (String, String) {
("region", region)
}
///|
/// Create user type tag
pub fn tag_user_type(user_type : String) -> (String, String) {
("user_type", user_type)
}
///|
/// Create scenario tag
pub fn tag_scenario(scenario : String) -> (String, String) {
("scenario", scenario)
}
///| Group Management
///|
/// Group configuration
pub struct GroupConfig {
name : String
tags : Map[String, String]
}
///|
/// Create group config
pub fn GroupConfig::new(name : String) -> GroupConfig {
{ name, tags: Map::new() }
}
///|
/// Add tag to group
pub fn GroupConfig::tag(self : GroupConfig, key : String, value : String) -> GroupConfig {
let tags = self.tags
tags.set(key, value)
{ ..self, tags }
}
///|
/// Execute group with config
pub fn[T : Default] GroupConfig::run(
self : GroupConfig,
body : () -> T
) -> T {
// k6's group function doesn't support tags directly
// But we can use the RequestBuilder tag system
group(self.name, body)
}
///| Nested Groups
///|
/// Run nested groups with different tags
pub fn[T : Default] nested_group(
parent_name : String,
child_name : String,
body : () -> T
) -> T {
group(parent_name, fn() {
group(child_name, body)
})
}
///|
/// Run multiple groups in sequence
pub fn run_groups(groups : Array[(String, () -> Unit)]) -> Unit {
groups.each(fn(item) {
let (name, body) = item
group(name, body)
})
}
///| Group Helpers
///|
/// Group for HTTP requests
pub fn http_group(name : String, body : () -> Unit) -> Unit {
group("HTTP: " + name, body)
}
///|
/// Group for database operations
pub fn db_group(name : String, body : () -> Unit) -> Unit {
group("DB: " + name, body)
}
///|
/// Group for API calls
pub fn api_group(endpoint : String, body : () -> Unit) -> Unit {
group("API: " + endpoint, body)
}
///|
/// Group for authentication
pub fn auth_group(body : () -> Unit) -> Unit {
group("Authentication", body)
}
///|
/// Group for setup operations
pub fn setup_group(body : () -> Unit) -> Unit {
group("Setup", body)
}
///|
/// Group for cleanup operations
pub fn cleanup_group(body : () -> Unit) -> Unit {
group("Cleanup", body)
}
///| Conditional Groups
///|
/// Run group only on first iteration
pub fn group_on_first_iteration(name : String, body : () -> Unit) -> Unit {
if is_first_iteration() {
group(name, body)
}
}
///|
/// Run group only on specific VU
pub fn group_on_vu(vu_id : Int, name : String, body : () -> Unit) -> Unit {
if current_vu() == vu_id {
group(name, body)
}
}
///|
/// Run group every N iterations
pub fn group_every_n_iterations(
n : Int,
name : String,
body : () -> Unit
) -> Unit {
if current_iteration() % n == 0 {
group(name, body)
}
}
///| Tagged Requests
///|
/// Execute request with tags
pub fn tagged_request(
builder : RequestBuilder,
tags : Map[String, String]
) -> Response {
let mut tagged_builder = builder
tags.each(fn(k, v) { tagged_builder = tagged_builder.tag(k, v) })
tagged_builder.send()
}
///|
/// Execute request in tagged group
pub fn tagged_group_request(
group_name : String,
builder : RequestBuilder,
tags : Map[String, String]
) -> Response {
let mut result : Response? = None
group(group_name, fn() {
result = Some(tagged_request(builder, tags))
})
match result {
Some(r) => r
None => {
// This should never happen, but we need to return something
// Create a dummy response (would need Response::default() in real implementation)
quick_get("about:blank") // Placeholder
}
}
}
///| Metric Tagging
///|
/// Create counter with tags
pub fn create_tagged_counter(name : String, _tags : Map[String, String]) -> Counter {
// Note: k6 metrics don't support tags in constructor
// Tags are applied at add() time via request params
create_counter(name)
}
///|
/// Create rate with tags
pub fn create_tagged_rate(name : String, _tags : Map[String, String]) -> Rate {
create_rate(name)
}
///|
/// Create trend with tags
pub fn create_tagged_trend(name : String, _tags : Map[String, String]) -> Trend {
create_trend(name)
}