use serde_json::{json, Value};
use super::{
PORTABLE_BENCHMARK_SCHEMA_VERSION, PORTABLE_MAX_COMPILE_ITERATIONS,
PORTABLE_MAX_DISPATCH_ITERATIONS, PORTABLE_MAX_WORKERS,
};
pub fn portable_benchmark_json_schema() -> Value {
json!({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://harnlang.com/schemas/portable-kernel-benchmark.v1.schema.json",
"$comment": "Generated by `make gen-portable-benchmark-schema`; do not edit by hand.",
"title": "Harn Portable Kernel benchmark receipt v1",
"type": "object",
"additionalProperties": false,
"required": [
"schemaVersion", "target", "source", "entry", "entryKind",
"artifactBytes", "artifactDigest", "iterations", "workers",
"provenance", "initializationMs", "compile", "decode", "dispatch",
"terminalDigest"
],
"properties": {
"schemaVersion": { "const": PORTABLE_BENCHMARK_SCHEMA_VERSION },
"target": { "enum": ["native", "browser"] },
"source": { "type": "string", "minLength": 1 },
"entry": { "type": "string", "minLength": 1 },
"entryKind": { "enum": ["function", "pipeline"] },
"artifactBytes": { "type": "integer", "minimum": 1 },
"artifactDigest": { "$ref": "#/$defs/digest" },
"iterations": {
"type": "integer", "minimum": 1,
"maximum": PORTABLE_MAX_DISPATCH_ITERATIONS
},
"workers": {
"type": "integer", "minimum": 1, "maximum": PORTABLE_MAX_WORKERS
},
"provenance": { "$ref": "#/$defs/provenance" },
"initializationMs": { "type": ["number", "null"], "minimum": 0 },
"compile": { "$ref": "#/$defs/compileMeasurements" },
"decode": {
"oneOf": [
{ "$ref": "#/$defs/compileStatistics" },
{ "type": "null" }
]
},
"dispatch": { "$ref": "#/$defs/dispatchMeasurements" },
"terminalDigest": { "$ref": "#/$defs/digest" }
},
"$defs": {
"digest": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
"provenance": {
"type": "object",
"additionalProperties": false,
"required": [
"harnVersion", "kernelVersion", "artifactFormatVersion",
"semanticAbiFingerprint", "opcodeAbiFingerprint", "buildProfile",
"os", "arch"
],
"properties": {
"harnVersion": { "type": "string", "minLength": 1 },
"kernelVersion": { "type": "string", "minLength": 1 },
"artifactFormatVersion": { "type": "integer", "minimum": 1 },
"semanticAbiFingerprint": { "$ref": "#/$defs/digest" },
"opcodeAbiFingerprint": { "$ref": "#/$defs/digest" },
"buildProfile": { "enum": ["debug", "release"] },
"os": { "type": "string", "minLength": 1 },
"arch": { "type": "string", "minLength": 1 }
}
},
"statistics": {
"type": "object",
"additionalProperties": false,
"required": [
"iterations", "min_ms", "mean_ms", "p50_ms", "p95_ms",
"max_ms", "stddev_ms", "total_ms"
],
"properties": {
"iterations": { "type": "integer", "minimum": 1 },
"min_ms": { "type": "number", "minimum": 0 },
"mean_ms": { "type": "number", "minimum": 0 },
"p50_ms": { "type": "number", "minimum": 0 },
"p95_ms": { "type": "number", "minimum": 0 },
"max_ms": { "type": "number", "minimum": 0 },
"stddev_ms": { "type": "number", "minimum": 0 },
"total_ms": { "type": "number", "minimum": 0 }
}
},
"compileStatistics": {
"allOf": [
{ "$ref": "#/$defs/statistics" },
{ "properties": { "iterations": {
"maximum": PORTABLE_MAX_COMPILE_ITERATIONS
} } }
]
},
"dispatchStatistics": {
"allOf": [
{ "$ref": "#/$defs/statistics" },
{ "properties": { "iterations": {
"maximum": PORTABLE_MAX_DISPATCH_ITERATIONS
} } }
]
},
"compileMeasurements": {
"type": "object",
"additionalProperties": false,
"required": ["firstMs", "repeated"],
"properties": {
"firstMs": { "type": "number", "minimum": 0 },
"repeated": { "$ref": "#/$defs/compileStatistics" }
}
},
"dispatchMeasurements": {
"type": "object",
"additionalProperties": false,
"required": [
"firstMs", "repeated", "batchWallMs", "throughputPerSecond"
],
"properties": {
"firstMs": { "type": "number", "minimum": 0 },
"repeated": { "$ref": "#/$defs/dispatchStatistics" },
"batchWallMs": { "type": "number", "exclusiveMinimum": 0 },
"throughputPerSecond": { "type": "number", "exclusiveMinimum": 0 }
}
}
}
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn schema_projects_owned_limits_and_receipt_fields() {
let schema = portable_benchmark_json_schema();
assert_eq!(
schema["properties"]["schemaVersion"]["const"],
PORTABLE_BENCHMARK_SCHEMA_VERSION
);
assert_eq!(
schema["properties"]["iterations"]["maximum"],
PORTABLE_MAX_DISPATCH_ITERATIONS
);
assert_eq!(
schema["properties"]["workers"]["maximum"],
PORTABLE_MAX_WORKERS
);
let required = schema["required"].as_array().expect("required fields");
let properties = schema["properties"].as_object().expect("properties");
assert_eq!(required.len(), properties.len());
assert!(properties.keys().all(|key| required.contains(&json!(key))));
}
}