Skip to content

Commit

Permalink
Merge branch 'main' into run_benchmark
Browse files Browse the repository at this point in the history
  • Loading branch information
afsalthaj authored Jul 5, 2024
2 parents ec0a544 + 55b8f4f commit 635b133
Showing 1 changed file with 339 additions and 6 deletions.
345 changes: 339 additions & 6 deletions golem-test-framework/src/dsl/benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ use cli_table::format::{Border, Separator};
use cli_table::{format::Justify, Cell, CellStruct, Style, Table};
use colored::Colorize;
use itertools::Itertools;
use serde::{Deserialize, Serialize};
use serde::de::{Error, Visitor};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::cmp::Ordering;
use std::collections::HashMap;
use std::fmt;
use std::fmt::{Debug, Display, Formatter};
use std::sync::{Arc, Mutex};
use std::time::Duration;
Expand Down Expand Up @@ -60,7 +62,7 @@ pub struct RunConfig {
pub length: usize,
}

#[derive(Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[derive(Clone, Eq, PartialEq, Hash)]
pub struct ResultKey {
name: String,
primary: bool,
Expand Down Expand Up @@ -118,7 +120,58 @@ impl From<&str> for ResultKey {
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
impl Serialize for ResultKey {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
if self.primary {
serializer.serialize_str(&self.name)
} else {
serializer.serialize_str(&format!("{}__secondary", self.name))
}
}
}

impl<'de> Deserialize<'de> for ResultKey {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct ResultKeyVisitor;

impl<'de> Visitor<'de> for ResultKeyVisitor {
type Value = ResultKey;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("struct ResultKey")
}

fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: Error,
{
let name = v.to_string();
if name.ends_with("__secondary") {
Ok(ResultKey {
name: name[0..(name.len() - "__secondary".len())].to_string(),
primary: false,
})
} else {
Ok(ResultKey {
name,
primary: true,
})
}
}
}

const FIELDS: &[&str] = &["secs", "nanos"];
deserializer.deserialize_struct("Duration", FIELDS, ResultKeyVisitor)
}
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct DurationResult {
pub avg: Duration,
pub min: Duration,
Expand Down Expand Up @@ -161,7 +214,7 @@ impl Default for DurationResult {
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct CountResult {
pub avg: u64,
pub min: u64,
Expand Down Expand Up @@ -419,7 +472,7 @@ impl Display for BenchmarkResultView {
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct BenchmarkResult {
pub runs: Vec<RunConfig>,
pub results: Vec<(RunConfig, BenchmarkRunResult)>,
Expand Down Expand Up @@ -482,7 +535,7 @@ impl BenchmarkResult {
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct BenchmarkRunResult {
pub duration_results: HashMap<ResultKey, DurationResult>,
pub count_results: HashMap<ResultKey, CountResult>,
Expand Down Expand Up @@ -761,3 +814,283 @@ impl<B: Benchmark> BenchmarkApi for B {
BenchmarkResult { runs, results }
}
}

#[cfg(test)]
mod tests {
use crate::dsl::benchmark::{
BenchmarkResult, BenchmarkRunResult, CountResult, DurationResult, ResultKey, RunConfig,
};
use std::collections::HashMap;
use std::time::Duration;

#[test]
fn benchmark_result_is_serializable_to_json() {
let rc1 = RunConfig {
cluster_size: 1,
size: 10,
length: 20,
};
let rc2 = RunConfig {
cluster_size: 5,
size: 100,
length: 20,
};

let mut dr1 = HashMap::new();
let mut cr1 = HashMap::new();
let mut dr2 = HashMap::new();
let mut cr2 = HashMap::new();

dr1.insert(
ResultKey::primary("a"),
DurationResult {
avg: Duration::from_millis(500),
min: Duration::from_millis(100),
max: Duration::from_millis(900),
all: vec![
Duration::from_millis(100),
Duration::from_millis(500),
Duration::from_millis(900),
],
per_iteration: vec![vec![
Duration::from_millis(100),
Duration::from_millis(500),
Duration::from_millis(900),
]],
},
);

cr1.insert(
ResultKey::primary("a"),
CountResult {
avg: 500,
min: 100,
max: 900,
all: vec![100, 500, 900],
per_iteration: vec![vec![100, 500, 900]],
},
);

dr2.insert(
ResultKey::secondary("b"),
DurationResult {
avg: Duration::from_millis(500),
min: Duration::from_millis(100),
max: Duration::from_millis(900),
all: vec![
Duration::from_millis(100),
Duration::from_millis(500),
Duration::from_millis(900),
],
per_iteration: vec![vec![
Duration::from_millis(100),
Duration::from_millis(500),
Duration::from_millis(900),
]],
},
);

cr2.insert(
ResultKey::secondary("b"),
CountResult {
avg: 500,
min: 100,
max: 900,
all: vec![100, 500, 900],
per_iteration: vec![vec![100, 500, 900]],
},
);

let example = BenchmarkResult {
runs: vec![rc1.clone(), rc2.clone()],
results: vec![
(
rc1,
BenchmarkRunResult {
duration_results: dr1,
count_results: cr1,
},
),
(
rc2,
BenchmarkRunResult {
duration_results: dr2,
count_results: cr2,
},
),
],
};

let json = serde_json::to_string_pretty(&example).unwrap();
assert_eq!(
json,
r#"{
"runs": [
{
"cluster_size": 1,
"size": 10,
"length": 20
},
{
"cluster_size": 5,
"size": 100,
"length": 20
}
],
"results": [
[
{
"cluster_size": 1,
"size": 10,
"length": 20
},
{
"duration_results": {
"a": {
"avg": {
"secs": 0,
"nanos": 500000000
},
"min": {
"secs": 0,
"nanos": 100000000
},
"max": {
"secs": 0,
"nanos": 900000000
},
"all": [
{
"secs": 0,
"nanos": 100000000
},
{
"secs": 0,
"nanos": 500000000
},
{
"secs": 0,
"nanos": 900000000
}
],
"per_iteration": [
[
{
"secs": 0,
"nanos": 100000000
},
{
"secs": 0,
"nanos": 500000000
},
{
"secs": 0,
"nanos": 900000000
}
]
]
}
},
"count_results": {
"a": {
"avg": 500,
"min": 100,
"max": 900,
"all": [
100,
500,
900
],
"per_iteration": [
[
100,
500,
900
]
]
}
}
}
],
[
{
"cluster_size": 5,
"size": 100,
"length": 20
},
{
"duration_results": {
"b__secondary": {
"avg": {
"secs": 0,
"nanos": 500000000
},
"min": {
"secs": 0,
"nanos": 100000000
},
"max": {
"secs": 0,
"nanos": 900000000
},
"all": [
{
"secs": 0,
"nanos": 100000000
},
{
"secs": 0,
"nanos": 500000000
},
{
"secs": 0,
"nanos": 900000000
}
],
"per_iteration": [
[
{
"secs": 0,
"nanos": 100000000
},
{
"secs": 0,
"nanos": 500000000
},
{
"secs": 0,
"nanos": 900000000
}
]
]
}
},
"count_results": {
"b__secondary": {
"avg": 500,
"min": 100,
"max": 900,
"all": [
100,
500,
900
],
"per_iteration": [
[
100,
500,
900
]
]
}
}
}
]
]
}"#
);

let deserialized = serde_json::from_str::<BenchmarkResult>(&json).unwrap();
assert_eq!(example, deserialized);
}
}

0 comments on commit 635b133

Please sign in to comment.