use std::collections::BTreeMap;
use std::fmt;
use serde::Deserialize;
use sha2::{Digest as _, Sha256};
use crate::bench::BenchError;
use crate::bench::posture::{
CLINICAL_DEFAULT, MINIMAL, MINIMAL_SIGNED_DIGEST, MINIMAL_SIGNED_PGP, PostureProfile,
};
const BLOOD_PRESSURE_OPT: &str = include_str!("fixtures/blood_pressure.opt");
const BLOOD_PRESSURE_OPT_SHA256: &str =
"97549fb2ab7ca36b9baa1cc86e857ef82924927a42140dfd3fd09a05dd83d006";
const BLOOD_PRESSURE_OPT_PROVENANCE: &str = "\
Authored in this repository for the smoke pack: an ADL 1.4 operational \
template with template id 'cnf.blood_pressure', rooted at \
openEHR-EHR-COMPOSITION.minimal.v1 and constraining \
openEHR-EHR-OBSERVATION.blood_pressure.v2. It exists to give the smoke pack a \
small upload, and it is not derived from any published library.";
const BP_COMPOSITION: &str = include_str!("fixtures/bp_composition.json");
const BP_COMPOSITION_SHA256: &str =
"bc0d07f4a6f89e5b357cddd558b4c05a6ee9cd4083dda6646e1b23ee80ff1d47";
const BP_COMPOSITION_PROVENANCE: &str = "\
Authored in this repository for the smoke pack: a canonical-JSON COMPOSITION \
declaring template id 'cnf.blood_pressure' and rooted at \
openEHR-EHR-COMPOSITION.minimal.v1, the root that template defines, carrying \
one POINT_EVENT with a systolic and a diastolic DV_QUANTITY in mm[Hg].";
const BP_COMPOSITION_TWIN: &str = include_str!("fixtures/bp_composition.missing_composer.json");
const BP_COMPOSITION_TWIN_SHA256: &str =
"eaec78e4b3541189b63bc2a83cbff88e4727aa3893406e08777e7330cbfb72b6";
const BP_COMPOSITION_TWIN_PROVENANCE: &str = "\
Derived in this repository from bp_composition.json by deleting the mandatory \
COMPOSITION.composer member and nothing else, so a server that validates a \
commit against the reference model refuses it.";
const VITAL_SIGNS_OPT: &str = include_str!("fixtures/vital_signs.opt");
const VITAL_SIGNS_OPT_SHA256: &str =
"3a0d31bd3b5dc6329e53c0d6f22fdbaece62c684136b86139d0729cff8796128";
const VITAL_SIGNS_OPT_PROVENANCE: &str = "\
The openEHR Clinical Knowledge Manager's own Operational Template export for \
template id 'Vital signs' (CKM cid 1013.26.380, <https://ckm.openehr.org/ckm>), \
vendored byte-identically and rooted at openEHR-EHR-COMPOSITION.encounter.v1.";
const VITAL_SIGNS_COMPOSITION: &str = include_str!("fixtures/vital_signs_composition.json");
const VITAL_SIGNS_COMPOSITION_SHA256: &str =
"468081c259c737d35d7f80403562b3f333e479d267286faf80fd7c087eaba947";
const VITAL_SIGNS_COMPOSITION_PROVENANCE: &str = "\
The composition attached to post 8 of the openEHR community's vital-signs \
benchmark thread (<https://discourse.openehr.org/t/17224>), vendored \
byte-identically: eight OBSERVATION entries under \
openEHR-EHR-COMPOSITION.encounter.v1, rm_version 1.0.2, declaring template id \
'Vital signs'.";
const VITAL_SIGNS_COMPOSITION_TWIN: &str =
include_str!("fixtures/vital_signs_composition.missing_composer.json");
const VITAL_SIGNS_COMPOSITION_TWIN_SHA256: &str =
"f0598db5ab447b371ead28cba0f841f72370dbbf93db98d5b8e477910a42688d";
const VITAL_SIGNS_COMPOSITION_TWIN_PROVENANCE: &str = "\
Derived in this repository from vital_signs_composition.json by deleting the \
mandatory COMPOSITION.composer member and nothing else, so a server that \
validates a commit against the reference model refuses it.";
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct PackId(&'static str);
impl PackId {
#[must_use]
pub const fn as_str(self) -> &'static str {
self.0
}
}
impl fmt::Display for PackId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct FixtureKey(&'static str);
impl FixtureKey {
#[must_use]
pub const fn as_str(self) -> &'static str {
self.0
}
}
impl fmt::Display for FixtureKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FixtureKind {
OperationalTemplate,
Composition,
InvalidComposition,
}
impl FixtureKind {
pub const ALL: &[FixtureKind] = &[
FixtureKind::Composition,
FixtureKind::InvalidComposition,
FixtureKind::OperationalTemplate,
];
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
FixtureKind::OperationalTemplate => "operational_template",
FixtureKind::Composition => "composition",
FixtureKind::InvalidComposition => "invalid_composition",
}
}
#[must_use]
pub const fn media_type(self) -> &'static str {
match self {
FixtureKind::OperationalTemplate => "application/xml",
FixtureKind::Composition | FixtureKind::InvalidComposition => "application/json",
}
}
}
impl fmt::Display for FixtureKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, Clone, Copy)]
pub struct Fixture {
pub key: FixtureKey,
pub kind: FixtureKind,
pub bytes: &'static str,
pub sha256: &'static str,
pub provenance: &'static str,
}
impl Fixture {
pub fn verify(&self, pack: PackId) -> Result<(), BenchError> {
let actual = hex(&Sha256::digest(self.bytes.as_bytes()));
if actual == self.sha256 {
return Ok(());
}
Err(BenchError::FixturePin {
pack,
fixture: self.key,
expected: self.sha256.to_owned(),
actual,
})
}
}
fn hex(bytes: &[u8]) -> String {
use std::fmt::Write as _;
bytes.iter().fold(
String::with_capacity(bytes.len().saturating_mul(2)),
|mut out, byte| {
let _ = write!(out, "{byte:02x}");
out
},
)
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum BenchOp {
CreateComposition,
GetCompositionAtTime,
GetCompositionLatest,
GetEhr,
GetEhrStatus,
GetVersionedComposition,
GetVersionedCompositionRevisionHistory,
GetVersionedCompositionVersionAtTime,
GetVersionedCompositionVersionById,
GetVersionedCompositionVersionLatest,
AdhocQueryUid,
AdhocQueryAggregate,
AdhocQueryEhrScan,
AdhocQueryFiltered,
AdhocQueryOrderedPage,
AdhocQueryPointLookup,
AdhocQueryPopulation,
}
impl BenchOp {
pub const ALL: &[BenchOp] = &[
BenchOp::AdhocQueryAggregate,
BenchOp::AdhocQueryEhrScan,
BenchOp::AdhocQueryFiltered,
BenchOp::AdhocQueryOrderedPage,
BenchOp::AdhocQueryPointLookup,
BenchOp::AdhocQueryPopulation,
BenchOp::AdhocQueryUid,
BenchOp::CreateComposition,
BenchOp::GetCompositionAtTime,
BenchOp::GetCompositionLatest,
BenchOp::GetEhr,
BenchOp::GetEhrStatus,
BenchOp::GetVersionedComposition,
BenchOp::GetVersionedCompositionRevisionHistory,
BenchOp::GetVersionedCompositionVersionAtTime,
BenchOp::GetVersionedCompositionVersionById,
BenchOp::GetVersionedCompositionVersionLatest,
];
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
BenchOp::CreateComposition => "create_composition",
BenchOp::GetCompositionAtTime => "get_composition_at_time",
BenchOp::GetCompositionLatest => "get_composition_latest",
BenchOp::GetEhr => "get_ehr",
BenchOp::GetEhrStatus => "get_ehr_status",
BenchOp::GetVersionedComposition => "get_versioned_composition",
BenchOp::GetVersionedCompositionRevisionHistory => {
"get_versioned_composition_revision_history"
}
BenchOp::GetVersionedCompositionVersionAtTime => {
"get_versioned_composition_version_at_time"
}
BenchOp::GetVersionedCompositionVersionById => {
"get_versioned_composition_version_by_id"
}
BenchOp::GetVersionedCompositionVersionLatest => {
"get_versioned_composition_version_latest"
}
BenchOp::AdhocQueryUid => "adhoc_query_uid",
BenchOp::AdhocQueryAggregate => "adhoc_query_aggregate",
BenchOp::AdhocQueryEhrScan => "adhoc_query_ehr_scan",
BenchOp::AdhocQueryFiltered => "adhoc_query_filtered",
BenchOp::AdhocQueryOrderedPage => "adhoc_query_ordered_page",
BenchOp::AdhocQueryPointLookup => "adhoc_query_point_lookup",
BenchOp::AdhocQueryPopulation => "adhoc_query_population",
}
}
#[must_use]
pub const fn wire(self) -> &'static str {
match self {
BenchOp::CreateComposition => "POST /ehr/{ehr_id}/composition",
BenchOp::GetCompositionAtTime => {
"GET /ehr/{ehr_id}/composition/{uid}?version_at_time={at_time}"
}
BenchOp::GetCompositionLatest => "GET /ehr/{ehr_id}/composition/{uid}",
BenchOp::GetEhr => "GET /ehr/{ehr_id}",
BenchOp::GetEhrStatus => "GET /ehr/{ehr_id}/ehr_status",
BenchOp::GetVersionedComposition => "GET /ehr/{ehr_id}/versioned_composition/{uid}",
BenchOp::GetVersionedCompositionRevisionHistory => {
"GET /ehr/{ehr_id}/versioned_composition/{uid}/revision_history"
}
BenchOp::GetVersionedCompositionVersionAtTime => {
"GET /ehr/{ehr_id}/versioned_composition/{uid}/version?version_at_time={at_time}"
}
BenchOp::GetVersionedCompositionVersionById => {
"GET /ehr/{ehr_id}/versioned_composition/{uid}/version/{version_uid}"
}
BenchOp::GetVersionedCompositionVersionLatest => {
"GET /ehr/{ehr_id}/versioned_composition/{uid}/version"
}
BenchOp::AdhocQueryUid
| BenchOp::AdhocQueryAggregate
| BenchOp::AdhocQueryEhrScan
| BenchOp::AdhocQueryFiltered
| BenchOp::AdhocQueryOrderedPage
| BenchOp::AdhocQueryPointLookup
| BenchOp::AdhocQueryPopulation => "POST /query/aql",
}
}
#[must_use]
pub fn path(self, ehr_id: &str, uid: &str, version_uid: &str, at_time: &str) -> String {
self.wire()
.split_once(' ')
.map_or(self.wire(), |(_method, path)| path)
.replace("{ehr_id}", ehr_id)
.replace("{uid}", uid)
.replace("{version_uid}", version_uid)
.replace("{at_time}", at_time)
}
#[must_use]
pub const fn addresses_a_composition(self) -> bool {
match self {
BenchOp::CreateComposition
| BenchOp::GetEhr
| BenchOp::GetEhrStatus
| BenchOp::AdhocQueryUid
| BenchOp::AdhocQueryAggregate
| BenchOp::AdhocQueryEhrScan
| BenchOp::AdhocQueryFiltered
| BenchOp::AdhocQueryOrderedPage
| BenchOp::AdhocQueryPopulation => false,
BenchOp::GetCompositionAtTime
| BenchOp::GetCompositionLatest
| BenchOp::GetVersionedComposition
| BenchOp::GetVersionedCompositionRevisionHistory
| BenchOp::GetVersionedCompositionVersionAtTime
| BenchOp::GetVersionedCompositionVersionById
| BenchOp::GetVersionedCompositionVersionLatest
| BenchOp::AdhocQueryPointLookup => true,
}
}
#[must_use]
pub const fn is_adhoc_query(self) -> bool {
match self {
BenchOp::AdhocQueryAggregate
| BenchOp::AdhocQueryEhrScan
| BenchOp::AdhocQueryFiltered
| BenchOp::AdhocQueryOrderedPage
| BenchOp::AdhocQueryPointLookup
| BenchOp::AdhocQueryPopulation
| BenchOp::AdhocQueryUid => true,
BenchOp::CreateComposition
| BenchOp::GetCompositionAtTime
| BenchOp::GetCompositionLatest
| BenchOp::GetEhr
| BenchOp::GetEhrStatus
| BenchOp::GetVersionedComposition
| BenchOp::GetVersionedCompositionRevisionHistory
| BenchOp::GetVersionedCompositionVersionAtTime
| BenchOp::GetVersionedCompositionVersionById
| BenchOp::GetVersionedCompositionVersionLatest => false,
}
}
pub fn parse(token: &str) -> Result<Self, BenchError> {
Self::ALL
.iter()
.copied()
.find(|op| op.as_str() == token)
.ok_or_else(|| BenchError::UnknownToken {
vocabulary: "bench operation",
token: token.to_owned(),
accepted: accepted_ops(),
})
}
}
impl fmt::Display for BenchOp {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
fn accepted_ops() -> String {
BenchOp::ALL
.iter()
.map(|op| op.as_str())
.collect::<Vec<_>>()
.join(", ")
}
#[derive(Debug, Clone)]
pub struct SeedPhase {
pub name: String,
pub fixtures: Vec<Fixture>,
pub ehrs: usize,
pub compositions_per_ehr: usize,
pub workers: usize,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MixEntry {
pub op: BenchOp,
pub share: u32,
pub rationale: String,
}
impl MixEntry {
#[must_use]
pub fn new(op: BenchOp, share: u32, rationale: &str) -> Self {
Self {
op,
share,
rationale: rationale.to_owned(),
}
}
}
#[derive(Debug, Clone)]
pub struct MeasurePhase {
pub name: String,
pub rate_per_s: f64,
pub warmup_s: u64,
pub duration_s: u64,
pub mix: Vec<MixEntry>,
}
impl MeasurePhase {
#[must_use]
pub fn total_share(&self) -> u64 {
self.mix
.iter()
.map(|entry| u64::from(entry.share))
.fold(0_u64, u64::saturating_add)
}
#[must_use]
pub fn op_for_draw(&self, draw: u64) -> Option<BenchOp> {
let total = self.total_share();
if total == 0 {
return None;
}
let mut point = draw % total;
for entry in &self.mix {
let share = u64::from(entry.share);
if point < share {
return Some(entry.op);
}
point = point.saturating_sub(share);
}
self.mix.last().map(|entry| entry.op)
}
#[must_use]
pub fn planned_arrivals(&self) -> u64 {
let span_s = self.warmup_s.saturating_add(self.duration_s);
if self.rate_per_s <= 0.0 || span_s == 0 {
return 0;
}
#[expect(
clippy::as_conversions,
clippy::cast_precision_loss,
clippy::cast_possible_truncation,
clippy::cast_sign_loss,
reason = "the arrival count is rate x span, both operator-scale values far below 2^52"
)]
let total = (self.rate_per_s * span_s as f64).ceil() as u64;
total
}
#[must_use]
pub fn is_measured(&self, index: u64) -> bool {
if self.rate_per_s <= 0.0 {
return false;
}
#[expect(
clippy::as_conversions,
clippy::cast_precision_loss,
reason = "the arrival ordinal and the warmup boundary are operator-scale values far below 2^52"
)]
let measured = index as f64 / self.rate_per_s >= self.warmup_s as f64;
measured
}
#[must_use]
pub fn planned_measured_arrivals(&self) -> u64 {
(0..self.planned_arrivals())
.filter(|index| self.is_measured(*index))
.count()
.try_into()
.unwrap_or(u64::MAX)
}
#[must_use]
pub fn rate_of(&self, entry: &MixEntry) -> f64 {
let total = self.total_share();
if total == 0 {
return 0.0;
}
#[expect(
clippy::as_conversions,
clippy::cast_precision_loss,
reason = "the share and its total are small operator-scale counts"
)]
let rate = self.rate_per_s * (f64::from(entry.share) / total as f64);
rate
}
#[must_use]
pub fn rationales(&self) -> BTreeMap<String, String> {
self.mix
.iter()
.map(|entry| (entry.op.as_str().to_owned(), entry.rationale.clone()))
.collect()
}
}
#[derive(Debug, Clone)]
pub struct SweepPhase {
pub name: String,
pub per_composition: Vec<BenchOp>,
pub workers: usize,
}
impl SweepPhase {
#[must_use]
pub fn requests(&self, compositions: usize) -> usize {
compositions.saturating_mul(self.per_composition.len())
}
}
#[derive(Debug, Clone)]
pub enum BenchPhase {
Seed(SeedPhase),
Sweep(SweepPhase),
Measure(MeasurePhase),
}
pub const DEFAULT_MAX_FAILED_SHARE: f64 = 0.01;
#[must_use]
pub fn failed_share_statement() -> String {
format!(
"This pack version pins a failed-arrival ceiling of {DEFAULT_MAX_FAILED_SHARE:.2}: a \
record in which any repetition, phase and operation loses a larger share of its \
arrivals, on the target or on any baseline, is not submittable, because percentiles \
taken over failed arrivals measure the failure rather than the system."
)
}
#[derive(Debug, Clone)]
pub struct BenchPack {
pub id: PackId,
pub version: String,
pub description: String,
pub max_failed_share: f64,
pub seed: u64,
pub profiles: Vec<&'static PostureProfile>,
pub phases: Vec<BenchPhase>,
}
impl BenchPack {
#[must_use]
pub fn with_phases(mut self, phases: Vec<BenchPhase>) -> Self {
self.phases = phases;
self
}
pub fn resolve_profile(
&self,
token: Option<&str>,
) -> Result<&'static PostureProfile, BenchError> {
let Some(token) = token else {
return self
.profiles
.first()
.copied()
.ok_or_else(|| BenchError::NoProfiles { pack: self.id });
};
self.profiles
.iter()
.copied()
.find(|profile| profile.name == token)
.ok_or_else(|| BenchError::UnknownProfile {
pack: self.id,
requested: token.to_owned(),
known: self.profile_names().join(", "),
})
}
#[must_use]
pub fn profile_names(&self) -> Vec<&'static str> {
self.profiles.iter().map(|profile| profile.name).collect()
}
#[must_use]
pub fn invalid_twin(&self) -> Option<Fixture> {
self.fixtures()
.into_iter()
.find(|fixture| fixture.kind == FixtureKind::InvalidComposition)
}
#[must_use]
pub fn fixtures(&self) -> Vec<Fixture> {
self.phases
.iter()
.filter_map(|phase| match phase {
BenchPhase::Seed(seed) => Some(seed.fixtures.clone()),
BenchPhase::Sweep(_) | BenchPhase::Measure(_) => None,
})
.flatten()
.collect()
}
#[must_use]
pub fn fixture_pins(&self) -> BTreeMap<String, String> {
self.fixtures()
.into_iter()
.map(|fixture| (fixture.key.as_str().to_owned(), fixture.sha256.to_owned()))
.collect()
}
pub fn verify_pins(&self) -> Result<(), BenchError> {
for fixture in self.fixtures() {
fixture.verify(self.id)?;
}
Ok(())
}
pub fn verify_fixture_roots(&self) -> Result<(), BenchError> {
let templates = self.template_identities()?;
for fixture in self.fixtures() {
match fixture.kind {
FixtureKind::OperationalTemplate => continue,
FixtureKind::Composition | FixtureKind::InvalidComposition => {}
}
let declared = composition_roots(fixture.bytes).map_err(|detail| {
BenchError::FixtureUnreadable {
pack: self.id,
fixture: fixture.key,
detail,
}
})?;
let Some(template) = templates
.iter()
.find(|identity| identity.id == declared.archetype_details.template_id.value)
else {
return Err(BenchError::FixtureTemplate {
pack: self.id,
fixture: fixture.key,
template: declared.archetype_details.template_id.value,
seeded: templates
.iter()
.map(|identity| identity.id.as_str())
.collect::<Vec<_>>()
.join(", "),
});
};
if declared.archetype_node_id != template.root
|| declared.archetype_details.archetype_id.value != template.root
{
return Err(BenchError::FixtureRoot(Box::new(RootMismatch {
pack: self.id,
fixture: fixture.key,
template: template.id.clone(),
root: template.root.clone(),
node_id: declared.archetype_node_id,
archetype_id: declared.archetype_details.archetype_id.value,
})));
}
}
Ok(())
}
fn template_identities(&self) -> Result<Vec<TemplateIdentity>, BenchError> {
let mut identities = Vec::new();
for fixture in self.fixtures() {
match fixture.kind {
FixtureKind::OperationalTemplate => {}
FixtureKind::Composition | FixtureKind::InvalidComposition => continue,
}
let identity = template_identity(fixture.bytes).map_err(|detail| {
BenchError::FixtureUnreadable {
pack: self.id,
fixture: fixture.key,
detail,
}
})?;
identities.push(identity);
}
Ok(identities)
}
#[must_use]
pub fn measure_phases(&self) -> Vec<&MeasurePhase> {
self.phases
.iter()
.filter_map(|phase| match phase {
BenchPhase::Measure(measure) => Some(measure),
BenchPhase::Seed(_) | BenchPhase::Sweep(_) => None,
})
.collect()
}
#[must_use]
pub fn probe_rationales(&self) -> BTreeMap<String, String> {
self.measure_phases()
.into_iter()
.flat_map(MeasurePhase::rationales)
.collect()
}
#[must_use]
pub fn sweep_phases(&self) -> Vec<&SweepPhase> {
self.phases
.iter()
.filter_map(|phase| match phase {
BenchPhase::Sweep(sweep) => Some(sweep),
BenchPhase::Seed(_) | BenchPhase::Measure(_) => None,
})
.collect()
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RootMismatch {
pub pack: PackId,
pub fixture: FixtureKey,
pub template: String,
pub root: String,
pub node_id: String,
pub archetype_id: String,
}
#[derive(Debug, Clone, PartialEq, Eq)]
struct TemplateIdentity {
id: String,
root: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
struct CompositionRoots {
archetype_node_id: String,
archetype_details: DeclaredArchetyped,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
struct DeclaredArchetyped {
archetype_id: DeclaredId,
template_id: DeclaredId,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
struct DeclaredId {
value: String,
}
fn template_identity(opt_xml: &str) -> Result<TemplateIdentity, String> {
let mut reader = quick_xml::Reader::from_str(opt_xml);
let mut path: Vec<String> = Vec::new();
let mut id: Option<String> = None;
let mut root: Option<String> = None;
loop {
let event = reader.read_event().map_err(|e| e.to_string())?;
match event {
quick_xml::events::Event::Eof if path.is_empty() => break,
quick_xml::events::Event::Eof => {
return Err(format!(
"the document ends with {} element(s) still open",
path.len()
));
}
quick_xml::events::Event::Start(start) => {
path.push(String::from_utf8_lossy(start.local_name().as_ref()).into_owned());
}
quick_xml::events::Event::End(_) => {
path.pop();
}
quick_xml::events::Event::Text(text) => {
let decoded = text.decode().map_err(|e| e.to_string())?;
let trimmed = decoded.trim();
if trimmed.is_empty() {
continue;
}
if path_is(&path, &["template", "template_id", "value"]) {
id = Some(trimmed.to_owned());
} else if path_is(&path, &["template", "definition", "archetype_id", "value"]) {
root = Some(trimmed.to_owned());
}
}
_ => {}
}
}
let id = id.ok_or_else(|| "no template/template_id/value".to_owned())?;
let root = root.ok_or_else(|| "no template/definition/archetype_id/value".to_owned())?;
Ok(TemplateIdentity { id, root })
}
fn path_is(path: &[String], expected: &[&str]) -> bool {
path.len() == expected.len()
&& path
.iter()
.zip(expected)
.all(|(open, want)| open.as_str() == *want)
}
fn composition_roots(json: &str) -> Result<CompositionRoots, String> {
serde_json::from_str(json).map_err(|e| e.to_string())
}
const SMOKE: PackId = PackId("smoke");
const COMMUNITY_VITALS: PackId = PackId("community-vitals");
const AQL_MIX: PackId = PackId("aql-mix");
const COMMUNITY_READS: &[(BenchOp, &str)] = &[
(
BenchOp::GetCompositionLatest,
"the harness's latest-version composition read, the read a client issues most",
),
(
BenchOp::GetCompositionAtTime,
"the harness's composition read at an instant, which resolves a version by time",
),
(
BenchOp::GetVersionedComposition,
"the harness's read of the VERSIONED_COMPOSITION container itself",
),
(
BenchOp::GetVersionedCompositionVersionLatest,
"the harness's latest-version read through the versioned object",
),
(
BenchOp::GetVersionedCompositionVersionAtTime,
"the harness's version-at-an-instant read through the versioned object",
),
(
BenchOp::GetVersionedCompositionVersionById,
"the harness's read of one version by its own identifier",
),
(
BenchOp::GetVersionedCompositionRevisionHistory,
"the harness's revision-history read, which walks every version of the object",
),
];
pub const EMBEDDED: &[PackId] = &[AQL_MIX, COMMUNITY_VITALS, SMOKE];
pub fn load(token: &str) -> Result<BenchPack, BenchError> {
let pack = match token {
"smoke" => smoke(),
"community-vitals" => community_vitals(),
"aql-mix" => aql_mix(),
other => {
return Err(BenchError::UnknownPack {
requested: other.to_owned(),
known: EMBEDDED
.iter()
.map(|id| id.as_str())
.collect::<Vec<_>>()
.join(", "),
});
}
};
pack.verify_pins()?;
pack.verify_fixture_roots()?;
Ok(pack)
}
const SMOKE_PREAMBLE: &str = "\
One blood-pressure template, a small EHR corpus, and a mixed open-loop phase \
over the read, write and query surface. Version 1.1.0 moved the committed \
composition onto openEHR-EHR-COMPOSITION.minimal.v1, the root its own template \
defines, so the bytes offered to a server changed and a 1.1.0 record is not \
comparable with a 1.0.0 one.";
#[must_use]
pub fn smoke() -> BenchPack {
BenchPack {
id: SMOKE,
version: "1.2.0".to_owned(),
description: format!("{SMOKE_PREAMBLE} {}", failed_share_statement()),
max_failed_share: DEFAULT_MAX_FAILED_SHARE,
seed: 0x5645_5245_4449_4354,
profiles: vec![&MINIMAL, &MINIMAL_SIGNED_DIGEST, &MINIMAL_SIGNED_PGP],
phases: vec![
BenchPhase::Seed(SeedPhase {
name: "seed".to_owned(),
fixtures: vec![
Fixture {
key: FixtureKey("blood_pressure.opt"),
kind: FixtureKind::OperationalTemplate,
bytes: BLOOD_PRESSURE_OPT,
sha256: BLOOD_PRESSURE_OPT_SHA256,
provenance: BLOOD_PRESSURE_OPT_PROVENANCE,
},
Fixture {
key: FixtureKey("bp_composition.json"),
kind: FixtureKind::Composition,
bytes: BP_COMPOSITION,
sha256: BP_COMPOSITION_SHA256,
provenance: BP_COMPOSITION_PROVENANCE,
},
Fixture {
key: FixtureKey("bp_composition.missing_composer.json"),
kind: FixtureKind::InvalidComposition,
bytes: BP_COMPOSITION_TWIN,
sha256: BP_COMPOSITION_TWIN_SHA256,
provenance: BP_COMPOSITION_TWIN_PROVENANCE,
},
],
ehrs: 200,
compositions_per_ehr: 5,
workers: 8,
}),
BenchPhase::Measure(MeasurePhase {
name: "mixed".to_owned(),
rate_per_s: 50.0,
warmup_s: 10,
duration_s: 60,
mix: vec![
MixEntry::new(
BenchOp::CreateComposition,
20,
"the commit path, measured while reads compete with it",
),
MixEntry::new(
BenchOp::GetCompositionLatest,
30,
"the latest-version composition read",
),
MixEntry::new(
BenchOp::GetEhr,
20,
"the EHR resource read, the cheapest addressed read the API offers",
),
MixEntry::new(
BenchOp::GetEhrStatus,
15,
"the status read, which reaches a second versioned object in the same EHR",
),
MixEntry::new(
BenchOp::AdhocQueryUid,
15,
"an EHR-scoped projection, so the query path is exercised beside the direct reads",
),
],
}),
],
}
}
fn vital_signs_fixtures() -> Vec<Fixture> {
vec![
Fixture {
key: FixtureKey("vital_signs.opt"),
kind: FixtureKind::OperationalTemplate,
bytes: VITAL_SIGNS_OPT,
sha256: VITAL_SIGNS_OPT_SHA256,
provenance: VITAL_SIGNS_OPT_PROVENANCE,
},
Fixture {
key: FixtureKey("vital_signs_composition.json"),
kind: FixtureKind::Composition,
bytes: VITAL_SIGNS_COMPOSITION,
sha256: VITAL_SIGNS_COMPOSITION_SHA256,
provenance: VITAL_SIGNS_COMPOSITION_PROVENANCE,
},
Fixture {
key: FixtureKey("vital_signs_composition.missing_composer.json"),
kind: FixtureKind::InvalidComposition,
bytes: VITAL_SIGNS_COMPOSITION_TWIN,
sha256: VITAL_SIGNS_COMPOSITION_TWIN_SHA256,
provenance: VITAL_SIGNS_COMPOSITION_TWIN_PROVENANCE,
},
]
}
const COMMUNITY_EHRS: usize = 100;
const COMMUNITY_COMPOSITIONS_PER_EHR: usize = 1_000;
const COMMUNITY_READ_RATE_PER_S: f64 = 200.0;
#[must_use]
pub fn community_vitals() -> BenchPack {
let fixtures = vital_signs_fixtures();
BenchPack {
id: COMMUNITY_VITALS,
version: "1.1.0".to_owned(),
description: format!(
"{COMMUNITY_VITALS_DESCRIPTION} {}",
failed_share_statement()
),
max_failed_share: DEFAULT_MAX_FAILED_SHARE,
seed: 0x436f_6d6d_5f56_6974,
profiles: vec![
&MINIMAL,
&MINIMAL_SIGNED_DIGEST,
&MINIMAL_SIGNED_PGP,
&CLINICAL_DEFAULT,
],
phases: vec![
BenchPhase::Seed(SeedPhase {
name: "write".to_owned(),
fixtures,
ehrs: COMMUNITY_EHRS,
compositions_per_ehr: COMMUNITY_COMPOSITIONS_PER_EHR,
workers: 1,
}),
BenchPhase::Sweep(SweepPhase {
name: "read_walk".to_owned(),
per_composition: COMMUNITY_READS.iter().map(|(op, _)| *op).collect(),
workers: 1,
}),
BenchPhase::Measure(MeasurePhase {
name: "read_open_loop".to_owned(),
rate_per_s: COMMUNITY_READ_RATE_PER_S,
warmup_s: 15,
duration_s: 60,
mix: COMMUNITY_READS
.iter()
.map(|(op, rationale)| MixEntry::new(*op, 1, rationale))
.collect(),
}),
],
}
}
const COMMUNITY_VITALS_DESCRIPTION: &str = "\
Reproduces the openEHR community's vital-signs benchmark harness \
(<https://discourse.openehr.org/t/17224>) and measures the same work a second \
way. The write phase creates 100 EHRs and commits the same Vital signs \
composition 1,000 times into each with Prefer: return=identifier, on one \
worker, and reports bulk-load throughput plus the whole-loop \
milliseconds-per-composition average the thread quotes, labelled closed-loop. \
The read phase then runs twice: read_walk is the sequential walk over every \
committed composition, seven GETs each (latest, version_at_time, the \
VERSIONED_COMPOSITION, its latest version, its version at that instant, one \
version by id, and the revision history), reporting the whole-loop \
microseconds-per-request average, labelled closed-loop; read_open_loop offers \
the same seven reads as an arrival schedule pinned at 200/s for 60s after a \
15s warmup, which is where the coordinated-omission-free percentiles come \
from. The pinned rate is part of this pack version: changing it changes the \
work and bumps the version. Every version_at_time read addresses one instant \
captured after the write phase finished, which every seeded version predates, \
so it selects the same versions the harness's own start-of-run instant \
selects. Fixture provenance: the operational template is the vendored CKM \
export for template id 'Vital signs' (CKM cid 1013.26.380), byte-identical; \
the composition is the attachment on post 8 of that thread, byte-identical. \
Both are pinned by sha256 and verified at load.";
const AQL_MIX_EHRS: usize = 50;
const AQL_MIX_COMPOSITIONS_PER_EHR: usize = 20;
const AQL_MIX_SEED_WORKERS: usize = 8;
const AQL_MIX_RATE_PER_S: f64 = 24.0;
const AQL_MIX_WARMUP_S: u64 = 15;
const AQL_MIX_DURATION_S: u64 = 60;
const AQL_MIX_CLASSES: &[(BenchOp, &str)] = &[
(
BenchOp::AdhocQueryPointLookup,
"the indexed-read floor: one composition addressed by its own uid inside one EHR, the cheapest query a server can answer",
),
(
BenchOp::AdhocQueryEhrScan,
"the loaded-database shape: every composition in one EHR projected by uid, so the cost follows how much that EHR holds",
),
(
BenchOp::AdhocQueryFiltered,
"the value index: a systolic magnitude threshold over the observation leaves of one EHR, with the threshold drawn per arrival so no result set can be memoized",
),
(
BenchOp::AdhocQueryPopulation,
"the cross-EHR planner: the same magnitude threshold with no EHR scope and a fetch bound, so the server picks an access path over the whole population",
),
(
BenchOp::AdhocQueryAggregate,
"the columnar shape: one COUNT over the population that threshold matches, which returns a single row and reads every value behind it",
),
(
BenchOp::AdhocQueryOrderedPage,
"sorting and pagination: an ORDER BY over composition start time read through a moving fetch window, the shape a paged user interface issues",
),
];
#[must_use]
pub fn aql_mix() -> BenchPack {
BenchPack {
id: AQL_MIX,
version: "1.1.0".to_owned(),
description: aql_mix_description(),
max_failed_share: DEFAULT_MAX_FAILED_SHARE,
seed: 0x4151_4c5f_4d69_7800,
profiles: vec![&MINIMAL, &MINIMAL_SIGNED_DIGEST, &MINIMAL_SIGNED_PGP],
phases: vec![
BenchPhase::Seed(SeedPhase {
name: "seed".to_owned(),
fixtures: vital_signs_fixtures(),
ehrs: AQL_MIX_EHRS,
compositions_per_ehr: AQL_MIX_COMPOSITIONS_PER_EHR,
workers: AQL_MIX_SEED_WORKERS,
}),
BenchPhase::Measure(MeasurePhase {
name: "queries".to_owned(),
rate_per_s: AQL_MIX_RATE_PER_S,
warmup_s: AQL_MIX_WARMUP_S,
duration_s: AQL_MIX_DURATION_S,
mix: AQL_MIX_CLASSES
.iter()
.map(|(op, rationale)| MixEntry::new(*op, 1, rationale))
.collect(),
}),
],
}
}
fn aql_mix_description() -> String {
let classes = AQL_MIX_CLASSES
.iter()
.map(|(op, rationale)| format!("{op} probes {rationale}"))
.collect::<Vec<_>>()
.join("; ");
format!(
"{AQL_MIX_PREAMBLE} The six classes: {classes}. {AQL_MIX_PROVENANCE} {}",
failed_share_statement()
)
}
const AQL_MIX_PREAMBLE: &str = "\
Measures AQL query speed over the same Vital signs population the \
community-vitals pack seeds, so a query figure and a read figure describe the \
same corpus. The seed phase creates 50 EHRs and commits the same composition \
20 times into each, on a pool of 8 workers. This pack version pins that \
population, and it is sized for query shapes: large enough that a query has to \
choose an access path, small enough to load before a measured window opens. \
The measured phase is open-loop at 24 arrivals a \
second for 60s after a 15s warmup, over six query classes at equal share, so \
each class is offered at 4 arrivals a second and every class returns the same \
number of samples. Each class posts one AQL statement to /query/aql, accepts \
only 200, and counts every other answer in its own error class, so a server \
that refuses one shape never contaminates another class's percentiles. Every \
query parameter draws from the run's seeded streams: the systolic threshold, \
the page offset, and the EHR or composition each arrival addresses, so no \
arrival repeats the previous one's result set and the whole draw is \
reproducible from the seed the record discloses.";
const AQL_MIX_PROVENANCE: &str = "\
Fixture provenance: the operational template is the vendored CKM export for \
template id 'Vital signs' (CKM cid 1013.26.380) and the composition is the \
attachment on post 8 of <https://discourse.openehr.org/t/17224>, both \
byte-identical and pinned by sha256.";
#[cfg(test)]
#[expect(
clippy::panic_in_result_fn,
reason = "Result-returning tests in the Book ch11 shape, each asserting; \
clippy offers no allow-in-tests knob for this lint"
)]
mod tests {
use super::*;
#[test]
fn every_embedded_pack_loads_with_verified_pins() -> Result<(), BenchError> {
for id in EMBEDDED {
let pack = load(id.as_str())?;
assert_eq!(pack.id, *id);
assert!(!pack.fixtures().is_empty(), "{id} embeds no fixture");
pack.verify_pins()?;
}
Ok(())
}
const DOCTORED_COMPOSITION: &str = r#"{
"_type": "COMPOSITION",
"archetype_node_id": "openEHR-EHR-COMPOSITION.encounter.v1",
"archetype_details": {
"_type": "ARCHETYPED",
"archetype_id": { "_type": "ARCHETYPE_ID", "value": "openEHR-EHR-COMPOSITION.encounter.v1" },
"template_id": { "_type": "TEMPLATE_ID", "value": "cnf.blood_pressure" },
"rm_version": "1.0.2"
}
}"#;
const UNSEEDED_TEMPLATE_COMPOSITION: &str = r#"{
"_type": "COMPOSITION",
"archetype_node_id": "openEHR-EHR-COMPOSITION.minimal.v1",
"archetype_details": {
"_type": "ARCHETYPED",
"archetype_id": { "_type": "ARCHETYPE_ID", "value": "openEHR-EHR-COMPOSITION.minimal.v1" },
"template_id": { "_type": "TEMPLATE_ID", "value": "cnf.absent" },
"rm_version": "1.0.2"
}
}"#;
fn with_composition_bytes(bytes: &'static str) -> BenchPack {
let pack = smoke();
let phases = pack
.phases
.iter()
.map(|phase| match phase {
BenchPhase::Seed(seed) => {
let mut seed = seed.clone();
for fixture in &mut seed.fixtures {
if fixture.kind == FixtureKind::Composition {
fixture.bytes = bytes;
}
}
BenchPhase::Seed(seed)
}
other => other.clone(),
})
.collect();
pack.with_phases(phases)
}
#[test]
fn every_embedded_pack_agrees_with_its_own_templates() -> Result<(), BenchError> {
for id in EMBEDDED {
load(id.as_str())?.verify_fixture_roots()?;
}
Ok(())
}
#[test]
fn the_smoke_template_declares_the_root_its_compositions_carry() -> Result<(), String> {
let identity = template_identity(BLOOD_PRESSURE_OPT)?;
assert_eq!(identity.id, "cnf.blood_pressure");
assert_eq!(identity.root, "openEHR-EHR-COMPOSITION.minimal.v1");
for bytes in [BP_COMPOSITION, BP_COMPOSITION_TWIN] {
let declared = composition_roots(bytes)?;
assert_eq!(declared.archetype_details.template_id.value, identity.id);
assert_eq!(declared.archetype_node_id, identity.root);
assert_eq!(declared.archetype_details.archetype_id.value, identity.root);
}
Ok(())
}
#[test]
fn a_fixture_root_its_template_does_not_have_is_refused() {
let error = with_composition_bytes(DOCTORED_COMPOSITION)
.verify_fixture_roots()
.unwrap_err();
let BenchError::FixtureRoot(mismatch) = &error else {
panic!("expected a fixture-root refusal, got {error}");
};
assert_eq!(mismatch.fixture.as_str(), "bp_composition.json");
assert_eq!(mismatch.template, "cnf.blood_pressure");
assert_eq!(mismatch.root, "openEHR-EHR-COMPOSITION.minimal.v1");
assert_eq!(mismatch.node_id, "openEHR-EHR-COMPOSITION.encounter.v1");
assert_eq!(
mismatch.archetype_id,
"openEHR-EHR-COMPOSITION.encounter.v1"
);
let rendered = error.to_string();
assert!(
rendered.contains("openEHR-EHR-COMPOSITION.encounter.v1")
&& rendered.contains("openEHR-EHR-COMPOSITION.minimal.v1"),
"{rendered}"
);
}
#[test]
fn a_fixture_naming_an_unseeded_template_is_refused() {
let error = with_composition_bytes(UNSEEDED_TEMPLATE_COMPOSITION)
.verify_fixture_roots()
.unwrap_err();
assert!(
matches!(error, BenchError::FixtureTemplate { .. }),
"{error}"
);
assert!(error.to_string().contains("cnf.absent"), "{error}");
}
#[test]
fn an_unreadable_fixture_is_refused() {
let error = with_composition_bytes("{")
.verify_fixture_roots()
.unwrap_err();
assert!(
matches!(error, BenchError::FixtureUnreadable { .. }),
"{error}"
);
}
#[test]
fn a_truncated_template_is_refused() {
let truncated = "<template><template_id><value>t</value></template_id>";
assert!(template_identity(truncated).is_err());
}
#[test]
fn a_moved_pin_is_refused() {
let fixture = Fixture {
key: FixtureKey("moved"),
kind: FixtureKind::Composition,
bytes: "{}",
sha256: "0000000000000000000000000000000000000000000000000000000000000000",
provenance: "authored for this test",
};
let error = fixture.verify(SMOKE).unwrap_err();
assert!(matches!(error, BenchError::FixturePin { .. }), "{error}");
assert!(error.to_string().contains("moved"), "{error}");
}
#[test]
fn an_unknown_pack_is_refused() {
let error = load("does-not-exist").unwrap_err();
assert!(error.to_string().contains("smoke"), "{error}");
}
#[test]
fn every_operation_publishes_a_substitutable_wire_template() {
for op in BenchOp::ALL {
let wire = op.wire();
assert!(
wire.starts_with("GET /") || wire.starts_with("POST /"),
"{op}: {wire} is not a method plus a path"
);
let path = op.path("E", "U", "V", "T");
assert!(!path.contains('{'), "{op}: {path} kept a placeholder");
assert!(path.starts_with('/'), "{op}: {path} is not rooted");
}
}
#[test]
fn a_wire_path_substitutes_only_what_its_operation_addresses() {
assert_eq!(
BenchOp::GetVersionedCompositionVersionById.path("E", "U", "V", "T"),
"/ehr/E/versioned_composition/U/version/V"
);
assert_eq!(
BenchOp::GetCompositionAtTime.path("E", "U", "V", "T"),
"/ehr/E/composition/U?version_at_time=T"
);
assert_eq!(
BenchOp::GetEhrStatus.path("E", "U", "V", "T"),
"/ehr/E/ehr_status"
);
assert_eq!(
BenchOp::AdhocQueryUid.path("E", "U", "V", "T"),
"/query/aql"
);
}
#[test]
fn an_unknown_operation_token_is_refused() {
assert!(BenchOp::parse("create_composition").is_ok());
let error = BenchOp::parse("create_compositon").unwrap_err();
assert!(matches!(error, BenchError::UnknownToken { .. }), "{error}");
}
#[test]
fn every_operation_token_round_trips() -> Result<(), BenchError> {
for op in BenchOp::ALL {
assert_eq!(BenchOp::parse(op.as_str())?, *op);
}
Ok(())
}
#[test]
fn the_operation_vocabulary_is_token_sorted() {
let mut sorted: Vec<&str> = BenchOp::ALL.iter().map(|op| op.as_str()).collect();
let listed = sorted.clone();
sorted.sort_unstable();
assert_eq!(listed, sorted);
}
#[test]
fn the_mix_picker_follows_the_declared_shares() {
let phase = MeasurePhase {
name: "t".to_owned(),
rate_per_s: 1.0,
warmup_s: 0,
duration_s: 1,
mix: vec![
MixEntry::new(BenchOp::GetEhr, 3, "the EHR read"),
MixEntry::new(BenchOp::CreateComposition, 1, "the commit"),
],
};
let picked: Vec<BenchOp> = (0..8).filter_map(|d| phase.op_for_draw(d)).collect();
assert_eq!(
picked,
vec![
BenchOp::GetEhr,
BenchOp::GetEhr,
BenchOp::GetEhr,
BenchOp::CreateComposition,
BenchOp::GetEhr,
BenchOp::GetEhr,
BenchOp::GetEhr,
BenchOp::CreateComposition,
]
);
}
#[test]
fn the_community_pack_pins_its_source_fixtures() -> Result<(), BenchError> {
let deck = load("community-vitals")?;
assert_eq!(deck.id, COMMUNITY_VITALS);
assert_eq!(deck.version, "1.1.0");
let pins = deck.fixture_pins();
assert_eq!(
pins.get("vital_signs.opt").map(String::as_str),
Some("3a0d31bd3b5dc6329e53c0d6f22fdbaece62c684136b86139d0729cff8796128")
);
assert_eq!(
pins.get("vital_signs_composition.json").map(String::as_str),
Some("468081c259c737d35d7f80403562b3f333e479d267286faf80fd7c087eaba947")
);
assert_eq!(
pins.get("vital_signs_composition.missing_composer.json")
.map(String::as_str),
Some("f0598db5ab447b371ead28cba0f841f72370dbbf93db98d5b8e477910a42688d")
);
assert_eq!(pins.len(), 3);
deck.verify_pins()
}
#[test]
fn every_pack_declares_its_posture_profiles() -> Result<(), BenchError> {
for id in EMBEDDED {
let deck = load(id.as_str())?;
assert!(!deck.profiles.is_empty(), "{id} defines no posture profile");
assert_eq!(
deck.resolve_profile(None)?.name,
"minimal",
"{id} does not default to the bare spec-conformant surface"
);
assert_eq!(deck.resolve_profile(Some("minimal"))?.name, "minimal");
let error = deck.resolve_profile(Some("hardened")).unwrap_err();
assert!(
matches!(error, BenchError::UnknownProfile { .. }),
"{error}"
);
assert!(error.to_string().contains("minimal"), "{error}");
}
assert_eq!(
community_vitals().profile_names(),
vec![
"minimal",
"minimal-signed-digest",
"minimal-signed-pgp",
"clinical-default"
]
);
Ok(())
}
#[test]
#[expect(
clippy::disallowed_types,
reason = "the approved wire-body seam: both fixtures are JSON documents compared member by member"
)]
fn every_seeded_composition_carries_its_invalid_twin() -> Result<(), Box<dyn std::error::Error>>
{
for id in EMBEDDED {
let deck = load(id.as_str())?;
let fixtures = deck.fixtures();
let Some(valid) = fixtures
.iter()
.find(|fixture| fixture.kind == FixtureKind::Composition)
else {
panic!("{id} seeds no composition");
};
let Some(twin) = deck.invalid_twin() else {
panic!("{id} embeds no invalid twin");
};
let mut parent: serde_json::Value = serde_json::from_str(valid.bytes)?;
let twin_document: serde_json::Value = serde_json::from_str(twin.bytes)?;
let removed = parent
.as_object_mut()
.and_then(|root| root.remove("composer"));
assert!(removed.is_some(), "{id}: the valid twin has no composer");
assert_eq!(
parent, twin_document,
"{id}: the twin differs by more than the composer"
);
assert_eq!(twin.kind.media_type(), "application/json");
twin.verify(deck.id)?;
}
Ok(())
}
#[test]
#[expect(
clippy::disallowed_types,
reason = "the approved wire-body seam: the embedded composition is a JSON document read for two attributes"
)]
fn the_community_composition_names_the_embedded_template()
-> Result<(), Box<dyn std::error::Error>> {
let document: serde_json::Value = serde_json::from_str(VITAL_SIGNS_COMPOSITION)?;
assert_eq!(
document
.pointer("/archetype_details/template_id/value")
.and_then(serde_json::Value::as_str),
Some("Vital signs")
);
assert_eq!(
document
.pointer("/archetype_node_id")
.and_then(serde_json::Value::as_str),
Some("openEHR-EHR-COMPOSITION.encounter.v1")
);
let identity = template_identity(VITAL_SIGNS_OPT)
.map_err(|detail| format!("the embedded template does not parse: {detail}"))?;
assert_eq!(identity.id, "Vital signs");
Ok(())
}
#[test]
fn the_community_pack_carries_one_phase_per_discipline() {
let deck = community_vitals();
assert_eq!(deck.phases.len(), 3);
let seeds: Vec<&SeedPhase> = deck
.phases
.iter()
.filter_map(|phase| match phase {
BenchPhase::Seed(seed) => Some(seed),
BenchPhase::Sweep(_) | BenchPhase::Measure(_) => None,
})
.collect();
assert_eq!(seeds.len(), 1);
assert_eq!(deck.sweep_phases().len(), 1);
assert_eq!(deck.measure_phases().len(), 1);
let Some(write) = seeds.first() else {
panic!("the write phase is gone");
};
assert_eq!(write.ehrs, 100);
assert_eq!(write.compositions_per_ehr, 1000);
assert_eq!(write.workers, 1, "the reproduction is sequential");
}
#[test]
fn the_seven_variant_walk_sums_to_the_published_request_count() {
let deck = community_vitals();
let Some(sweep) = deck.sweep_phases().first().copied() else {
panic!("the read walk is gone");
};
assert_eq!(sweep.per_composition.len(), 7);
assert_eq!(sweep.workers, 1);
let compositions = COMMUNITY_EHRS.saturating_mul(COMMUNITY_COMPOSITIONS_PER_EHR);
assert_eq!(compositions, 100_000);
assert_eq!(sweep.requests(compositions), 700_000);
let distinct: std::collections::BTreeSet<BenchOp> =
sweep.per_composition.iter().copied().collect();
assert_eq!(distinct.len(), 7, "a variant is repeated");
assert!(
sweep
.per_composition
.iter()
.all(|op| op.addresses_a_composition()),
"the walk offers an operation that does not address a composition"
);
}
#[test]
fn the_open_loop_half_mirrors_the_walk_at_a_pinned_rate() {
let deck = community_vitals();
let Some(measure) = deck.measure_phases().first().copied() else {
panic!("the open-loop read phase is gone");
};
assert!((measure.rate_per_s - 200.0).abs() < f64::EPSILON);
assert_eq!(measure.warmup_s, 15);
assert_eq!(measure.duration_s, 60);
assert_eq!(measure.total_share(), 7);
let offered: Vec<BenchOp> = measure.mix.iter().map(|entry| entry.op).collect();
let declared: Vec<BenchOp> = COMMUNITY_READS.iter().map(|(op, _)| *op).collect();
assert_eq!(offered, declared);
}
#[test]
fn an_empty_mix_selects_nothing() {
let phase = MeasurePhase {
name: "t".to_owned(),
rate_per_s: 1.0,
warmup_s: 0,
duration_s: 1,
mix: Vec::new(),
};
assert_eq!(phase.op_for_draw(7), None);
}
#[test]
fn every_embedded_mix_entry_states_what_it_probes() -> Result<(), BenchError> {
for id in EMBEDDED {
let deck = load(id.as_str())?;
let mut entries = 0_usize;
for phase in deck.measure_phases() {
for entry in &phase.mix {
assert!(
!entry.rationale.trim().is_empty(),
"{id}: {} carries no rationale",
entry.op
);
entries = entries.saturating_add(1);
}
}
assert_eq!(
deck.probe_rationales().len(),
entries,
"{id}: the legend lost an entry"
);
}
Ok(())
}
#[test]
fn every_embedded_pack_pins_and_states_its_failed_arrival_ceiling() -> Result<(), BenchError> {
for id in EMBEDDED {
let deck = load(id.as_str())?;
assert!(
(deck.max_failed_share - DEFAULT_MAX_FAILED_SHARE).abs() < f64::EPSILON,
"{id} pins {} rather than the conservative default",
deck.max_failed_share
);
assert!(
deck.description.contains(&failed_share_statement()),
"{id} does not state its failed-arrival ceiling"
);
assert!(deck.description.contains("0.01"), "{id}");
}
Ok(())
}
#[test]
fn the_aql_pack_seeds_the_community_population() -> Result<(), BenchError> {
let deck = load("aql-mix")?;
assert_eq!(deck.id, AQL_MIX);
assert_eq!(deck.version, "1.1.0");
assert_eq!(deck.fixture_pins(), community_vitals().fixture_pins());
assert_eq!(
deck.fixture_pins()
.get("vital_signs.opt")
.map(String::as_str),
Some("3a0d31bd3b5dc6329e53c0d6f22fdbaece62c684136b86139d0729cff8796128")
);
deck.verify_pins()
}
#[test]
fn the_aql_pack_pins_its_population_and_window() {
let deck = aql_mix();
assert_eq!(deck.phases.len(), 2);
assert!(deck.sweep_phases().is_empty());
let seeds: Vec<&SeedPhase> = deck
.phases
.iter()
.filter_map(|phase| match phase {
BenchPhase::Seed(seed) => Some(seed),
BenchPhase::Sweep(_) | BenchPhase::Measure(_) => None,
})
.collect();
let Some(seed) = seeds.first() else {
panic!("the seed phase is gone");
};
assert_eq!(seed.ehrs, 50);
assert_eq!(seed.compositions_per_ehr, 20);
assert_eq!(seed.workers, 8);
assert_eq!(seed.ehrs.saturating_mul(seed.compositions_per_ehr), 1_000);
let Some(measure) = deck.measure_phases().first().copied() else {
panic!("the measured query phase is gone");
};
assert_eq!(measure.name, "queries");
assert!((measure.rate_per_s - 24.0).abs() < f64::EPSILON);
assert_eq!(measure.warmup_s, 15);
assert_eq!(measure.duration_s, 60);
}
#[test]
fn the_aql_pack_offers_six_query_classes_at_equal_share() {
let deck = aql_mix();
let Some(measure) = deck.measure_phases().first().copied() else {
panic!("the measured query phase is gone");
};
assert_eq!(measure.mix.len(), 6);
assert_eq!(measure.total_share(), 6);
assert!(
measure.mix.iter().all(|entry| entry.share == 1),
"a class was given an unequal share"
);
assert!(
measure.mix.iter().all(|entry| entry.op.is_adhoc_query()),
"a class is not an ad-hoc query"
);
let distinct: std::collections::BTreeSet<BenchOp> =
measure.mix.iter().map(|entry| entry.op).collect();
assert_eq!(distinct.len(), 6, "a class is repeated");
let picked: std::collections::BTreeSet<BenchOp> = (0..6)
.filter_map(|draw| measure.op_for_draw(draw))
.collect();
assert_eq!(picked, distinct, "the picker starves a class");
}
#[test]
fn the_aql_pack_description_names_every_class() {
let deck = aql_mix();
for (op, rationale) in AQL_MIX_CLASSES {
assert!(deck.description.contains(op.as_str()), "{op} is unnamed");
assert!(
deck.description.contains(rationale),
"{op} lost its rationale"
);
assert_eq!(
deck.probe_rationales().get(op.as_str()).map(String::as_str),
Some(*rationale)
);
}
assert!(deck.description.contains("sized for query shapes"));
}
}