Files
Michał Pierzchała b15121ffc8 test(ios): establish snapshot convergence baselines and permanent evidence (#2204)
* test(ios): add snapshot convergence evidence harness

* fix(ios): satisfy benchmark CI guards

* fix(ios): constrain benchmark proxy routes

* fix(ios-benchmark): enforce cell admission evidence

* fix(ios-benchmark): protect benchmark state ownership

* fix(ios-benchmark): use proxy port flag

* fix(ios-benchmark): let proxy choose an ephemeral port

* test(ios-benchmark): keep CLI process seam local

* fix(ios-benchmark): parse proxy startup envelope

* fix(ios-benchmark): bind proxy lease to simulator

* fix(ios-benchmark): keep fresh proxy CLI sessions isolated

* fix(ios-benchmark): preserve async timeout evidence

* docs(ios-benchmark): retain exact-head evidence

* test(ios): reveal offscreen alert fixture controls

* test(ios): reset alert between relaunch samples

* test(ios): admit native alert snapshots

* docs(ios): publish snapshot convergence corpus

* chore(ios): format benchmark evidence

* fix(ios-benchmark): admit proxy fixture anchors

* docs(ios): republish exact-head benchmark corpus

* fix(size): make publish asset evidence hermetic

* style(size): format package evidence test

* test(size): update publish preparation contracts

* fix: retire stale utils layering zone

* test: pin shared publish asset owner

* test: verify preserved size reporter closure

* fix: move mutation ownership to snapshot module

* test(ios): add snapshot convergence evidence harness

* fix(ios): satisfy benchmark CI guards

* fix(ios): constrain benchmark proxy routes

* fix(ios-benchmark): enforce cell admission evidence

* fix(ios-benchmark): protect benchmark state ownership

* fix(ios-benchmark): use proxy port flag

* fix(ios-benchmark): let proxy choose an ephemeral port

* test(ios-benchmark): keep CLI process seam local

* fix(ios-benchmark): parse proxy startup envelope

* fix(ios-benchmark): bind proxy lease to simulator

* fix(ios-benchmark): keep fresh proxy CLI sessions isolated

* fix(ios-benchmark): preserve async timeout evidence

* docs(ios-benchmark): retain exact-head evidence

* test(ios): reveal offscreen alert fixture controls

* test(ios): reset alert between relaunch samples

* test(ios): admit native alert snapshots

* docs(ios): publish snapshot convergence corpus

* chore(ios): format benchmark evidence

* fix(ios-benchmark): admit proxy fixture anchors

* docs(ios): republish exact-head benchmark corpus

* fix(size): make publish asset evidence hermetic

* test(size): update publish preparation contracts

* fix: keep git-state gates out of mutation sandboxes
2026-09-01 21:39:05 +02:00

111 lines
4.0 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { BenchmarkResult, Measurement, PackageSize, Summary } from './types.ts';
export function renderBenchmarkMarkdown(result: BenchmarkResult): string {
const lines = [
'# iOS snapshot convergence benchmark',
'',
`- Status: **${result.status}**`,
`- Revision: ${result.revision.commit}`,
`- Host: ${result.host.model} (${result.host.modelIdentifier}; ${result.host.cpu}, ${result.host.cpuCores} cores)`,
`- Target: ${result.target.name} (${result.target.udid}, ${result.target.runtime})`,
`- Generated: ${result.generatedAt}`,
'',
'| State | Screen | Transport | Execution | N | Wall median | Wall p95 | Daemon median | Response median | Failures |',
'|---|---|---|---|---:|---:|---:|---:|---:|---:|',
...result.measurements.map(measurementRow),
'',
'## Package size',
'',
packageSizeLines(result),
'',
'## Deep-button control',
'',
`- Fixture artifact: ${result.deepButtonEvidence.artifact} (depth ${result.deepButtonEvidence.depth})`,
`- Red control: ${result.deepButtonEvidence.invalidShallowRule.command} (exit ${result.deepButtonEvidence.invalidShallowRule.exitCode})`,
` - ${result.deepButtonEvidence.invalidShallowRule.assertion}`,
`- Safe control: ${result.deepButtonEvidence.safeFullRule.command} (exit ${result.deepButtonEvidence.safeFullRule.exitCode})`,
` - ${result.deepButtonEvidence.safeFullRule.assertion}`,
];
if (result.stop) {
lines.push('', '## Stop condition', '', `- ${result.stop.category}: ${result.stop.message}`);
if (result.stop.reason) lines.push(`- Reason: ${result.stop.reason}`);
if (result.stop.command) lines.push(`- Command: ${result.stop.command}`);
}
return `${lines.join('\n')}\n`;
}
function measurementRow(measurement: Measurement): string {
return `| ${[
measurement.state,
measurement.screen,
measurement.transport,
measurement.execution,
measurement.wallClockMs?.n ?? 0,
formatSummaryValue(measurement.wallClockMs, 'median'),
formatSummaryValue(measurement.wallClockMs, 'p95'),
formatSummaryValue(measurement.daemonDurationMs, 'median'),
formatSummaryValue(measurement.responseBytes, 'median'),
measurement.failures,
].join(' | ')} |`;
}
function formatSummaryValue(summary: Summary | null, key: 'median' | 'p95'): string {
return summary ? `${summary[key].toFixed(1)}` : '–';
}
function packageSizeLines(result: BenchmarkResult): string {
const packageSize = result.packageSize;
if (packageSize.status !== 'measured') return 'Not measured.';
return measuredPackageSizeLines(packageSize);
}
function measuredPackageSizeLines(packageSize: PackageSize & { status: 'measured' }): string {
return [
...packedSizeLines(packageSize),
cleanInstalledSizeLine(packageSize),
bundledSizeLine(packageSize),
].join('\n');
}
function packedSizeLines(packageSize: PackageSize): string[] {
const packed = packageSize.packed;
return [
packageSizeLine('Packed tarball', packed?.tarballBytes),
packageSizeLine('Packed unpacked tree', packed?.unpackedBytes),
];
}
function cleanInstalledSizeLine(packageSize: PackageSize): string {
const cleanInstalled = packageSize.cleanInstalled;
return packageTreeLine(
'Clean-installed package tree',
cleanInstalled?.packageBytes,
cleanInstalled?.files,
);
}
function bundledSizeLine(packageSize: PackageSize): string {
const bundled = packageSize.bundled;
return packageBundleLine('Bundled JavaScript', bundled?.rawBytes, bundled?.gzipBytes);
}
function packageSizeLine(label: string, bytes: number | undefined): string {
return `- ${label}: ${bytes ?? '–'} bytes`;
}
function packageTreeLine(
label: string,
bytes: number | undefined,
files: number | undefined,
): string {
return `- ${label}: ${bytes ?? '–'} bytes (${files ?? '–'} files)`;
}
function packageBundleLine(
label: string,
raw: number | undefined,
gzip: number | undefined,
): string {
return `- ${label}: ${raw ?? '–'} raw / ${gzip ?? '–'} gzip bytes`;
}