Skip to content

Commit

Permalink
bencher_comment
Browse files Browse the repository at this point in the history
  • Loading branch information
epompeii committed Dec 3, 2023
1 parent 235a79a commit 952787d
Show file tree
Hide file tree
Showing 21 changed files with 141 additions and 166 deletions.
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ edition = "2021"
bencher_adapter = { path = "lib/bencher_adapter" }
bencher_boundary = { path = "lib/bencher_boundary" }
bencher_client = { path = "lib/bencher_client" }
bencher_comment = { path = "lib/bencher_comment" }
bencher_json = { path = "lib/bencher_json" }
bencher_logger = { path = "lib/bencher_logger" }
bencher_plot = { path = "lib/bencher_plot" }
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,10 @@ You can set the [`bencher run` CLI subcommand](https://bencher.dev/docs/explanat
bencher run --project my-project-slug --github-actions "${{ secrets.GITHUB_TOKEN }}" "bencher mock"
```

To display the benchmark metrics and boundary limits, use the `--ci-with-metrics` flag.
To omit the benchmark metrics and boundary limits from the results, use the `--ci-no-metrics` flag.

```bash
bencher run --project my-project-slug --github-actions "${{ secrets.GITHUB_TOKEN }}" --ci-with-metrics "bencher mock"
bencher run --project my-project-slug --github-actions "${{ secrets.GITHUB_TOKEN }}" --ci-no-metrics "bencher mock"
```

If you want to only show results when [a Threshold is set](https://bencher.dev/docs/explanation/thresholds) use the `--ci-only-thresholds` flag.
Expand All @@ -191,7 +191,7 @@ bencher run --project my-project-slug --github-actions "${{ secrets.GITHUB_TOKEN
You can also use all of them together!

```bash
bencher run --project my-project-slug --github-actions "${{ secrets.GITHUB_TOKEN }}" --ci-with-metrics --ci-only-thresholds --ci-only-on-alert "bencher mock"
bencher run --project my-project-slug --github-actions "${{ secrets.GITHUB_TOKEN }}" --ci-no-metrics --ci-only-thresholds --ci-only-on-alert "bencher mock"
```

For more options see the [`bencher run`](https://bencher.dev/docs/explanation/bencher-run) documentation.
Expand Down
12 changes: 12 additions & 0 deletions lib/bencher_comment/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "bencher_comment"
version.workspace = true
authors.workspace = true
edition.workspace = true

[dependencies]
bencher_json.workspace = true
url.workspace = true

[lints]
workspace = true
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ use bencher_json::{
};
use url::Url;

pub struct ReportUrls {
pub struct ReportComment {
endpoint_url: Url,
project_slug: Slug,
json_report: JsonReport,
benchmark_urls: BenchmarkUrls,
alert_urls: AlertUrls,
}

impl ReportUrls {
impl ReportComment {
pub fn new(endpoint_url: Url, json_report: JsonReport) -> Self {
Self {
alert_urls: AlertUrls::new(&endpoint_url, &json_report),
Expand All @@ -25,15 +25,45 @@ impl ReportUrls {
}
}

pub fn text(&self) -> String {
let mut comment = String::new();

comment.push_str("View results:");
for (benchmark, metric_kinds) in &self.benchmark_urls.0 {
for (metric_kind, MetricKindData { console_url, .. }) in metric_kinds {
comment.push_str(&format!(
"\n- {benchmark_name} ({metric_kind_name}): {console_url}",
benchmark_name = benchmark.name,
metric_kind_name = metric_kind.name
));
}
}

if self.json_report.alerts.is_empty() {
return comment;
}

comment.push_str("\nView alerts:");
for ((benchmark, metric_kind), AlertData { console_url, .. }) in &self.alert_urls.0 {
comment.push_str(&format!(
"\n- {benchmark_name} ({metric_kind_name}): {console_url}",
benchmark_name = benchmark.name,
metric_kind_name = metric_kind.name,
));
}

comment
}

pub fn html(
&self,
with_metrics: bool,
require_threshold: bool,
public_links: bool,
id: Option<&NonEmpty>,
) -> String {
let mut html = String::new();
let html_mut = &mut html;
let public_links = self.json_report.project.visibility.is_public();
self.html_header(html_mut);
self.html_report_table(html_mut, public_links);
self.html_benchmarks_table(html_mut, with_metrics, require_threshold, public_links);
Expand Down Expand Up @@ -104,7 +134,6 @@ impl ReportUrls {
html.push_str("</table>");
}

#[allow(clippy::too_many_lines)]
fn html_benchmarks_table(
&self,
html: &mut String,
Expand All @@ -116,9 +145,26 @@ impl ReportUrls {
html.push_str("<b>No benchmarks found!</b>");
return;
};

html.push_str("<table>");
self.html_benchmarks_table_header(
html,
metric_kinds,
with_metrics,
require_threshold,
public_links,
);
self.html_benchmarks_table_body(html, with_metrics, require_threshold, public_links);
html.push_str("</table>");
}

fn html_benchmarks_table_header(
&self,
html: &mut String,
metric_kinds: &MetricKindsMap,
with_metrics: bool,
require_threshold: bool,
public_links: bool,
) {
html.push_str("<tr>");
html.push_str("<th>Benchmark</th>");
for (metric_kind, MetricKindData { boundary, .. }) in metric_kinds {
Expand Down Expand Up @@ -158,7 +204,15 @@ impl ReportUrls {
}
}
html.push_str("</tr>");
}

fn html_benchmarks_table_body(
&self,
html: &mut String,
with_metrics: bool,
require_threshold: bool,
public_links: bool,
) {
for (benchmark, metric_kinds) in &self.benchmark_urls.0 {
html.push_str("<tr>");
if public_links {
Expand Down Expand Up @@ -254,11 +308,8 @@ impl ReportUrls {
}
}
}

html.push_str("</tr>");
}

html.push_str("</table>");
}

fn html_footer(&self, html: &mut String) {
Expand Down Expand Up @@ -306,39 +357,6 @@ impl ReportUrls {
}
}

impl std::fmt::Display for ReportUrls {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "\nView results:")?;
for (benchmark, metric_kinds) in &self.benchmark_urls.0 {
for (metric_kind, MetricKindData { console_url, .. }) in metric_kinds {
writeln!(
f,
"- {benchmark_name} ({metric_kind_name}): {console_url}",
benchmark_name = benchmark.name,
metric_kind_name = metric_kind.name
)?;
}
}

if self.json_report.alerts.is_empty() {
return Ok(());
}

writeln!(f, "\nView alerts:")?;
for ((benchmark, metric_kind), AlertData { console_url, .. }) in &self.alert_urls.0 {
writeln!(
f,
"- {benchmark_name} ({metric_kind_name}): {console_url}",
benchmark_name = benchmark.name,
metric_kind_name = metric_kind.name,
)?;
}
writeln!(f, "\n")?;

Ok(())
}
}

pub struct BenchmarkUrls(BTreeMap<Benchmark, MetricKindsMap>);
pub type MetricKindsMap = BTreeMap<MetricKind, MetricKindData>;

Expand All @@ -360,7 +378,7 @@ pub struct MetricKindData {
pub public_url: Url,
pub console_url: Url,
pub value: f64,
pub boundary: BoundaryParam,
pub boundary: BoundaryLimits,
}

impl BenchmarkUrls {
Expand Down Expand Up @@ -422,7 +440,7 @@ impl BenchmarkUrls {
.any(|MetricKindData { boundary, .. }| Self::boundary_has_threshold(*boundary))
}

fn boundary_has_threshold(boundary: BoundaryParam) -> bool {
fn boundary_has_threshold(boundary: BoundaryLimits) -> bool {
!boundary.is_empty()
}
}
Expand Down Expand Up @@ -462,7 +480,7 @@ impl BenchmarkUrl {
&self,
metric_kind: MetricKindUuid,
benchmark: BenchmarkUuid,
boundary: BoundaryParam,
boundary: BoundaryLimits,
) -> Url {
self.to_url(metric_kind, benchmark, boundary, true)
}
Expand All @@ -471,7 +489,7 @@ impl BenchmarkUrl {
&self,
metric_kind: MetricKindUuid,
benchmark: BenchmarkUuid,
boundary: BoundaryParam,
boundary: BoundaryLimits,
) -> Url {
self.to_url(metric_kind, benchmark, boundary, false)
}
Expand All @@ -480,7 +498,7 @@ impl BenchmarkUrl {
&self,
metric_kind: MetricKindUuid,
benchmark: BenchmarkUuid,
boundary: BoundaryParam,
boundary: BoundaryLimits,
public_links: bool,
) -> Url {
let json_perf_query = JsonPerfQuery {
Expand Down Expand Up @@ -510,13 +528,13 @@ impl BenchmarkUrl {
}

#[derive(Clone, Copy)]
pub struct BoundaryParam {
pub struct BoundaryLimits {
average: f64,
lower_boundary: Option<f64>,
upper_boundary: Option<f64>,
}

impl From<JsonBoundary> for BoundaryParam {
impl From<JsonBoundary> for BoundaryLimits {
fn from(json_boundary: JsonBoundary) -> Self {
Self {
average: json_boundary.average.into(),
Expand All @@ -526,7 +544,7 @@ impl From<JsonBoundary> for BoundaryParam {
}
}

impl BoundaryParam {
impl BoundaryLimits {
fn to_query_string(self) -> Vec<(&'static str, Option<String>)> {
let mut query_string = Vec::new();
if self.lower_boundary.is_some() {
Expand Down
1 change: 1 addition & 0 deletions services/api/builder.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ COPY .cargo/config.toml config.toml
WORKDIR /usr/src/lib
COPY lib/bencher_adapter bencher_adapter
COPY lib/bencher_boundary bencher_boundary
COPY lib/bencher_comment bencher_comment
COPY lib/bencher_json bencher_json
COPY lib/bencher_logger bencher_logger
COPY lib/bencher_plot bencher_plot
Expand Down
1 change: 1 addition & 0 deletions services/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ seed = []
async-trait.workspace = true
bencher_adapter.workspace = true
bencher_client.workspace = true
bencher_comment.workspace = true
bencher_json = { workspace = true, features = ["lite", "table"] }
chrono = { workspace = true, features = ["clock"] }
clap.workspace = true
Expand Down
Loading

0 comments on commit 952787d

Please sign in to comment.