Skip to content

Commit ec2dcf4

Browse files
committed
run
1 parent 0bb3fa8 commit ec2dcf4

File tree

8 files changed

+325
-9
lines changed

8 files changed

+325
-9
lines changed

lib/bencher_json/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub mod big_int;
1919
pub mod organization;
2020
pub mod pagination;
2121
pub mod project;
22+
pub mod run;
2223
pub mod system;
2324
pub(crate) mod typed_uuid;
2425
pub mod urlencoded;
@@ -52,6 +53,7 @@ pub use project::{
5253
threshold::{JsonNewThreshold, JsonThreshold, JsonThresholds, ThresholdUuid},
5354
JsonNewProject, JsonProject, JsonProjects, ProjectUuid,
5455
};
56+
pub use run::JsonNewRun;
5557
#[cfg(feature = "plus")]
5658
pub use system::{
5759
auth::JsonOAuth,

lib/bencher_json/src/project/branch.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub const START_POINT_MAX_VERSIONS: u32 = 255;
1414

1515
pub const BRANCH_MAIN_STR: &str = "main";
1616
#[allow(clippy::expect_used)]
17-
static BRANCH_MAIN: LazyLock<BranchName> = LazyLock::new(|| {
17+
pub static BRANCH_MAIN: LazyLock<BranchName> = LazyLock::new(|| {
1818
BRANCH_MAIN_STR
1919
.parse()
2020
.expect("Failed to parse branch name.")

lib/bencher_json/src/project/testbed.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::ProjectUuid;
1010

1111
pub const TESTBED_LOCALHOST_STR: &str = "localhost";
1212
#[allow(clippy::expect_used)]
13-
static TESTBED_LOCALHOST: LazyLock<ResourceName> = LazyLock::new(|| {
13+
pub static TESTBED_LOCALHOST: LazyLock<ResourceName> = LazyLock::new(|| {
1414
TESTBED_LOCALHOST_STR
1515
.parse()
1616
.expect("Failed to parse testbed name.")

lib/bencher_json/src/run/mod.rs

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
use bencher_valid::{BranchName, DateTime, Fingerprint, GitHash, ResourceId};
2+
#[cfg(feature = "schema")]
3+
use schemars::JsonSchema;
4+
use serde::{Deserialize, Serialize};
5+
6+
use crate::{
7+
project::{
8+
branch::{JsonUpdateStartPoint, BRANCH_MAIN},
9+
report::{JsonReportSettings, JsonReportThresholds},
10+
testbed::TESTBED_LOCALHOST,
11+
},
12+
JsonNewReport, NameId,
13+
};
14+
15+
crate::typed_uuid::typed_uuid!(ReportUuid);
16+
17+
#[derive(Debug, Serialize, Deserialize)]
18+
#[cfg_attr(feature = "schema", derive(JsonSchema))]
19+
pub struct JsonNewRun {
20+
/// Organization UUID or slug.
21+
pub organization: Option<ResourceId>,
22+
/// Project UUID, slug, or name.
23+
pub project: Option<NameId>,
24+
/// Branch UUID, slug, or name.
25+
/// If the branch does not exist, it will be created.
26+
pub branch: Option<NameId>,
27+
/// Full `git` commit hash.
28+
/// All reports with the same `git` commit hash will be considered part of the same branch version.
29+
/// This can be useful for tracking the performance of a specific commit across multiple testbeds.
30+
pub hash: Option<GitHash>,
31+
/// The start point for the report branch.
32+
/// If the branch does not exist, the start point will be used to create a new branch.
33+
/// If the branch already exists and the start point is not provided, the current branch will be used.
34+
/// If the branch already exists and the start point provided is different, a new branch head will be created from the new start point.
35+
/// If a new branch or new branch head is created with a start point,
36+
/// historical branch versions from the start point branch will be shallow copied over to the new branch.
37+
/// That is, historical metrics data for the start point branch will appear in queries for the branch.
38+
/// For example, pull request branches often use their base branch as their start point branch.
39+
/// If a new branch is created, it is not kept in sync with the start point branch.
40+
pub start_point: Option<JsonUpdateStartPoint>,
41+
/// Testbed UUID, slug, or name.
42+
/// If the testbed does not exist, it will be created.
43+
pub testbed: Option<NameId>,
44+
/// Thresholds to use for the branch, testbed, and measures in the report.
45+
/// If a threshold does not exist, it will be created.
46+
/// If a threshold exists and the model is different, it will be updated with the new model.
47+
/// If a measure name or slug is provided, the measure will be created if it does not exist.
48+
pub thresholds: Option<JsonReportThresholds>,
49+
/// Start time for the report. Must be an ISO 8601 formatted string.
50+
pub start_time: DateTime,
51+
/// End time for the report. Must be an ISO 8601 formatted string.
52+
pub end_time: DateTime,
53+
/// An array of benchmarks results.
54+
pub results: Vec<String>,
55+
/// Settings for how to handle the report.
56+
pub settings: Option<JsonReportSettings>,
57+
/// Context for the run.
58+
pub context: Option<JsonRunContext>,
59+
}
60+
61+
impl From<JsonNewRun> for JsonNewReport {
62+
fn from(run: JsonNewRun) -> Self {
63+
let JsonNewRun {
64+
organization: _,
65+
project: _,
66+
branch,
67+
hash,
68+
start_point,
69+
testbed,
70+
thresholds,
71+
start_time,
72+
end_time,
73+
results,
74+
settings,
75+
context,
76+
} = run;
77+
let branch = branch
78+
.or_else(|| {
79+
context
80+
.as_ref()
81+
.and_then(|ctx| ctx.branch.clone().map(Into::into))
82+
})
83+
.unwrap_or_else(|| BRANCH_MAIN.clone().into());
84+
let testbed = testbed
85+
.or_else(|| {
86+
context
87+
.as_ref()
88+
.and_then(|ctx| ctx.os.and_then(|os| os.as_ref().parse().ok()))
89+
})
90+
.unwrap_or_else(|| TESTBED_LOCALHOST.clone().into());
91+
Self {
92+
branch,
93+
hash,
94+
start_point,
95+
testbed,
96+
thresholds,
97+
start_time,
98+
end_time,
99+
results,
100+
settings,
101+
}
102+
}
103+
}
104+
105+
#[derive(Debug, Serialize, Deserialize)]
106+
#[cfg_attr(feature = "schema", derive(JsonSchema))]
107+
pub struct JsonRunContext {
108+
/// The branch during the run.
109+
pub branch: Option<BranchName>,
110+
/// The root commit hash during the run.
111+
pub root_commit: Option<GitHash>,
112+
/// The testbed operating system during the run.
113+
pub os: Option<OperatingSystem>,
114+
/// The testbed fingerprint during the run.
115+
pub fingerprint: Option<Fingerprint>,
116+
}
117+
118+
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
119+
#[cfg_attr(feature = "schema", derive(JsonSchema))]
120+
#[serde(rename_all = "snake_case")]
121+
pub enum OperatingSystem {
122+
Linux,
123+
Macos,
124+
Windows,
125+
}
126+
127+
impl AsRef<str> for OperatingSystem {
128+
fn as_ref(&self) -> &str {
129+
match self {
130+
Self::Linux => "linux",
131+
Self::Macos => "macos",
132+
Self::Windows => "windows",
133+
}
134+
}
135+
}

lib/bencher_valid/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ crate-type = ["cdylib", "rlib"]
1111

1212
[features]
1313
full = ["dep:rand", "dep:regex"]
14-
lite = ["dep:regex-lite"]
14+
lite = ["dep:regex-lite", "dep:windows"]
1515
db = ["dep:diesel"]
1616
plus = ["chrono/clock"]
1717
schema = ["dep:schemars", "ordered-float/schemars"]

lib/bencher_valid/src/name_id.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use serde::{
1111
};
1212
use uuid::Uuid;
1313

14-
use crate::{non_empty::is_valid_non_empty, NonEmpty, Slug, ValidError};
14+
use crate::{non_empty::is_valid_non_empty, BranchName, NonEmpty, ResourceName, Slug, ValidError};
1515

1616
#[typeshare::typeshare]
1717
#[derive(Debug, derive_more::Display, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
@@ -76,6 +76,18 @@ impl From<NonEmpty> for NameId {
7676
}
7777
}
7878

79+
impl From<ResourceName> for NameId {
80+
fn from(resource_name: ResourceName) -> Self {
81+
Self(resource_name.into())
82+
}
83+
}
84+
85+
impl From<BranchName> for NameId {
86+
fn from(branch_name: BranchName) -> Self {
87+
Self(branch_name.into())
88+
}
89+
}
90+
7991
impl AsRef<str> for NameId {
8092
fn as_ref(&self) -> &str {
8193
&self.0

0 commit comments

Comments
 (0)