1use serde_json::{json, Value};
8
9use super::{
10 PORTABLE_BENCHMARK_SCHEMA_VERSION, PORTABLE_MAX_COMPILE_ITERATIONS,
11 PORTABLE_MAX_DISPATCH_ITERATIONS, PORTABLE_MAX_WORKERS,
12};
13
14pub fn portable_benchmark_json_schema() -> Value {
16 json!({
17 "$schema": "https://json-schema.org/draft/2020-12/schema",
18 "$id": "https://harnlang.com/schemas/portable-kernel-benchmark.v1.schema.json",
19 "$comment": "Generated by `make gen-portable-benchmark-schema`; do not edit by hand.",
20 "title": "Harn Portable Kernel benchmark receipt v1",
21 "type": "object",
22 "additionalProperties": false,
23 "required": [
24 "schemaVersion", "target", "source", "entry", "entryKind",
25 "artifactBytes", "artifactDigest", "iterations", "workers",
26 "provenance", "initializationMs", "compile", "decode", "dispatch",
27 "terminalDigest"
28 ],
29 "properties": {
30 "schemaVersion": { "const": PORTABLE_BENCHMARK_SCHEMA_VERSION },
31 "target": { "enum": ["native", "browser"] },
32 "source": { "type": "string", "minLength": 1 },
33 "entry": { "type": "string", "minLength": 1 },
34 "entryKind": { "enum": ["function", "pipeline"] },
35 "artifactBytes": { "type": "integer", "minimum": 1 },
36 "artifactDigest": { "$ref": "#/$defs/digest" },
37 "iterations": {
38 "type": "integer", "minimum": 1,
39 "maximum": PORTABLE_MAX_DISPATCH_ITERATIONS
40 },
41 "workers": {
42 "type": "integer", "minimum": 1, "maximum": PORTABLE_MAX_WORKERS
43 },
44 "provenance": { "$ref": "#/$defs/provenance" },
45 "initializationMs": { "type": ["number", "null"], "minimum": 0 },
46 "compile": { "$ref": "#/$defs/compileMeasurements" },
47 "decode": {
48 "oneOf": [
49 { "$ref": "#/$defs/compileStatistics" },
50 { "type": "null" }
51 ]
52 },
53 "dispatch": { "$ref": "#/$defs/dispatchMeasurements" },
54 "terminalDigest": { "$ref": "#/$defs/digest" }
55 },
56 "$defs": {
57 "digest": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
58 "provenance": {
59 "type": "object",
60 "additionalProperties": false,
61 "required": [
62 "harnVersion", "kernelVersion", "artifactFormatVersion",
63 "semanticAbiFingerprint", "opcodeAbiFingerprint", "buildProfile",
64 "os", "arch"
65 ],
66 "properties": {
67 "harnVersion": { "type": "string", "minLength": 1 },
68 "kernelVersion": { "type": "string", "minLength": 1 },
69 "artifactFormatVersion": { "type": "integer", "minimum": 1 },
70 "semanticAbiFingerprint": { "$ref": "#/$defs/digest" },
71 "opcodeAbiFingerprint": { "$ref": "#/$defs/digest" },
72 "buildProfile": { "enum": ["debug", "release"] },
73 "os": { "type": "string", "minLength": 1 },
74 "arch": { "type": "string", "minLength": 1 }
75 }
76 },
77 "statistics": {
78 "type": "object",
79 "additionalProperties": false,
80 "required": [
81 "iterations", "min_ms", "mean_ms", "p50_ms", "p95_ms",
82 "max_ms", "stddev_ms", "total_ms"
83 ],
84 "properties": {
85 "iterations": { "type": "integer", "minimum": 1 },
86 "min_ms": { "type": "number", "minimum": 0 },
87 "mean_ms": { "type": "number", "minimum": 0 },
88 "p50_ms": { "type": "number", "minimum": 0 },
89 "p95_ms": { "type": "number", "minimum": 0 },
90 "max_ms": { "type": "number", "minimum": 0 },
91 "stddev_ms": { "type": "number", "minimum": 0 },
92 "total_ms": { "type": "number", "minimum": 0 }
93 }
94 },
95 "compileStatistics": {
96 "allOf": [
97 { "$ref": "#/$defs/statistics" },
98 { "properties": { "iterations": {
99 "maximum": PORTABLE_MAX_COMPILE_ITERATIONS
100 } } }
101 ]
102 },
103 "dispatchStatistics": {
104 "allOf": [
105 { "$ref": "#/$defs/statistics" },
106 { "properties": { "iterations": {
107 "maximum": PORTABLE_MAX_DISPATCH_ITERATIONS
108 } } }
109 ]
110 },
111 "compileMeasurements": {
112 "type": "object",
113 "additionalProperties": false,
114 "required": ["firstMs", "repeated"],
115 "properties": {
116 "firstMs": { "type": "number", "minimum": 0 },
117 "repeated": { "$ref": "#/$defs/compileStatistics" }
118 }
119 },
120 "dispatchMeasurements": {
121 "type": "object",
122 "additionalProperties": false,
123 "required": [
124 "firstMs", "repeated", "batchWallMs", "throughputPerSecond"
125 ],
126 "properties": {
127 "firstMs": { "type": "number", "minimum": 0 },
128 "repeated": { "$ref": "#/$defs/dispatchStatistics" },
129 "batchWallMs": { "type": "number", "exclusiveMinimum": 0 },
130 "throughputPerSecond": { "type": "number", "exclusiveMinimum": 0 }
131 }
132 }
133 }
134 })
135}
136
137#[cfg(test)]
138mod tests {
139 use super::*;
140
141 #[test]
142 fn schema_projects_owned_limits_and_receipt_fields() {
143 let schema = portable_benchmark_json_schema();
144 assert_eq!(
145 schema["properties"]["schemaVersion"]["const"],
146 PORTABLE_BENCHMARK_SCHEMA_VERSION
147 );
148 assert_eq!(
149 schema["properties"]["iterations"]["maximum"],
150 PORTABLE_MAX_DISPATCH_ITERATIONS
151 );
152 assert_eq!(
153 schema["properties"]["workers"]["maximum"],
154 PORTABLE_MAX_WORKERS
155 );
156 let required = schema["required"].as_array().expect("required fields");
157 let properties = schema["properties"].as_object().expect("properties");
158 assert_eq!(required.len(), properties.len());
159 assert!(properties.keys().all(|key| required.contains(&json!(key))));
160 }
161}