use std::path::PathBuf;
use crate::bench::baselines::{BaselineRun, DockerCli, run_baselines};
use crate::bench::client::AuthKind;
use crate::bench::compare::Comparison;
use crate::bench::manifest::{MANIFEST_FILE, PackManifest};
use crate::bench::pack::BenchPack;
use crate::bench::posture::PostureProfile;
use crate::bench::render::COMPARISON_FILE;
use crate::bench::result::BenchResult;
use crate::bench::run::BenchRun;
use crate::bench::{compare, render, run};
use crate::pipeline::{Error, RenderedFile};
#[derive(Debug)]
pub struct ManifestOutcome {
pub manifest: PackManifest,
pub document: RenderedFile,
}
pub fn describe_packs() -> Result<ManifestOutcome, Error> {
let manifest = PackManifest::of_embedded()
.map_err(|error| Error::Instrument(format!("bench: {error}")))?;
let body = manifest
.to_document()
.map_err(|error| Error::Instrument(format!("bench: {error}")))?;
Ok(ManifestOutcome {
manifest,
document: RenderedFile {
name: MANIFEST_FILE.to_owned(),
body,
},
})
}
#[derive(Debug)]
pub struct BenchRequest<'a> {
pub pack: &'a BenchPack,
pub profile: &'a PostureProfile,
pub base_url: &'a str,
pub auth: AuthKind,
pub user: Option<&'a str>,
pub repetitions: u32,
pub label: Option<&'a str>,
pub scale: f64,
pub seed_workers: Option<usize>,
pub with_baselines: bool,
pub docker: Option<DockerCli>,
}
#[derive(Debug)]
pub struct BenchOutcome {
pub result: BenchResult,
pub documents: Vec<RenderedFile>,
}
pub fn run_bench(
request: &BenchRequest<'_>,
progress: &(dyn Fn(String) + Sync),
) -> Result<BenchOutcome, Error> {
let docker = request.docker.clone().unwrap_or_default();
if request.with_baselines {
let _version = docker
.probe()
.map_err(|error| Error::Instrument(format!("bench: {error}")))?;
}
let mut result = run::execute(
&BenchRun {
pack: request.pack,
base_url: request.base_url,
profile: request.profile,
auth: request.auth,
user: request.user,
credential: None,
repetitions: request.repetitions,
label: request.label,
scale: request.scale,
seed_workers: request.seed_workers,
},
progress,
)
.map_err(|error| Error::Instrument(format!("bench: {error}")))?;
if request.with_baselines {
let baselines = run_baselines(
&BaselineRun {
pack: request.pack,
profile: request.profile,
repetitions: request.repetitions,
scale: request.scale,
seed_workers: request.seed_workers,
docker: &docker,
},
progress,
)
.map_err(|error| Error::Instrument(format!("bench: {error}")))?;
result.attach_baselines(baselines);
}
let document = result
.to_document()
.map_err(|error| Error::Instrument(format!("bench: {error}")))?;
let summary = render::run_summary(&result);
let stem = result.file_name();
let markdown = stem.replace(".json", ".md");
Ok(BenchOutcome {
documents: vec![
RenderedFile {
name: stem,
body: document,
},
RenderedFile {
name: markdown,
body: summary,
},
],
result,
})
}
#[derive(Debug)]
pub struct ComparisonOutcome {
pub comparison: Comparison,
pub document: RenderedFile,
}
pub fn compare_bench(paths: &[PathBuf]) -> Result<ComparisonOutcome, Error> {
let comparison =
compare::compare(paths).map_err(|error| Error::Instrument(format!("bench: {error}")))?;
let body = render::comparison(&comparison);
Ok(ComparisonOutcome {
comparison,
document: RenderedFile {
name: COMPARISON_FILE.to_owned(),
body,
},
})
}